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