class CFPropertyList::Binary
def load(opts)
def load(opts) @unique_table = {} @count_objects = 0 @object_refs = 0 @written_object_count = 0 @object_table = [] @object_ref_size = 0 @offsets = [] fd = nil if(opts.has_key?(:file)) fd = File.open(opts[:file],"rb") file = opts[:file] else fd = StringIO.new(opts[:data],"rb") file = "<string>" end # first, we read the trailer: 32 byte from the end fd.seek(-32,IO::SEEK_END) buff = fd.read(32) offset_size, object_ref_size, number_of_objects, top_object, table_offset = buff.unpack "x6CCx4Nx4Nx4N" # after that, get the offset table fd.seek(table_offset, IO::SEEK_SET) coded_offset_table = fd.read(number_of_objects * offset_size) raise CFFormatError.new("#{file}: Format error!") unless coded_offset_table.bytesize == number_of_objects * offset_size @count_objects = number_of_objects # decode offset table if(offset_size != 3) formats = ["","C*","n*","","N*"] @offsets = coded_offset_table.unpack(formats[offset_size]) else @offsets = coded_offset_table.unpack("C*").each_slice(3).map { |x,y,z| (x << 16) | (y << 8) | z } end @object_ref_size = object_ref_size val = read_binary_object_at(file,fd,top_object) fd.close val end