rhodes 2.0.0.beta1 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/CHANGELOG +5 -0
  2. data/LICENSE +19 -674
  3. data/Manifest.txt +21 -4
  4. data/README.textile +5 -36
  5. data/Rakefile +5 -0
  6. data/lib/build/jake.rb +3 -1
  7. data/lib/extensions/rexml/rexml/document.rb +2 -0
  8. data/lib/extensions/rexml/rexml/parsers/baseparser.rb +0 -6
  9. data/lib/extensions/rhoxml/rexml/child.rb +96 -0
  10. data/lib/extensions/rhoxml/rexml/document.rb +527 -0
  11. data/lib/extensions/rhoxml/rexml/element.rb +987 -0
  12. data/lib/extensions/rhoxml/rexml/encoding.rb +71 -0
  13. data/lib/extensions/rhoxml/rexml/encodings/US-ASCII.rb +30 -0
  14. data/lib/extensions/rhoxml/rexml/encodings/UTF-16.rb +35 -0
  15. data/lib/extensions/rhoxml/rexml/encodings/UTF-8.rb +18 -0
  16. data/lib/extensions/rhoxml/rexml/namespace.rb +47 -0
  17. data/lib/extensions/rhoxml/rexml/node.rb +76 -0
  18. data/lib/extensions/rhoxml/rexml/parent.rb +166 -0
  19. data/lib/extensions/rhoxml/rexml/parseexception.rb +51 -0
  20. data/lib/extensions/rhoxml/rexml/parsers/baseparser.rb +531 -0
  21. data/lib/extensions/rhoxml/rexml/parsers/treeparser.rb +100 -0
  22. data/lib/extensions/rhoxml/rexml/parsers/xpathparser.rb +698 -0
  23. data/lib/extensions/rhoxml/rexml/set.rb +1274 -0
  24. data/lib/extensions/rhoxml/rexml/source.rb +258 -0
  25. data/lib/extensions/rhoxml/rexml/xmltokens.rb +18 -0
  26. data/lib/extensions/rhoxml/rexml/xpath.rb +77 -0
  27. data/lib/extensions/rhoxml/rexml/xpath_parser.rb +806 -0
  28. data/lib/framework/builtinME.rb +2 -0
  29. data/lib/framework/dateME.rb +5 -1
  30. data/lib/framework/rho/render.rb +10 -2
  31. data/lib/framework/rhom/rhom_object_factory.rb +2 -1
  32. data/lib/framework/singleton.rb +1 -1
  33. data/platform/android/Rhodes/jni/src/rhodes.cpp +2 -4
  34. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeBar.java +23 -18
  35. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +42 -69
  36. data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +59 -7
  37. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/Camera.java +1 -1
  38. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/Annotation.java +1 -0
  39. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/MapView.java +97 -85
  40. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/SmsUriHandler.java +52 -0
  41. data/platform/android/build/RhodesSRC_build.files +1 -0
  42. data/platform/android/build/android.rake +38 -14
  43. data/platform/bb/RubyVM/RubyVM.jdp +1 -0
  44. data/platform/bb/build/RubyVM_build.files +1 -0
  45. data/platform/bb/build/bb.rake +44 -2
  46. data/platform/bb/rhodes/platform/5.0/com/rho/BrowserAdapter5.java +1 -1
  47. data/platform/bb/rhodes/rhodes.jdp +4 -4
  48. data/platform/bb/rhodes/src/com/rho/BrowserAdapter.java +8 -4
  49. data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +149 -17
  50. data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +20 -17
  51. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +54 -28
  52. data/platform/bb/rhodes/src/rhomobile/mapview/Annotation.java +1 -0
  53. data/platform/bb/rhodes/src/rhomobile/mapview/GoogleMapField.java +37 -11
  54. data/platform/bb/rhodes/src/rhomobile/mapview/MapView.java +49 -19
  55. data/platform/bb/rhodes/src/rhomobile/mapview/MapViewScreen.java +6 -0
  56. data/platform/iphone/Classes/MapView/GoogleGeocoder.h +6 -7
  57. data/platform/iphone/Classes/MapView/GoogleGeocoder.m +70 -70
  58. data/platform/iphone/Classes/MapView/MapAnnotation.h +5 -3
  59. data/platform/iphone/Classes/MapView/MapAnnotation.m +10 -8
  60. data/platform/iphone/Classes/MapView/MapViewController.h +13 -10
  61. data/platform/iphone/Classes/MapView/MapViewController.m +131 -72
  62. data/platform/iphone/Classes/Rhodes.h +2 -0
  63. data/platform/iphone/Classes/Rhodes.m +13 -1
  64. data/platform/iphone/Classes/SimpleMainView.m +0 -1
  65. data/platform/iphone/Classes/TabbedMainView.m +5 -6
  66. data/platform/shared/common/RhoTime.h +2 -2
  67. data/platform/shared/common/RhodesApp.cpp +1 -1
  68. data/platform/shared/db/DBAdapter.cpp +6 -0
  69. data/platform/shared/net/CURLNetRequest.cpp +23 -1
  70. data/platform/shared/ruby/thread_win32.c +9 -1
  71. data/platform/shared/rubyJVM/src/com/rho/Capabilities.java +6 -0
  72. data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +1 -1
  73. data/platform/shared/rubyJVM/src/com/rho/sync/ClientRegister.java +1 -1
  74. data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubySymbol_Methods.java +6 -1
  75. data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubyTime_Methods.java +3 -3
  76. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/InputStreamExecutor.java +1 -1
  77. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyArray.java +15 -3
  78. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyString.java +10 -2
  79. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyTime.java +12 -1
  80. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubyKernelModule.java +18 -9
  81. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubySymbol.java +5 -0
  82. data/platform/shared/rubyJVM/src/org/json/me/JSONArray.java +2 -1
  83. data/platform/shared/unzip/unzip.cpp +1 -1
  84. data/platform/wm/build/wm.rake +27 -6
  85. data/platform/wm/rhodes/Alert.cpp +335 -5
  86. data/platform/wm/rhodes/Alert.h +84 -1
  87. data/platform/wm/rhodes/MainWindow.cpp +28 -6
  88. data/platform/wm/rhodes/MainWindow.h +7 -2
  89. data/platform/wm/rhodes/Rhodes.cpp +23 -0
  90. data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +2 -1
  91. data/platform/wm/rhodes/stdafx.h +1 -0
  92. data/platform/wm/tools/detool/detool.cpp +405 -14
  93. data/rakefile.rb +5 -0
  94. data/res/build-tools/detool.exe +0 -0
  95. data/res/generators/rhogen.rb +2 -0
  96. data/rhodes.gemspec +1 -1
  97. data/spec/framework_spec/app/spec/fixtures/object_values.txt +1 -1
  98. data/spec/framework_spec/app/spec/pagination/fixtures/object_values.txt +1 -1
  99. data/spec/framework_spec/app/spec/rhom_object_spec.rb +12 -12
  100. metadata +23 -6
  101. data/LICENSING_OPTIONS +0 -1
  102. data/platform/bb/build/rhodesApp.rapc +0 -9
  103. data/res/generators/templates/source/source_adapter.rb +0 -48
  104. data/rhobuild.yml +0 -37
