class Plist::StreamParser
Constants
- COMMENT_END
- COMMENT_START
- DOCTYPE_PATTERN
- TEXT
- XMLDECL_PATTERN
Public Class Methods
new(plist_data_or_file, listener)
click to toggle source
# File lib/plist/parser.rb, line 63 def initialize(plist_data_or_file, listener) if plist_data_or_file.respond_to? :read @xml = plist_data_or_file.read elsif File.exist? plist_data_or_file @xml = File.read(plist_data_or_file) else @xml = plist_data_or_file end @listener = listener end
Public Instance Methods
parse()
click to toggle source
# File lib/plist/parser.rb, line 81 def parse plist_tags = PTag.mappings.keys.join('|') start_tag = /<(#{plist_tags})([^>]*)>/i end_tag = /<\/(#{plist_tags})[^>]*>/i require 'strscan' @scanner = StringScanner.new(@xml) until @scanner.eos? if @scanner.scan(COMMENT_START) @scanner.scan(COMMENT_END) elsif @scanner.scan(XMLDECL_PATTERN) encoding = parse_encoding_from_xml_declaration(@scanner[1]) next if encoding.nil? # use the specified encoding for the rest of the file next unless String.method_defined?(:force_encoding) @scanner.string = @scanner.rest.force_encoding(encoding) elsif @scanner.scan(DOCTYPE_PATTERN) next 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
Private Instance Methods
parse_encoding_from_xml_declaration(xml_declaration)
click to toggle source
# File lib/plist/parser.rb, line 118 def parse_encoding_from_xml_declaration(xml_declaration) return unless defined?(Encoding) xml_encoding = xml_declaration.match(/(?:\A|\s)encoding=(?:"(.*?)"|'(.*?)')(?:\s|\Z)/) return if xml_encoding.nil? begin Encoding.find(xml_encoding[1]) rescue ArgumentError nil end end