def to_str(opts={})
      @unique_table = {}
      @count_objects = 0
      @object_refs = 0

      @written_object_count = 0
      @object_table = []

      @offsets = []

      binary_str = "bplist00"

      @object_refs = count_object_refs(opts[:root])

      opts[:root].to_binary(self)

      next_offset = 8
      offsets = @object_table.map do |object|
        offset = next_offset
        next_offset += object.bytesize
        offset
      end
      binary_str << @object_table.join

      table_offset = next_offset
      offset_size = Binary.bytes_needed(table_offset)

      if offset_size < 8
        # Fast path: encode the entire offset array at once.
        binary_str << offsets.pack((%w(C n N N)[offset_size - 1]) + '*')
      else
        # Slow path: host may be little or big endian, must pack each offset
        # separately.
        offsets.each do |offset|
          binary_str << "#{Binary.pack_it_with_size(offset_size,offset)}"
        end
      end

      binary_str << [offset_size, object_ref_size(@object_refs)].pack("x6CC")
      binary_str << [@object_table.size].pack("x4N")
      binary_str << [0].pack("x4N")
      binary_str << [table_offset].pack("x4N")

      binary_str
    end
def to_str(opts={})
      @unique_table = {}
      @count_objects = 0
      @object_refs = 0

      @written_object_count = 0
      @object_table = []

      @offsets = []

      binary_str = "bplist00"

      @object_refs = count_object_refs(opts[:root])

      opts[:root].to_binary(self)

      next_offset = 8
      offsets = @object_table.map do |object|
        offset = next_offset
        next_offset += object.bytesize
        offset
      end
      binary_str << @object_table.join

      table_offset = next_offset
      offset_size = Binary.bytes_needed(table_offset)

      if offset_size < 8
        # Fast path: encode the entire offset array at once.
        binary_str << offsets.pack((%w(C n N N)[offset_size - 1]) + '*')
      else
        # Slow path: host may be little or big endian, must pack each offset
        # separately.
        offsets.each do |offset|
          binary_str << "#{Binary.pack_it_with_size(offset_size,offset)}"
        end
      end

      binary_str << [offset_size, object_ref_size(@object_refs)].pack("x6CC")
      binary_str << [@object_table.size].pack("x4N")
      binary_str << [0].pack("x4N")
      binary_str << [table_offset].pack("x4N")

      binary_str
    end
Convert CFPropertyList to binary format; since we have to count our objects we simply unique CFDictionary and CFArray