class KeyedArchive
Constants
- VERSION
Attributes
archiver[RW]
objects[RW]
top[RW]
version[RW]
Public Class Methods
new(opts={})
click to toggle source
Take the same sort of arguments as CFPropertyList :file => filename to load :data => variable with the data to load directly
# File lib/keyed_archive.rb, line 13 def initialize(opts={}) blob = opts[:data] filename = opts[:file] plist = CFPropertyList::List.new(:file => filename) unless filename.nil? or !File.exists?(filename) plist = CFPropertyList::List.new(:data => blob) unless blob.nil? or blob.length < 1 if !plist.nil? data = CFPropertyList.native_types(plist.value) @archiver = data['$archiver'] @objects = data['$objects'] @top = data['$top'] @version = data['$version'] else raise "Plist not created" end end
Public Instance Methods
unpacked_top()
click to toggle source
Loops through the entries within '$top' to replace any values that are pointers to objects.
# File lib/keyed_archive/unpacked_objects.rb, line 5 def unpacked_top # Create the return value unpacked_top = Hash.new # Loop over each pair in the '$top' hash # to recursively replace the values @top.each_pair do |key, value| unpacked_top[key] = recursive_replace(value, -1, []) end # Politely return, our job is done return unpacked_top end
Private Instance Methods
recursive_replace(value, current_location, locations)
click to toggle source
Handles the recursive replacement of values within the '$objects' array. Tracks the object locations it has already touched to prevent infinite loops.
# File lib/keyed_archive/unpacked_objects.rb, line 25 def recursive_replace(value, current_location, locations) # By default we just return the value itself, usually a String to_return = value # If the value is really representing nil, change it to nil if value.is_a? String and value == "$null" to_return = nil end # If we have an Integer, we want to bring in the object # that Integer points to if value.is_a? Integer # If we ever find a reference to one of our parents, just stop where we are if locations.include?(current_location) to_return = value else to_return = recursive_replace(@objects[value], value, locations.clone.push(current_location)) end # If we have a Hash, we want to check each entry # and replace any values which need it elsif value.is_a? Hash # Build up a new Hash to_return = Hash.new # Loop over the pairs to check the key, value, or both value.each_pair do |tmp_key, tmp_value| # If this points to an array of objects, # then we should bring those values in if tmp_key == "NS.objects" or tmp_key == "NS.keys" new_array = Array.new tmp_value.each do |entry| new_array.push(recursive_replace(entry, entry, locations.clone.push(current_location))) end to_return[tmp_key] = new_array # Otherwise, we just want to replace the value with # its recursive version else to_return[tmp_key] = recursive_replace(tmp_value, tmp_value, locations.clone.push(current_location)) end end end # Give back the value, politely return to_return end