Add Plist <=> Ruby infrastructure

This commit is contained in:
Matthias Neeracher 2007-08-18 23:17:57 +00:00
parent d9d1096dc2
commit 75b5c558ce
4 changed files with 921 additions and 735 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

87
Filters/plistReader.rb Normal file
View File

@ -0,0 +1,87 @@
#
# plistReader - Read apple plist into ruby object
#
require 'rexml/document'
require 'rexml/streamlistener'
require 'base64'
require 'date'
class PlistListener
include REXML::StreamListener
def initialize
@stack = []
@kstack = []
@vessel = nil
@obj = nil
@key = nil
@kind = nil
end
def rootObject
return @obj
end
def tag_start(tag, attrs)
case tag
when "array" then
@stack.push(@vessel = [])
@kstack.push(@key)
@key = nil
when "dict" then
@stack.push(@vessel = {})
@kstack.push(@key)
@key = nil
when "string", "integer", "real", "data", "date", "key" then
@kind = tag
@obj = ""
when "true" then
@obj = true
when "false" then
@obj = false
end
end
def text(text)
case @kind
when "string", "key" then
@obj = text
when "data" then
@obj = Base64.decode(text)
when "date" then
@obj = Time.xmlschema(text)
when "integer" then
@obj = text.to_i
when "real" then
@obj = text.to_f
end
end
def tag_end(tag)
@kind = nil
case tag
when "array", "dict" then
@obj = @stack.pop
@key = @kstack.pop
@vessel = @stack.last
when "key" then
@key = @obj
@obj = nil
end
if @vessel && @obj then
if @key then
@vessel[@key] = @obj
@key = nil
else
@vessel.push(@obj)
end
end
end
end
def readPlist(source)
listener = PlistListener.new
REXML::Document.parse_stream(source, listener)
listener.rootObject
end

68
Filters/plistWriter.rb Normal file
View File

@ -0,0 +1,68 @@
#
# plistWriter - Write ruby object as Apple plist
#
require 'rexml/document'
require 'base64'
class PlistData
def initialize(string)
@str = string
end
def to_s
return @str
end
end
def _encodePlist(object)
e = nil
case object
when String then
e = REXML::Element.new("string")
e.add_text(object)
when PlistData then
e = REXML::Element.new("data")
e.add_text(object.to_s)
when Integer then
e = REXML::Element.new("integer")
e.add_text(object.to_s)
when Float then
e = REXML::Element.new("real")
e.add_text(object.to_s)
when Time then
e = REXML::Element.new("date")
e.add_text(object.utc.xmlschema)
when Array then
e = REXML::Element.new("array")
object.each do |elt|
e.add_element(_encodePlist(elt))
end
when Hash then
e = REXML::Element.new("dict")
object.each do |key,elt|
k = REXML::Element.new("key")
k.add_text(key)
e.add_element(k)
e.add_element(_encodePlist(elt))
end
else
raise "plistWriter can't encode objects of type `#{object.class}'[#{object.class.id}]"
end
return e
end
def writePlist(destination, object)
doc = REXML::Document.new
doc.add REXML::XMLDecl.new("1.0", "UTF-8")
doc.add REXML::DocType.new(["plist", "PUBLIC",
"\"-//Apple//DTD PLIST 1.0//EN\"",
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\""])
contents = REXML::Element.new("plist")
contents.add_attribute("version", "1.0")
contents.add_element(_encodePlist(object))
doc.add_element(contents)
doc.write(destination, 4)
end