@@ -0,0 +1,51 @@
1
+ module REXML
2
+ class ParseException < RuntimeError
3
+ attr_accessor :source, :parser, :continued_exception
4
+
5
+ def initialize( message, source=nil, parser=nil, exception=nil )
6
+ super(message)
7
+ @source = source
8
+ @parser = parser
9
+ @continued_exception = exception
10
+ end
11
+
12
+ def to_s
13
+ # Quote the original exception, if there was one
14
+ if @continued_exception
15
+ err = @continued_exception.inspect
16
+ err << "\n"
17
+ err << @continued_exception.backtrace.join("\n")
18
+ err << "\n...\n"
19
+ else
20
+ err = ""
21
+ end
22
+
23
+ # Get the stack trace and error message
24
+ err << super
25
+
26
+ # Add contextual information
27
+ if @source
28
+ err << "\nLine: #{line}\n"
29
+ err << "Position: #{position}\n"
30
+ err << "Last 80 unconsumed characters:\n"
31
+ err << @source.buffer[0..80].gsub(/\n/, ' ')
32
+ end
33
+
34
+ err
35
+ end
36
+
37
+ def position
38
+ @source.current_line[0] if @source and defined?( @source.current_line ) and
39
+ @source.current_line
40
+ end
41
+
42
+ def line
43
+ @source.current_line[2] if @source and defined?( @source.current_line ) and
44
+ @source.current_line
45
+ end
46
+
47
+ def context
48
+ @source.current_line
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,531 @@
1
+ require 'rexml/parseexception'
2
+ #require 'rexml/undefinednamespaceexception'
3
+ require 'rexml/source'
4
+ require 'rexml/set'
5
+
6
+ module REXML
7
+ module Parsers
8
+ # = Using the Pull Parser
9
+ # <em>This API is experimental, and subject to change.</em>
10
+ # parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
11
+ # while parser.has_next?
12
+ # res = parser.next
13
+ # puts res[1]['att'] if res.start_tag? and res[0] == 'b'
14
+ # end
15
+ # See the PullEvent class for information on the content of the results.
16
+ # The data is identical to the arguments passed for the various events to
17
+ # the StreamListener API.
18
+ #
19
+ # Notice that:
20
+ # parser = PullParser.new( "<a>BAD DOCUMENT" )
21
+ # while parser.has_next?
22
+ # res = parser.next
23
+ # raise res[1] if res.error?
24
+ # end
25
+ #
26
+ # Nat Price gave me some good ideas for the API.
27
+ class BaseParser
28
+ if String.method_defined? :encode
29
+ # Oniguruma / POSIX [understands unicode]
30
+ LETTER = '[[:alpha:]]'
31
+ DIGIT = '[[:digit:]]'
32
+ else
33
+ # Ruby < 1.9 [doesn't understand unicode]
34
+ LETTER = 'a-zA-Z'
35
+ DIGIT = '\d'
36
+ end
37
+
38
+ COMBININGCHAR = '' # TODO
39
+ EXTENDER = '' # TODO
40
+
41
+ NCNAME_STR= "[#{LETTER}_:][-#{LETTER}#{DIGIT}._:#{COMBININGCHAR}#{EXTENDER}]*"
42
+ NAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})"
43
+ UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
44
+
45
+ NAMECHAR = '[\-\w\d\.:]'
46
+ NAME = "([\\w:]#{NAMECHAR}*)"
47
+ NMTOKEN = "(?:#{NAMECHAR})+"
48
+ NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
49
+ REFERENCE = "&(?:#{NAME};|#\\d+;|#x[0-9a-fA-F]+;)"
50
+ REFERENCE_RE = /#{REFERENCE}/
51
+
52
+ DOCTYPE_START = /\A\s*<!DOCTYPE\s/um
53
+ DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um
54
+ ATTRIBUTE_PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\4/um
55
+ COMMENT_START = /\A<!--/u
56
+ COMMENT_PATTERN = /<!--(.*?)-->/um
57
+ CDATA_START = /\A<!\[CDATA\[/u
58
+ CDATA_END = /^\s*\]\s*>/um
59
+ CDATA_PATTERN = /<!\[CDATA\[(.*?)\]\]>/um
60
+ XMLDECL_START = /\A<\?xml\s/u;
61
+ XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>/um
62
+ INSTRUCTION_START = /\A<\?/u
63
+ INSTRUCTION_PATTERN = /<\?(.*?)(\s+.*?)?\?>/um
64
+ TAG_MATCH = /^<((?>#{NAME_STR}))\s*((?>\s+#{UNAME_STR}\s*=\s*(["']).*?\5)*)\s*(\/)?>/um
65
+ CLOSE_MATCH = /^\s*<\/(#{NAME_STR})\s*>/um
66
+
67
+ VERSION = /\bversion\s*=\s*["'](.*?)['"]/um
68
+ ENCODING = /\bencoding\s*=\s*["'](.*?)['"]/um
69
+ STANDALONE = /\bstandalone\s*=\s["'](.*?)['"]/um
70
+
71
+ ENTITY_START = /^\s*<!ENTITY/
72
+ IDENTITY = /^([!\*\w\-]+)(\s+#{NCNAME_STR})?(\s+["'](.*?)['"])?(\s+['"](.*?)["'])?/u
73
+ ELEMENTDECL_START = /^\s*<!ELEMENT/um
74
+ ELEMENTDECL_PATTERN = /^\s*(<!ELEMENT.*?)>/um
75
+ SYSTEMENTITY = /^\s*(%.*?;)\s*$/um
76
+ ENUMERATION = "\\(\\s*#{NMTOKEN}(?:\\s*\\|\\s*#{NMTOKEN})*\\s*\\)"
77
+ NOTATIONTYPE = "NOTATION\\s+\\(\\s*#{NAME}(?:\\s*\\|\\s*#{NAME})*\\s*\\)"
78
+ ENUMERATEDTYPE = "(?:(?:#{NOTATIONTYPE})|(?:#{ENUMERATION}))"
79
+ ATTTYPE = "(CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|#{ENUMERATEDTYPE})"
80
+ ATTVALUE = "(?:\"((?:[^<&\"]|#{REFERENCE})*)\")|(?:'((?:[^<&']|#{REFERENCE})*)')"
81
+ DEFAULTDECL = "(#REQUIRED|#IMPLIED|(?:(#FIXED\\s+)?#{ATTVALUE}))"
82
+ ATTDEF = "\\s+#{NAME}\\s+#{ATTTYPE}\\s+#{DEFAULTDECL}"
83
+ ATTDEF_RE = /#{ATTDEF}/
84
+ ATTLISTDECL_START = /^\s*<!ATTLIST/um
85
+ ATTLISTDECL_PATTERN = /^\s*<!ATTLIST\s+#{NAME}(?:#{ATTDEF})*\s*>/um
86
+ NOTATIONDECL_START = /^\s*<!NOTATION/um
87
+ PUBLIC = /^\s*<!NOTATION\s+(\w[\-\w]*)\s+(PUBLIC)\s+(["'])(.*?)\3(?:\s+(["'])(.*?)\5)?\s*>/um
88
+ SYSTEM = /^\s*<!NOTATION\s+(\w[\-\w]*)\s+(SYSTEM)\s+(["'])(.*?)\3\s*>/um
89
+
90
+ TEXT_PATTERN = /\A([^<]*)/um
91
+
92
+ # Entity constants
93
+ PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
94
+ SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
95
+ PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
96
+ EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
97
+ NDATADECL = "\\s+NDATA\\s+#{NAME}"
98
+ PEREFERENCE = "%#{NAME};"
99
+ ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
100
+ PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
101
+ ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
102
+ PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
103
+ GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
104
+ ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
105
+
106
+ EREFERENCE = /&(?!#{NAME};)/
107
+
108
+ DEFAULT_ENTITIES = {
109
+ 'gt' => [/&gt;/, '&gt;', '>', />/],
110
+ 'lt' => [/&lt;/, '&lt;', '<', /</],
111
+ 'quot' => [/&quot;/, '&quot;', '"', /"/],
112
+ "apos" => [/&apos;/, "&apos;", "'", /'/]
113
+ }
114
+
115
+
116
+ ######################################################################
117
+ # These are patterns to identify common markup errors, to make the
118
+ # error messages more informative.
119
+ ######################################################################
120
+ MISSING_ATTRIBUTE_QUOTES = /^<#{NAME_STR}\s+#{NAME_STR}\s*=\s*[^"']/um
121
+
122
+ def initialize( source )
123
+ self.stream = source
124
+ end
125
+
126
+ def add_listener( listener )
127
+ if !defined?(@listeners) or !@listeners
128
+ @listeners = []
129
+ instance_eval <<-EOL
130
+ alias :_old_pull :pull
131
+ def pull
132
+ event = _old_pull
133
+ @listeners.each do |listener|
134
+ listener.receive event
135
+ end
136
+ event
137
+ end
138
+ EOL
139
+ end
140
+ @listeners << listener
141
+ end
142
+
143
+ attr_reader :source
144
+
145
+ def stream=( source )
146
+ @source = SourceFactory.create_from( source )
147
+ @closed = nil
148
+ @document_status = nil
149
+ @tags = []
150
+ @stack = []
151
+ @entities = []
152
+ @nsstack = []
153
+ end
154
+
155
+ def position
156
+ if @source.respond_to? :position
157
+ @source.position
158
+ else
159
+ # FIXME
160
+ 0
161
+ end
162
+ end
163
+
164
+ # Returns true if there are no more events
165
+ def empty?
166
+ return (@source.empty?() and @stack.empty?())
167
+ end
168
+
169
+ # Returns true if there are more events. Synonymous with !empty?
170
+ def has_next?
171
+ return !(@source.empty?() and @stack.empty?())
172
+ end
173
+
174
+ # Push an event back on the head of the stream. This method
175
+ # has (theoretically) infinite depth.
176
+ def unshift token
177
+ @stack.unshift(token)
178
+ end
179
+
180
+ # Peek at the +depth+ event in the stack. The first element on the stack
181
+ # is at depth 0. If +depth+ is -1, will parse to the end of the input
182
+ # stream and return the last event, which is always :end_document.
183
+ # Be aware that this causes the stream to be parsed up to the +depth+
184
+ # event, so you can effectively pre-parse the entire document (pull the
185
+ # entire thing into memory) using this method.
186
+ def peek depth=0
187
+ raise %Q[Illegal argument "#{depth}"] if depth < -1
188
+ temp = []
189
+ if depth == -1
190
+ temp.push(pull()) until empty?
191
+ else
192
+ while @stack.size+temp.size < depth+1
193
+ temp.push(pull())
194
+ end
195
+ end
196
+ @stack += temp if temp.size > 0
197
+ @stack[depth]
198
+ end
199
+
200
+ # Returns the next event. This is a +PullEvent+ object.
201
+ def pull
202
+ if @closed
203
+ x, @closed = @closed, nil
204
+ return [ :end_element, x ]
205
+ end
206
+ return [ :end_document ] if empty?
207
+ return @stack.shift if @stack.size > 0
208
+ #STDERR.puts @source.encoding
209
+ @source.read if @source.buffer.size<2
210
+ #STDERR.puts "BUFFER = #{@source.buffer.inspect}"
211
+ if @document_status == nil
212
+ #@source.consume( /^\s*/um )
213
+ word = @source.match( /^((?:\s+)|(?:<[^>]*>))/um )
214
+ word = word[1] unless word.nil?
215
+ #STDERR.puts "WORD = #{word.inspect}"
216
+ case word
217
+ when COMMENT_START
218
+ return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ]
219
+ when XMLDECL_START
220
+ #STDERR.puts "XMLDECL"
221
+ results = @source.match( XMLDECL_PATTERN, true )[1]
222
+ version = VERSION.match( results )
223
+ version = version[1] unless version.nil?
224
+ encoding = ENCODING.match(results)
225
+ encoding = encoding[1] unless encoding.nil?
226
+ @source.encoding = encoding
227
+ standalone = STANDALONE.match(results)
228
+ standalone = standalone[1] unless standalone.nil?
229
+ return [ :xmldecl, version, encoding, standalone ]
230
+ when INSTRUCTION_START
231
+ return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]
232
+ when DOCTYPE_START
233
+ md = @source.match( DOCTYPE_PATTERN, true )
234
+ @nsstack.unshift(curr_ns=Set.new)
235
+ identity = md[1]
236
+ close = md[2]
237
+ identity =~ IDENTITY
238
+ name = $1
239
+ raise REXML::ParseException.new("DOCTYPE is missing a name") if name.nil?
240
+ pub_sys = $2.nil? ? nil : $2.strip
241
+ long_name = $4.nil? ? nil : $4.strip
242
+ uri = $6.nil? ? nil : $6.strip
243
+ args = [ :start_doctype, name, pub_sys, long_name, uri ]
244
+ if close == ">"
245
+ @document_status = :after_doctype
246
+ @source.read if @source.buffer.size<2
247
+ md = @source.match(/^\s*/um, true)
248
+ @stack << [ :end_doctype ]
249
+ else
250
+ @document_status = :in_doctype
251
+ end
252
+ return args
253
+ when /^\s+/
254
+ else
255
+ @document_status = :after_doctype
256
+ @source.read if @source.buffer.size<2
257
+ md = @source.match(/\s*/um, true)
258
+ if @source.encoding == "UTF-8"
259
+ if @source.buffer.respond_to? :force_encoding
260
+ @source.buffer.force_encoding(Encoding::UTF_8)
261
+ end
262
+ end
263
+ end
264
+ end
265
+ if @document_status == :in_doctype
266
+ md = @source.match(/\s*(.*?>)/um)
267
+ case md[1]
268
+ when SYSTEMENTITY
269
+ match = @source.match( SYSTEMENTITY, true )[1]
270
+ return [ :externalentity, match ]
271
+
272
+ when ELEMENTDECL_START
273
+ return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]
274
+
275
+ when ENTITY_START
276
+ match = @source.match( ENTITYDECL, true ).to_a.compact
277
+ match[0] = :entitydecl
278
+ ref = false
279
+ if match[1] == '%'
280
+ ref = true
281
+ match.delete_at 1
282
+ end
283
+ # Now we have to sort out what kind of entity reference this is
284
+ if match[2] == 'SYSTEM'
285
+ # External reference
286
+ match[3] = match[3][1..-2] # PUBID
287
+ match.delete_at(4) if match.size > 4 # Chop out NDATA decl
288
+ # match is [ :entity, name, SYSTEM, pubid(, ndata)? ]
289
+ elsif match[2] == 'PUBLIC'
290
+ # External reference
291
+ match[3] = match[3][1..-2] # PUBID
292
+ match[4] = match[4][1..-2] # HREF
293
+ # match is [ :entity, name, PUBLIC, pubid, href ]
294
+ else
295
+ match[2] = match[2][1..-2]
296
+ match.pop if match.size == 4
297
+ # match is [ :entity, name, value ]
298
+ end
299
+ match << '%' if ref
300
+ return match
301
+ when ATTLISTDECL_START
302
+ md = @source.match( ATTLISTDECL_PATTERN, true )
303
+ raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil?
304
+ element = md[1]
305
+ contents = md[0]
306
+
307
+ pairs = {}
308
+ values = md[0].scan( ATTDEF_RE )
309
+ values.each do |attdef|
310
+ unless attdef[3] == "#IMPLIED"
311
+ attdef.compact!
312
+ val = attdef[3]
313
+ val = attdef[4] if val == "#FIXED "
314
+ pairs[attdef[0]] = val
315
+ if attdef[0] =~ /^xmlns:(.*)/
316
+ @nsstack[0] << $1
317
+ end
318
+ end
319
+ end
320
+ return [ :attlistdecl, element, pairs, contents ]
321
+ when NOTATIONDECL_START
322
+ md = nil
323
+ if @source.match( PUBLIC )
324
+ md = @source.match( PUBLIC, true )
325
+ vals = [md[1],md[2],md[4],md[6]]
326
+ elsif @source.match( SYSTEM )
327
+ md = @source.match( SYSTEM, true )
328
+ vals = [md[1],md[2],nil,md[4]]
329
+ else
330
+ raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source )
331
+ end
332
+ return [ :notationdecl, *vals ]
333
+ when CDATA_END
334
+ @document_status = :after_doctype
335
+ @source.match( CDATA_END, true )
336
+ return [ :end_doctype ]
337
+ end
338
+ end
339
+ begin
340
+ if @source.buffer[0] == ?<
341
+ if @source.buffer[1] == ?/
342
+ @nsstack.shift
343
+ last_tag = @tags.pop
344
+ #md = @source.match_to_consume( '>', CLOSE_MATCH)
345
+ md = @source.match( CLOSE_MATCH, true )
346
+ raise REXML::ParseException.new( "Missing end tag for "+
347
+ "'#{last_tag}' (got \"#{md[1]}\")",
348
+ @source) unless last_tag == md[1]
349
+ return [ :end_element, last_tag ]
350
+ elsif @source.buffer[1] == ?!
351
+ md = @source.match(/\A(\s*[^>]*>)/um)
352
+ #STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
353
+ raise REXML::ParseException.new("Malformed node", @source) unless md
354
+ if md[0][2] == ?-
355
+ md = @source.match( COMMENT_PATTERN, true )
356
+
357
+ case md[1]
358
+ when /--/, /-$/
359
+ raise REXML::ParseException.new("Malformed comment", @source)
360
+ end
361
+
362
+ return [ :comment, md[1] ] if md
363
+ else
364
+ md = @source.match( CDATA_PATTERN, true )
365
+ return [ :cdata, md[1] ] if md
366
+ end
367
+ raise REXML::ParseException.new( "Declarations can only occur "+
368
+ "in the doctype declaration.", @source)
369
+ elsif @source.buffer[1] == ??
370
+ md = @source.match( INSTRUCTION_PATTERN, true )
371
+ return [ :processing_instruction, md[1], md[2] ] if md
372
+ raise REXML::ParseException.new( "Bad instruction declaration",
373
+ @source)
374
+ else
375
+ # Get the next tag
376
+ md = @source.match(TAG_MATCH, true)
377
+ unless md
378
+ # Check for missing attribute quotes
379
+ raise REXML::ParseException.new("missing attribute quote", @source) if @source.match(MISSING_ATTRIBUTE_QUOTES )
380
+ raise REXML::ParseException.new("malformed XML: missing tag start", @source)
381
+ end
382
+ attributes = {}
383
+ prefixes = Set.new
384
+ prefixes << md[2] if md[2]
385
+ @nsstack.unshift(curr_ns=Set.new)
386
+ if md[4].size > 0
387
+ attrs = md[4].scan( ATTRIBUTE_PATTERN )
388
+ raise ::REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0
389
+ attrs.each { |a,b,c,d,e|
390
+ if b == "xmlns"
391
+ if c == "xml"
392
+ if d != "http://www.w3.org/XML/1998/namespace"
393
+ msg = "The 'xml' prefix must not be bound to any other namespace "+
394
+ "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
395
+ raise ::REXML::ParseException.new( msg, @source, self )
396
+ end
397
+ elsif c == "xmlns"
398
+ msg = "The 'xmlns' prefix must not be declared "+
399
+ "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
400
+ raise ::REXML::ParseException.new( msg, @source, self)
401
+ end
402
+ curr_ns << c
403
+ elsif b
404
+ prefixes << b unless b == "xml"
405
+ end
406
+
407
+ if attributes.has_key? a
408
+ msg = "Duplicate attribute #{a.inspect}"
409
+ raise ::REXML::ParseException.new( msg, @source, self)
410
+ end
411
+
412
+ attributes[a] = e
413
+ }
414
+ end
415
+
416
+ # Verify that all of the prefixes have been defined
417
+ #for prefix in prefixes
418
+ prefixes.each do |prefix|
419
+ unless @nsstack.find{|k| k.member?(prefix)}
420
+ raise ::REXML::UndefinedNamespaceException.new(prefix,@source,self)
421
+ end
422
+ end
423
+
424
+ if md[6]
425
+ @closed = md[1]
426
+ @nsstack.shift
427
+ else
428
+ @tags.push( md[1] )
429
+ end
430
+ return [ :start_element, md[1], attributes ]
431
+ end
432
+ else
433
+ md = @source.match( TEXT_PATTERN, true )
434
+ if md[0].length == 0
435
+ @source.match( /(\s+)/, true )
436
+ end
437
+ #STDERR.puts "GOT #{md[1].inspect}" unless md[0].length == 0
438
+ #return [ :text, "" ] if md[0].length == 0
439
+ # unnormalized = Text::unnormalize( md[1], self )
440
+ # return PullEvent.new( :text, md[1], unnormalized )
441
+ return [ :text, md[1] ]
442
+ end
443
+ rescue REXML::UndefinedNamespaceException
444
+ raise
445
+ rescue REXML::ParseException
446
+ raise
447
+ rescue Exception, NameError => error
448
+ raise REXML::ParseException.new( "Exception parsing",
449
+ @source, self, (error ? error : $!) )
450
+ end
451
+ return [ :dummy ]
452
+ end
453
+
454
+ def entity( reference, entities )
455
+ value = nil
456
+ value = entities[ reference ] if entities
457
+ if not value
458
+ value = DEFAULT_ENTITIES[ reference ]
459
+ value = value[2] if value
460
+ end
461
+ unnormalize( value, entities ) if value
462
+ end
463
+
464
+ # Escapes all possible entities
465
+ def normalize( input, entities=nil, entity_filter=nil )
466
+ copy = input.clone
467
+ # Doing it like this rather than in a loop improves the speed
468
+ copy.gsub!( EREFERENCE, '&amp;' )
469
+ entities.each do |key, value|
470
+ copy.gsub!( value, "&#{key};" ) unless entity_filter and
471
+ entity_filter.include?(entity)
472
+ end if entities
473
+ copy.gsub!( EREFERENCE, '&amp;' )
474
+ DEFAULT_ENTITIES.each do |key, value|
475
+ copy.gsub!( value[3], value[1] )
476
+ end
477
+ copy
478
+ end
479
+
480
+ # Unescapes all possible entities
481
+ def unnormalize( string, entities=nil, filter=nil )
482
+ rv = string.clone
483
+ rv.gsub!( /\r\n?/, "\n" )
484
+ matches = rv.scan( REFERENCE_RE )
485
+ return rv if matches.size == 0
486
+ rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {
487
+ m=$1
488
+ m = "0#{m}" if m[0] == ?x
489
+ [Integer(m)].pack('U*')
490
+ }
491
+ matches.collect!{|x|x[0]}.compact!
492
+ if matches.size > 0
493
+ matches.each do |entity_reference|
494
+ unless filter and filter.include?(entity_reference)
495
+ entity_value = entity( entity_reference, entities )
496
+ if entity_value
497
+ re = /&#{entity_reference};/
498
+ rv.gsub!( re, entity_value )
499
+ else
500
+ er = DEFAULT_ENTITIES[entity_reference]
501
+ rv.gsub!( er[0], er[2] ) if er
502
+ end
503
+ end
504
+ end
505
+ rv.gsub!( /&amp;/, '&' )
506
+ end
507
+ rv
508
+ end
509
+ end
510
+ end
511
+ end
512
+
513
+ =begin
514
+ case event[0]
515
+ when :start_element
516
+ when :text
517
+ when :end_element
518
+ when :processing_instruction
519
+ when :cdata
520
+ when :comment
521
+ when :xmldecl
522
+ when :start_doctype
523
+ when :end_doctype
524
+ when :externalentity
525
+ when :elementdecl
526
+ when :entity
527
+ when :attlistdecl
528
+ when :notationdecl
529
+ when :end_doctype
530
+ end
531
+ =end