plist.rb in plist-2.0.0 vs plist.rb in plist-2.1.0

- old
+ new

@@ -26,12 +26,17 @@ # FalseClass # TrueClass # Array # Hash # -# Note that Array and Hash are recursive -- the elements of an Array and the values of a Hash -# must convert to a plist. Also note that the keys of the Hash must be strings. +# Notes: +# +# + Array and Hash are recursive -- the elements of an Array and the values of a Hash +# must convert to a plist. +# + The keys of the Hash must be strings. +# + The contents of data elements are returned as a Tempfile. +# + Data elements can be set with to an open IO or a StringIO # # If you have suggestions for mapping other Ruby types to the plist types, send a note to: # # mailto:plist@hexane.org # @@ -43,10 +48,13 @@ # # + Martin Dittus, who pointed out that Time wasn't enough for plist Dates, # especially those in "~/Library/Cookies/Cookies.plist" # # + Chuck Remes, who pushed me towards implementing #to_plist +# +# + Mat Schaffer, who supplied code and test cases for <data> elements +# class Plist TEMPLATE = <<-XML <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> @@ -59,11 +67,12 @@ end # Note that I don't use these two elements much: # # + Date elements are returned as DateTime objects. -# + Data elements are not yet implemented. +# + Data elements are implemented as a subcase of strings: +# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/31933 # # Plist::parse_xml will blow up if it encounters a data element. # If you encounter such an error, or if you have a Date element which # can't be parsed into a Time object, please send your plist file to # plist@hexane.org so that I can implement the proper support. @@ -242,10 +251,23 @@ def to_ruby DateTime.parse(text) end end + require 'base64' + require 'tempfile' + class PData < PTag + def to_ruby + tf = Tempfile.new("plist.tmp") + tf.write Base64.decode64(text.gsub(/\s+/,'')) + tf.close + # is this a good idea? + tf.open + tf + end + end + module Emit def save_plist(filename) File.open(filename, 'wb') do |f| f.write(self.to_plist) end @@ -309,11 +331,11 @@ def to_plist_fragment fragment = "<array>\n" self.each do |e| element_plist = e.to_plist_fragment element_plist.each do |l| - fragment += " #{l}\n" + fragment += "\t#{l.chomp}\n" end end fragment += "</array>" fragment end @@ -322,15 +344,32 @@ class Hash include Plist::Emit def to_plist_fragment fragment = "<dict>\n" self.keys.sort.each do |k| - fragment += " <key>#{k}</key>\n" + fragment += "\t<key>#{k}</key>\n" element_plist = self[k].to_plist_fragment element_plist.each do |l| - fragment += " #{l}\n" + fragment += "\t#{l.chomp}\n" end end fragment += "</dict>" fragment + end +end + +require 'stringio' +[ IO, StringIO ].each do |io_class| + io_class.module_eval do + include Plist::Emit + def to_plist_fragment + self.rewind + data = self.read + + output = "<data>\n" + Base64::encode64(data).gsub(/\s+/, '').scan(/.{1,68}/o) { output << $& << "\n" } + output << "</data>" + + output + end end end