lib/facter/util/plist/parser.rb in facter-1.5.4 vs lib/facter/util/plist/parser.rb in facter-1.5.5

- old
+ new

@@ -19,209 +19,208 @@ # # 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. - def Plist::parse_xml( filename_or_xml ) - listener = Listener.new - #parser = REXML::Parsers::StreamParser.new(File.new(filename), listener) - parser = StreamParser.new(filename_or_xml, listener) - parser.parse - listener.result - end + def Plist::parse_xml( filename_or_xml ) + listener = Listener.new + #parser = REXML::Parsers::StreamParser.new(File.new(filename), listener) + parser = StreamParser.new(filename_or_xml, listener) + parser.parse + listener.result + end - class Listener - #include REXML::StreamListener + class Listener + #include REXML::StreamListener - attr_accessor :result, :open + attr_accessor :result, :open - def initialize - @result = nil - @open = Array.new - end + def initialize + @result = nil + @open = Array.new + end - def tag_start(name, attributes) - @open.push PTag::mappings[name].new - end + def tag_start(name, attributes) + @open.push PTag::mappings[name].new + end - def text( contents ) - @open.last.text = contents if @open.last - end + def text( contents ) + @open.last.text = contents if @open.last + end - def tag_end(name) - last = @open.pop - if @open.empty? - @result = last.to_ruby - else - @open.last.children.push last - end + def tag_end(name) + last = @open.pop + if @open.empty? + @result = last.to_ruby + else + @open.last.children.push last + end + end end - end - class StreamParser - def initialize( filename_or_xml, listener ) - @filename_or_xml = filename_or_xml - @listener = listener - end + class StreamParser + def initialize( filename_or_xml, listener ) + @filename_or_xml = filename_or_xml + @listener = listener + end - TEXT = /([^<]+)/ - XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um - DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um - COMMENT_START = /\A<!--/u - COMMENT_END = /.*?-->/um + TEXT = /([^<]+)/ + XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um + DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um + COMMENT_START = /\A<!--/u + COMMENT_END = /.*?-->/um + def parse + plist_tags = PTag::mappings.keys.join('|') + start_tag = /<(#{plist_tags})([^>]*)>/i + end_tag = /<\/(#{plist_tags})[^>]*>/i - def parse - plist_tags = PTag::mappings.keys.join('|') - start_tag = /<(#{plist_tags})([^>]*)>/i - end_tag = /<\/(#{plist_tags})[^>]*>/i + require 'strscan' - require 'strscan' + contents = ( + if (File.exists? @filename_or_xml) + File.open(@filename_or_xml) {|f| f.read} + else + @filename_or_xml + end + ) - contents = ( - if (File.exists? @filename_or_xml) - File.open(@filename_or_xml) {|f| f.read} - else - @filename_or_xml + @scanner = StringScanner.new( contents ) + until @scanner.eos? + if @scanner.scan(COMMENT_START) + @scanner.scan(COMMENT_END) + elsif @scanner.scan(XMLDECL_PATTERN) + elsif @scanner.scan(DOCTYPE_PATTERN) + elsif @scanner.scan(start_tag) + @listener.tag_start(@scanner[1], nil) + if (@scanner[2] =~ /\/$/) + @listener.tag_end(@scanner[1]) + end + elsif @scanner.scan(TEXT) + @listener.text(@scanner[1]) + elsif @scanner.scan(end_tag) + @listener.tag_end(@scanner[1]) + else + raise "Unimplemented element" + end + end end - ) + end - @scanner = StringScanner.new( contents ) - until @scanner.eos? - if @scanner.scan(COMMENT_START) - @scanner.scan(COMMENT_END) - elsif @scanner.scan(XMLDECL_PATTERN) - elsif @scanner.scan(DOCTYPE_PATTERN) - elsif @scanner.scan(start_tag) - @listener.tag_start(@scanner[1], nil) - if (@scanner[2] =~ /\/$/) - @listener.tag_end(@scanner[1]) - end - elsif @scanner.scan(TEXT) - @listener.text(@scanner[1]) - elsif @scanner.scan(end_tag) - @listener.tag_end(@scanner[1]) - else - raise "Unimplemented element" + class PTag + @@mappings = { } + def PTag::mappings + @@mappings end - end - end - end - class PTag - @@mappings = { } - def PTag::mappings - @@mappings - end + def PTag::inherited( sub_class ) + key = sub_class.to_s.downcase + key.gsub!(/^plist::/, '' ) + key.gsub!(/^p/, '') unless key == "plist" - def PTag::inherited( sub_class ) - key = sub_class.to_s.downcase - key.gsub!(/^plist::/, '' ) - key.gsub!(/^p/, '') unless key == "plist" + @@mappings[key] = sub_class + end - @@mappings[key] = sub_class - end + attr_accessor :text, :children + def initialize + @children = Array.new + end - attr_accessor :text, :children - def initialize - @children = Array.new + def to_ruby + raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}" + end end - def to_ruby - raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}" + class PList < PTag + def to_ruby + children.first.to_ruby if children.first + end end - end - class PList < PTag - def to_ruby - children.first.to_ruby if children.first - end - end + class PDict < PTag + def to_ruby + dict = Hash.new + key = nil - class PDict < PTag - def to_ruby - dict = Hash.new - key = nil + children.each do |c| + if key.nil? + key = c.to_ruby + else + dict[key] = c.to_ruby + key = nil + end + end - children.each do |c| - if key.nil? - key = c.to_ruby - else - dict[key] = c.to_ruby - key = nil + dict end - end - - dict end - end - class PKey < PTag - def to_ruby - CGI::unescapeHTML(text || '') + class PKey < PTag + def to_ruby + CGI::unescapeHTML(text || '') + end end - end - class PString < PTag - def to_ruby - CGI::unescapeHTML(text || '') + class PString < PTag + def to_ruby + CGI::unescapeHTML(text || '') + end end - end - class PArray < PTag - def to_ruby - children.collect do |c| - c.to_ruby - end + class PArray < PTag + def to_ruby + children.collect do |c| + c.to_ruby + end + end end - end - class PInteger < PTag - def to_ruby - text.to_i + class PInteger < PTag + def to_ruby + text.to_i + end end - end - class PTrue < PTag - def to_ruby - true + class PTrue < PTag + def to_ruby + true + end end - end - class PFalse < PTag - def to_ruby - false + class PFalse < PTag + def to_ruby + false + end end - end - class PReal < PTag - def to_ruby - text.to_f + class PReal < PTag + def to_ruby + text.to_f + end end - end - require 'date' - class PDate < PTag - def to_ruby - DateTime.parse(text) + require 'date' + class PDate < PTag + def to_ruby + DateTime.parse(text) + end end - end - require 'base64' - class PData < PTag - def to_ruby - data = Base64.decode64(text.gsub(/\s+/, '')) + require 'base64' + class PData < PTag + def to_ruby + data = Base64.decode64(text.gsub(/\s+/, '')) - begin - return Marshal.load(data) - rescue Exception => e - io = StringIO.new - io.write data - io.rewind - return io - end + begin + return Marshal.load(data) + rescue Exception => e + io = StringIO.new + io.write data + io.rewind + return io + end + end end - end end # $Id: parser.rb 1781 2006-10-16 01:01:35Z luke $