Class: Plist::StreamParser

Inherits:
Object
  • Object
show all
Defined in:
lib/searchlink/plist.rb

Constant Summary collapse

TEXT =
/([^<]+)/.freeze
XMLDECL_PATTERN =
/<\?xml\s+(.*?)\?>*/um.freeze
DOCTYPE_PATTERN =
/\s*<!DOCTYPE\s+(.*?)(\[|>)/um.freeze
COMMENT_START =
/\A<!--/u.freeze
COMMENT_END =
/.*?-->/um.freeze

Instance Method Summary collapse

Constructor Details

#initialize(plist_data_or_file, listener) ⇒ StreamParser

Returns a new instance of StreamParser.



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/searchlink/plist.rb', line 48

def initialize(plist_data_or_file, listener)
  @xml = if plist_data_or_file.respond_to? :read
           plist_data_or_file.read
         elsif File.exist? plist_data_or_file
           File.read(plist_data_or_file)
         else
           plist_data_or_file
         end

  @listener = listener
end

Instance Method Details

#parseObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/searchlink/plist.rb', line 66

def parse
  plist_tags = PTag.mappings.keys.join('|')
  start_tag  = /<(#{plist_tags})([^>]*)>/i
  end_tag    = %r{</(#{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)
    elsif @scanner.scan(DOCTYPE_PATTERN)
    elsif @scanner.scan(start_tag)
      @listener.tag_start(@scanner[1], nil)
      @listener.tag_end(@scanner[1]) if @scanner[2] =~ %r{/$}
    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