rhodes 2.0.0.beta6 → 2.0.0.beta7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Manifest.txt CHANGED
@@ -56,7 +56,7 @@ lib/extensions/fcntl/ext/fcntl.c
56
56
  lib/extensions/fcntl/ext/Rakefile
57
57
  lib/extensions/fcntl/ext.yml
58
58
  lib/extensions/json/json/common.rb
59
- lib/extensions/json/json/pure/parser.rb
59
+ lib/extensions/json/json/pure/generator.rb
60
60
  lib/extensions/json/json/pure.rb
61
61
  lib/extensions/json/json/version.rb
62
62
  lib/extensions/json/json.rb
@@ -212,7 +212,9 @@ lib/framework/rhoframework.rb
212
212
  lib/framework/rhofsconnector.rb
213
213
  lib/framework/rholang/lang_en.rb
214
214
  lib/framework/rholang/localization_simplified.rb
215
+ lib/framework/rholang/rhoerror_de.rb
215
216
  lib/framework/rholang/rhoerror_en.rb
217
+ lib/framework/rholang/rhomsg_de.rb
216
218
  lib/framework/rholang/rhomsg_en.rb
217
219
  lib/framework/rhom/rhom.rb
218
220
  lib/framework/rhom/rhom_db_adapter.rb
@@ -44,8 +44,10 @@ module JSON
44
44
  # Set the module _generator_ to be used by JSON.
45
45
  def generator=(generator) # :nodoc:
46
46
  @generator = generator
47
+
47
48
  generator_methods = generator::GeneratorMethods
48
- for const in generator_methods.constants
49
+ #for const in generator_methods.constants
50
+ generator_methods.constants.each do |const|
49
51
  klass = deep_const_get(const)
50
52
  modul = generator_methods.const_get(const)
51
53
  klass.class_eval do
@@ -117,10 +119,10 @@ module JSON
117
119
  # * *create_additions*: If set to false, the Parser doesn't create
118
120
  # additions even if a matchin class and create_id was found. This option
119
121
  # defaults to true.
120
- def parse(source, opts = {})
121
- JSON.parser.new(source, opts).parse
122
- end
123
- module_function :parse
122
+ #def parse(source, opts = {})
123
+ # JSON.parser.new(source, opts).parse
124
+ #end
125
+ #module_function :parse
124
126
 
125
127
  # Parse the JSON string _source_ into a Ruby data structure and return it.
126
128
  # The bang version of the parse method, defaults to the more dangerous values
@@ -137,13 +139,13 @@ module JSON
137
139
  # * *create_additions*: If set to false, the Parser doesn't create
138
140
  # additions even if a matchin class and create_id was found. This option
139
141
  # defaults to true.
140
- def parse!(source, opts = {})
141
- opts = {
142
- :max_nesting => false,
143
- :allow_nan => true
144
- }.update(opts)
145
- JSON.parser.new(source, opts).parse
146
- end
142
+ #def parse!(source, opts = {})
143
+ # opts = {
144
+ # :max_nesting => false,
145
+ # :allow_nan => true
146
+ # }.update(opts)
147
+ # JSON.parser.new(source, opts).parse
148
+ #end
147
149
 
148
150
  # Unparse the Ruby data structure _obj_ into a single line JSON string and
149
151
  # return it. _state_ is
@@ -174,6 +176,7 @@ module JSON
174
176
  # See also the fast_generate for the fastest creation method with the least
175
177
  # amount of sanity checks, and the pretty_generate method for some
176
178
  # defaults for a pretty output.
179
+ module_function
177
180
  def generate(obj, state = nil)
178
181
  if state
179
182
  state = State.from_state(state)
@@ -182,7 +185,8 @@ module JSON
182
185
  end
183
186
  obj.to_json(state)
184
187
  end
185
-
188
+ module_function :generate
189
+
186
190
  # :stopdoc:
187
191
  # I want to deprecate these later, so I'll first be silent about them, and
188
192
  # later delete them.
@@ -0,0 +1,431 @@
1
+
2
+ module JSON
3
+ =begin
4
+ MAP = {
5
+ "\x0" => '\u0000',
6
+ "\x1" => '\u0001',
7
+ "\x2" => '\u0002',
8
+ "\x3" => '\u0003',
9
+ "\x4" => '\u0004',
10
+ "\x5" => '\u0005',
11
+ "\x6" => '\u0006',
12
+ "\x7" => '\u0007',
13
+ "\b" => '\b',
14
+ "\t" => '\t',
15
+ "\n" => '\n',
16
+ "\xb" => '\u000b',
17
+ "\f" => '\f',
18
+ "\r" => '\r',
19
+ "\xe" => '\u000e',
20
+ "\xf" => '\u000f',
21
+ "\x10" => '\u0010',
22
+ "\x11" => '\u0011',
23
+ "\x12" => '\u0012',
24
+ "\x13" => '\u0013',
25
+ "\x14" => '\u0014',
26
+ "\x15" => '\u0015',
27
+ "\x16" => '\u0016',
28
+ "\x17" => '\u0017',
29
+ "\x18" => '\u0018',
30
+ "\x19" => '\u0019',
31
+ "\x1a" => '\u001a',
32
+ "\x1b" => '\u001b',
33
+ "\x1c" => '\u001c',
34
+ "\x1d" => '\u001d',
35
+ "\x1e" => '\u001e',
36
+ "\x1f" => '\u001f',
37
+ '"' => '\"',
38
+ '\\' => '\\\\',
39
+ } # :nodoc:
40
+
41
+ # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
42
+ # UTF16 big endian characters as \u????, and return it.
43
+ if String.method_defined?(:force_encoding)
44
+ def utf8_to_json(string) # :nodoc:
45
+ string = string.dup
46
+ string << '' # XXX workaround: avoid buffer sharing
47
+ string.force_encoding(Encoding::ASCII_8BIT)
48
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
49
+ string.gsub!(/(
50
+ (?:
51
+ [\xc2-\xdf][\x80-\xbf] |
52
+ [\xe0-\xef][\x80-\xbf]{2} |
53
+ [\xf0-\xf4][\x80-\xbf]{3}
54
+ )+ |
55
+ [\x80-\xc1\xf5-\xff] # invalid
56
+ )/nx) { |c|
57
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
58
+ s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
59
+ s.gsub!(/.{4}/n, '\\\\u\&')
60
+ }
61
+ string.force_encoding(Encoding::UTF_8)
62
+ string
63
+ rescue Iconv::Failure => e
64
+ raise GeneratorError, "Caught #{e.class}: #{e}"
65
+ end
66
+ else
67
+ def utf8_to_json(string) # :nodoc:
68
+ string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
69
+ string.gsub!(/(
70
+ (?:
71
+ [\xc2-\xdf][\x80-\xbf] |
72
+ [\xe0-\xef][\x80-\xbf]{2} |
73
+ [\xf0-\xf4][\x80-\xbf]{3}
74
+ )+ |
75
+ [\x80-\xc1\xf5-\xff] # invalid
76
+ )/nx) { |c|
77
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
78
+ s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
79
+ s.gsub!(/.{4}/n, '\\\\u\&')
80
+ }
81
+ string
82
+ rescue Iconv::Failure => e
83
+ raise GeneratorError, "Caught #{e.class}: #{e}"
84
+ end
85
+ end
86
+ module_function :utf8_to_json
87
+ =end
88
+ module Pure
89
+ module Generator
90
+ # This class is used to create State instances, that are use to hold data
91
+ # while generating a JSON text from a a Ruby data structure.
92
+ class State
93
+ # Creates a State object from _opts_, which ought to be Hash to create
94
+ # a new State instance configured by _opts_, something else to create
95
+ # an unconfigured instance. If _opts_ is a State object, it is just
96
+ # returned.
97
+ def self.from_state(opts)
98
+ case opts
99
+ when self
100
+ opts
101
+ when Hash
102
+ new(opts)
103
+ else
104
+ new
105
+ end
106
+ end
107
+
108
+ # Instantiates a new State object, configured by _opts_.
109
+ #
110
+ # _opts_ can have the following keys:
111
+ #
112
+ # * *indent*: a string used to indent levels (default: ''),
113
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
114
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
115
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
116
+ # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
117
+ # * *check_circular*: true if checking for circular data structures
118
+ # should be done (the default), false otherwise.
119
+ # * *check_circular*: true if checking for circular data structures
120
+ # should be done, false (the default) otherwise.
121
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
122
+ # generated, otherwise an exception is thrown, if these values are
123
+ # encountered. This options defaults to false.
124
+ def initialize(opts = {})
125
+ @seen = {}
126
+ @indent = ''
127
+ @space = ''
128
+ @space_before = ''
129
+ @object_nl = ''
130
+ @array_nl = ''
131
+ @check_circular = true
132
+ @allow_nan = false
133
+ configure opts
134
+ end
135
+
136
+ # This string is used to indent levels in the JSON text.
137
+ attr_accessor :indent
138
+
139
+ # This string is used to insert a space between the tokens in a JSON
140
+ # string.
141
+ attr_accessor :space
142
+
143
+ # This string is used to insert a space before the ':' in JSON objects.
144
+ attr_accessor :space_before
145
+
146
+ # This string is put at the end of a line that holds a JSON object (or
147
+ # Hash).
148
+ attr_accessor :object_nl
149
+
150
+ # This string is put at the end of a line that holds a JSON array.
151
+ attr_accessor :array_nl
152
+
153
+ # This integer returns the maximum level of data structure nesting in
154
+ # the generated JSON, max_nesting = 0 if no maximum is checked.
155
+ attr_accessor :max_nesting
156
+
157
+ def check_max_nesting(depth) # :nodoc:
158
+ return if @max_nesting.zero?
159
+ current_nesting = depth + 1
160
+ current_nesting > @max_nesting and
161
+ raise NestingError, "nesting of #{current_nesting} is too deep"
162
+ end
163
+
164
+ # Returns true, if circular data structures should be checked,
165
+ # otherwise returns false.
166
+ def check_circular?
167
+ @check_circular
168
+ end
169
+
170
+ # Returns true if NaN, Infinity, and -Infinity should be considered as
171
+ # valid JSON and output.
172
+ def allow_nan?
173
+ @allow_nan
174
+ end
175
+
176
+ # Returns _true_, if _object_ was already seen during this generating
177
+ # run.
178
+ def seen?(object)
179
+ @seen.key?(object.__id__)
180
+ end
181
+
182
+ # Remember _object_, to find out if it was already encountered (if a
183
+ # cyclic data structure is if a cyclic data structure is rendered).
184
+ def remember(object)
185
+ @seen[object.__id__] = true
186
+ end
187
+
188
+ # Forget _object_ for this generating run.
189
+ def forget(object)
190
+ @seen.delete object.__id__
191
+ end
192
+
193
+ # Configure this State instance with the Hash _opts_, and return
194
+ # itself.
195
+ def configure(opts)
196
+ @indent = opts[:indent] if opts.key?(:indent)
197
+ @space = opts[:space] if opts.key?(:space)
198
+ @space_before = opts[:space_before] if opts.key?(:space_before)
199
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
200
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
201
+ @check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
202
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
203
+ if !opts.key?(:max_nesting) # defaults to 19
204
+ @max_nesting = 19
205
+ elsif opts[:max_nesting]
206
+ @max_nesting = opts[:max_nesting]
207
+ else
208
+ @max_nesting = 0
209
+ end
210
+ self
211
+ end
212
+
213
+ # Returns the configuration instance variables as a hash, that can be
214
+ # passed to the configure method.
215
+ def to_h
216
+ result = {}
217
+ for iv in %w[indent space space_before object_nl array_nl check_circular allow_nan max_nesting]
218
+ result[iv.intern] = instance_variable_get("@#{iv}")
219
+ end
220
+ result
221
+ end
222
+ end
223
+
224
+ module GeneratorMethods
225
+ module Object
226
+ # Converts this object to a string (calling #to_s), converts
227
+ # it to a JSON string, and returns the result. This is a fallback, if no
228
+ # special method #to_json was defined for some object.
229
+ def to_json(*) to_s.to_json end
230
+ end
231
+
232
+ module Hash
233
+ # Returns a JSON string containing a JSON object, that is unparsed from
234
+ # this Hash instance.
235
+ # _state_ is a JSON::State object, that can also be used to configure the
236
+ # produced JSON string output further.
237
+ # _depth_ is used to find out nesting depth, to indent accordingly.
238
+ def to_json(state = nil, depth = 0, *)
239
+ if state
240
+ state = JSON.state.from_state(state)
241
+ state.check_max_nesting(depth)
242
+ json_check_circular(state) { json_transform(state, depth) }
243
+ else
244
+ json_transform(state, depth)
245
+ end
246
+ end
247
+
248
+ private
249
+
250
+ def json_check_circular(state)
251
+ if state and state.check_circular?
252
+ state.seen?(self) and raise JSON::CircularDatastructure,
253
+ "circular data structures not supported!"
254
+ state.remember self
255
+ end
256
+ yield
257
+ ensure
258
+ state and state.forget self
259
+ end
260
+
261
+ def json_shift(state, depth)
262
+ state and not state.object_nl.empty? or return ''
263
+ state.indent * depth
264
+ end
265
+
266
+ def json_transform(state, depth)
267
+ delim = ','
268
+ if state
269
+ delim << state.object_nl
270
+ result = '{'
271
+ result << state.object_nl
272
+ result << map { |key,value|
273
+ s = json_shift(state, depth + 1)
274
+ s << key.to_s.to_json(state, depth + 1)
275
+ s << state.space_before
276
+ s << ':'
277
+ s << state.space
278
+ s << value.to_json(state, depth + 1)
279
+ }.join(delim)
280
+ result << state.object_nl
281
+ result << json_shift(state, depth)
282
+ result << '}'
283
+ else
284
+ result = '{'
285
+ result << map { |key,value|
286
+ key.to_s.to_json << ':' << value.to_json
287
+ }.join(delim)
288
+ result << '}'
289
+ end
290
+ result
291
+ end
292
+ end
293
+
294
+ module Array
295
+ # Returns a JSON string containing a JSON array, that is unparsed from
296
+ # this Array instance.
297
+ # _state_ is a JSON::State object, that can also be used to configure the
298
+ # produced JSON string output further.
299
+ # _depth_ is used to find out nesting depth, to indent accordingly.
300
+ def to_json(state = nil, depth = 0, *)
301
+ if state
302
+ state = JSON.state.from_state(state)
303
+ state.check_max_nesting(depth)
304
+ json_check_circular(state) { json_transform(state, depth) }
305
+ else
306
+ json_transform(state, depth)
307
+ end
308
+ end
309
+
310
+ private
311
+
312
+ def json_check_circular(state)
313
+ if state and state.check_circular?
314
+ state.seen?(self) and raise JSON::CircularDatastructure,
315
+ "circular data structures not supported!"
316
+ state.remember self
317
+ end
318
+ yield
319
+ ensure
320
+ state and state.forget self
321
+ end
322
+
323
+ def json_shift(state, depth)
324
+ state and not state.array_nl.empty? or return ''
325
+ state.indent * depth
326
+ end
327
+
328
+ def json_transform(state, depth)
329
+ delim = ','
330
+ if state
331
+ delim << state.array_nl
332
+ result = '['
333
+ result << state.array_nl
334
+ result << map { |value|
335
+ json_shift(state, depth + 1) << value.to_json(state, depth + 1)
336
+ }.join(delim)
337
+ result << state.array_nl
338
+ result << json_shift(state, depth)
339
+ result << ']'
340
+ else
341
+ '[' << map { |value| value.to_json }.join(delim) << ']'
342
+ end
343
+ end
344
+ end
345
+
346
+ module Integer
347
+ # Returns a JSON string representation for this Integer number.
348
+ def to_json(*) to_s end
349
+ end
350
+
351
+ module Float
352
+ # Returns a JSON string representation for this Float number.
353
+ def to_json(state = nil, *)
354
+ case
355
+ when infinite?
356
+ if !state || state.allow_nan?
357
+ to_s
358
+ else
359
+ raise GeneratorError, "#{self} not allowed in JSON"
360
+ end
361
+ when nan?
362
+ if !state || state.allow_nan?
363
+ to_s
364
+ else
365
+ raise GeneratorError, "#{self} not allowed in JSON"
366
+ end
367
+ else
368
+ to_s
369
+ end
370
+ end
371
+ end
372
+
373
+ module String
374
+ # This string should be encoded with UTF-8 A call to this method
375
+ # returns a JSON string encoded with UTF16 big endian characters as
376
+ # \u????.
377
+ def to_json(*)
378
+ '"' << self << '"' #JSON.utf8_to_json(self) << '"'
379
+ end
380
+
381
+ # Module that holds the extinding methods if, the String module is
382
+ # included.
383
+ module Extend
384
+ # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
385
+ # key "raw"). The Ruby String can be created by this module method.
386
+ def json_create(o)
387
+ o['raw'].pack('C*')
388
+ end
389
+ end
390
+
391
+ # Extends _modul_ with the String::Extend module.
392
+ def self.included(modul)
393
+ modul.extend Extend
394
+ end
395
+
396
+ # This method creates a raw object hash, that can be nested into
397
+ # other data structures and will be unparsed as a raw string. This
398
+ # method should be used, if you want to convert raw strings to JSON
399
+ # instead of UTF-8 strings, e. g. binary data.
400
+ def to_json_raw_object
401
+ {
402
+ JSON.create_id => self.class.name,
403
+ 'raw' => self.unpack('C*'),
404
+ }
405
+ end
406
+
407
+ # This method creates a JSON text from the result of
408
+ # a call to to_json_raw_object of this String.
409
+ def to_json_raw(*args)
410
+ to_json_raw_object.to_json(*args)
411
+ end
412
+ end
413
+
414
+ module TrueClass
415
+ # Returns a JSON string for true: 'true'.
416
+ def to_json(*) 'true' end
417
+ end
418
+
419
+ module FalseClass
420
+ # Returns a JSON string for false: 'false'.
421
+ def to_json(*) 'false' end
422
+ end
423
+
424
+ module NilClass
425
+ # Returns a JSON string for nil: 'null'.
426
+ def to_json(*) 'null' end
427
+ end
428
+ end
429
+ end
430
+ end
431
+ end
@@ -1,6 +1,6 @@
1
1
  require 'json/common'
2
- require 'json/pure/parser'
3
- #require 'json/pure/generator'
2
+ #require 'json/pure/parser'
3
+ require 'json/pure/generator'
4
4
 
5
5
  module JSON
6
6
  begin
@@ -69,8 +69,8 @@ module JSON
69
69
  # functionality in pure ruby.
70
70
  module Pure
71
71
  $DEBUG and warn "Using pure library for JSON."
72
- JSON.parser = Parser
73
- #JSON.generator = Generator
72
+ #JSON.parser = Parser
73
+ JSON.generator = Generator
74
74
  end
75
75
 
76
76
  JSON_LOADED = true
@@ -0,0 +1,36 @@
1
+ module Rho
2
+ class RhoError < Exception
3
+ def self.err_message(code)
4
+ if code == ERR_NETWORK
5
+ return "Netzwerkverbindung konnte nicht hergestellt werden."
6
+ elsif code == ERR_REMOTESERVER
7
+ return "Server gab Fehler zurück."
8
+ elsif code == ERR_RUNTIME
9
+ return "Die Applikation hat einen Fehler verursacht und muss beendet werden."
10
+ elsif code == ERR_UNEXPECTEDSERVERRESPONSE
11
+ return "Synchronisationsserver antwortete unerwartet."
12
+ elsif code == ERR_DIFFDOMAINSINSYNCSRC
13
+ return "Alle Synchronisationsquellen sollten von der gleichen Domain stammen.Installiere die Applikation erneut."
14
+ elsif code == ERR_NOSERVERRESPONSE
15
+ return "Verbindung zum Synchronisationsserver konnte nicht hergestellt werden."
16
+ elsif code == ERR_CLIENTISNOTLOGGEDIN
17
+ return "Client ist nicht eingeloggt. Keine Synchronisation wird durchgeführt."
18
+ elsif code == ERR_CUSTOMSYNCSERVER
19
+ return "Verbindung zum Datenserver konnte nicht hergestellt werden."
20
+ elsif code == ERR_UNATHORIZED
21
+ return "Eingabe eines falschen Benutzernamens/Passwortes, bitte versuchen Sie es erneut."
22
+ elsif code == ERR_CANCELBYUSER
23
+ return "Operation wurde durch den User abgebrochen."
24
+ elsif code == ERR_SYNCVERSION
25
+ return "Verbindung durch Server beendet. Ihr mobile Applikation muss aktualisiert werden. Bitte kontaktieren sie Ihren Administrator."
26
+ elsif code == ERR_GEOLOCATION
27
+ return "Ortsangabe konnte nicht bestimmt werden."
28
+ elsif code == ERR_NONE
29
+ return ""
30
+ end
31
+
32
+ return "Unbekannter Fehler"
33
+ end
34
+
35
+ end # RhoError
36
+ end # Rho
@@ -0,0 +1,28 @@
1
+ module Rho
2
+ class RhoMessages
3
+ LocalMessages = {
4
+ 'sync_failed_for' => "Synchronisation fehlgeschlagen für ",
5
+ 'details' => " Details: ",
6
+ 'sync_completed' => "Synchronisation abgeschlossen.",
7
+ 'syncronizing' => "Synchronisiere ",
8
+ 'syncronizing_data' => "Synchronisiere Daten...",
9
+
10
+ 'home_menu' => "Home",
11
+ 'refresh_menu' => "Refresh",
12
+ 'back_menu' => "Back",
13
+ 'sync_menu' => "Sync",
14
+ 'options_menu' => "Options",
15
+ 'log_menu' => "Log",
16
+ 'close_menu' => "Close",
17
+ 'get_link_menu' => "Link abrufen",
18
+ 'open_link_menu' => "Open Link",
19
+ 'email_menu' => "Email",
20
+ 'call_menu' => "Call",
21
+ 'sms_menu' => "SMS",
22
+ 'add_contacts_menu' => "Add to Contacts",
23
+
24
+ 'hide' => 'Hide'
25
+ }
26
+
27
+ end # RhoMessages
28
+ end # Rho
@@ -7,7 +7,7 @@ USE_TRACES = false
7
7
 
8
8
  ANDROID_API_LEVEL_TO_MARKET_VERSION = {}
9
9
  ANDROID_MARKET_VERSION_TO_API_LEVEL = {}
10
- {2 => "1.1", 3 => "1.5", 4 => "1.6", 5 => "2.0", 6 => "2.0.1", 7 => "2.1"}.each do |k,v|
10
+ {2 => "1.1", 3 => "1.5", 4 => "1.6", 5 => "2.0", 6 => "2.0.1", 7 => "2.1", 8 => "2.2"}.each do |k,v|
11
11
  ANDROID_API_LEVEL_TO_MARKET_VERSION[k] = v
12
12
  ANDROID_MARKET_VERSION_TO_API_LEVEL[v] = k
13
13
  end
@@ -337,11 +337,11 @@ namespace "config" do
337
337
  $objdir = {}
338
338
  $libname = {}
339
339
  $native_libs.each do |x|
340
- $objdir[x] = File.join($rhobindir, $confdir, "lib" + x)
341
- $libname[x] = File.join($rhobindir, $confdir, "lib" + x + ".a")
340
+ $objdir[x] = File.join($rhobindir, $confdir, $ndkgccver, "lib" + x)
341
+ $libname[x] = File.join($rhobindir, $confdir, $ndkgccver, "lib" + x + ".a")
342
342
  end
343
343
 
344
- $extensionsdir = $bindir + "/libs/" + $confdir + "/extensions"
344
+ $extensionsdir = $bindir + "/libs/" + $confdir + "/" + $ndkgccver + "/extensions"
345
345
 
346
346
  $app_config["extensions"] = [] if $app_config["extensions"].nil?
347
347
  $app_config["extensions"] = [] unless $app_config["extensions"].is_a? Array
@@ -724,8 +724,8 @@ namespace "build" do
724
724
 
725
725
  task :librhodes => [:libs, :gensources] do
726
726
  srcdir = File.join $androidpath, "Rhodes", "jni", "src"
727
- objdir = File.join $bindir, "libs", $confdir, "librhodes"
728
- libname = File.join $bindir, "libs", $confdir, "librhodes.so"
727
+ objdir = File.join $bindir, "libs", $confdir, $ndkgccver, "librhodes"
728
+ libname = File.join $bindir, "libs", $confdir, $ndkgccver, "librhodes.so"
729
729
 
730
730
  args = []
731
731
  args << "-I#{$appincdir}"
@@ -749,8 +749,8 @@ namespace "build" do
749
749
  end
750
750
 
751
751
  args = []
752
- args << "-L#{$rhobindir}/#{$confdir}"
753
- args << "-L#{$bindir}/libs/#{$confdir}"
752
+ args << "-L#{$rhobindir}/#{$confdir}/#{$ndkgccver}"
753
+ args << "-L#{$bindir}/libs/#{$confdir}/#{$ndkgccver}"
754
754
  args << "-L#{$extensionsdir}"
755
755
 
756
756
  rlibs = []
@@ -926,8 +926,8 @@ namespace "package" do
926
926
  next unless File.basename(f) =~ /^_/
927
927
  relpath = Pathname.new(f).relative_path_from(Pathname.new($tmpdir)).to_s
928
928
  puts "Add #{relpath} to #{resourcepkg}..."
929
- args = ["add", resourcepkg, relpath]
930
- puts Jake.run($aapt, args, $tmpdir)
929
+ args = ["uf", resourcepkg, relpath]
930
+ puts Jake.run($jarbin, args, $tmpdir)
931
931
  unless $? == 0
932
932
  puts "Error running AAPT (2)"
933
933
  exit 1
@@ -937,18 +937,18 @@ namespace "package" do
937
937
  # Add native librhodes.so
938
938
  rm_rf File.join($tmpdir, "lib")
939
939
  mkdir_p File.join($tmpdir, "lib/armeabi")
940
- cp_r File.join($bindir, "libs", $confdir, "librhodes.so"), File.join($tmpdir, "lib/armeabi")
940
+ cp_r File.join($bindir, "libs", $confdir, $ndkgccver, "librhodes.so"), File.join($tmpdir, "lib/armeabi")
941
941
  # Add extensions .so libraries
942
942
  Dir.glob($extensionsdir + "/lib*.so").each do |lib|
943
943
  cp_r lib, File.join($tmpdir, "lib/armeabi")
944
944
  end
945
- args = ["add", resourcepkg]
945
+ args = ["uf", resourcepkg]
946
946
  # Strip them all to decrease size
947
947
  Dir.glob($tmpdir + "/lib/armeabi/lib*.so").each do |lib|
948
948
  cc_run($stripbin, [lib])
949
949
  args << "lib/armeabi/#{File.basename(lib)}"
950
950
  end
951
- puts Jake.run($aapt, args, $tmpdir)
951
+ puts Jake.run($jarbin, args, $tmpdir)
952
952
  err = $?
953
953
  rm_rf $tmpdir + "/lib"
954
954
  unless err == 0
@@ -1229,8 +1229,8 @@ namespace "clean" do
1229
1229
  end
1230
1230
  end
1231
1231
  task :librhodes => "config:android" do
1232
- rm_rf $rhobindir + "/" + $confdir + "/librhodes"
1233
- rm_rf $bindir + "/libs/" + $confdir + "/librhodes.so"
1232
+ rm_rf $rhobindir + "/" + $confdir + "/" + $ndkgccver + "/librhodes"
1233
+ rm_rf $bindir + "/libs/" + $confdir + "/" + $ndkgccver + "/librhodes.so"
1234
1234
  end
1235
1235
  # desc "clean android"
1236
1236
  task :all => [:assets,:librhodes,:libs,:files]
@@ -30,6 +30,22 @@ def setup_ndk(ndkpath,apilevel)
30
30
  name = tool.gsub('+', 'p')
31
31
  eval "$#{name}bin = $ndktools + '/bin/arm-eabi-#{tool}' + $exe_ext"
32
32
  end
33
+
34
+ # Detect rlim_t
35
+ if $have_rlim_t.nil?
36
+ $have_rlim_t = false
37
+ resource_h = File.join(ndkpath, 'build', 'platforms', "android-#{apilevel}", "arch-arm", "usr", "include", "sys", "resource.h")
38
+ if File.exists? resource_h
39
+ File.open(resource_h, 'r') do |f|
40
+ while line = f.gets
41
+ if line =~ /^\s*typedef\b.*\brlim_t\s*;\s*$/
42
+ $have_rlim_t = true;
43
+ break;
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
33
49
  end
34
50
 
35
51
  def cc_def_args
@@ -43,6 +59,7 @@ def cc_def_args
43
59
  args << "-DANDROID"
44
60
  args << "-DOS_ANDROID"
45
61
  args << "-DRHO_DEBUG"
62
+ args << "-DHAVE_RLIM_T" if $have_rlim_t
46
63
  args << "-g"
47
64
  if $build_release
48
65
  args << "-O2"
@@ -161,7 +178,6 @@ def cc_link(outname, objects, additional = nil, deps = nil)
161
178
  args << "-Wl,--no-whole-archive"
162
179
  args << "-Wl,--no-undefined"
163
180
  args << "-Wl,-z,defs"
164
- args << "-shared"
165
181
  args << "-fPIC"
166
182
  args << "-Wl,-soname,#{File.basename(outname)}"
167
183
  args << "-o"
@@ -170,14 +186,21 @@ def cc_link(outname, objects, additional = nil, deps = nil)
170
186
  args += additional if additional.is_a? Array and not additional.empty?
171
187
  args << "-L#{$ndksysroot}/usr/lib"
172
188
  args << "-Wl,-rpath-link=#{$ndksysroot}/usr/lib"
173
- args << "#{$ndksysroot}/usr/lib/libstdc++.so"
174
- args << "#{$ndksysroot}/usr/lib/libsupc++.so" unless USE_STLPORT
175
- libgccdir = File.join($ndktools, "lib/gcc/arm-eabi", $ndkgccver)
176
- libgccdir = File.join(libgccdir, "interwork") if $ndkgccver == "4.2.1"
177
- args << "#{libgccdir}/libgcc.a" if $ndkgccver != "4.2.1"
189
+ if $cxxlibs.nil?
190
+ $cxxlibs = []
191
+ if USE_STLPORT
192
+ $cxxlibs << File.join($ndksysroot, "usr/lib/libstdc++.so")
193
+ else
194
+ $cxxlibs << `#{$gccbin} -mthumb-interwork -print-file-name=libstdc++.a`.gsub("\n", "")
195
+ $cxxlibs << `#{$gccbin} -mthumb-interwork -print-file-name=libsupc++.a`.gsub("\n", "")
196
+ end
197
+ end
198
+ args += $cxxlibs
199
+ $libgcc = `#{$gccbin} -mthumb-interwork -print-file-name=libgcc.a`.gsub("\n", "") if $libgcc.nil?
200
+ args << $libgcc
178
201
  args << "#{$ndksysroot}/usr/lib/libc.so"
179
202
  args << "#{$ndksysroot}/usr/lib/libm.so"
180
- args << "#{libgccdir}/libgcc.a" if $ndkgccver == "4.2.1"
203
+ args << $libgcc
181
204
  cc_run($gccbin, args)
182
205
  end
183
206
 
@@ -1,4 +1,26 @@
1
1
  #
2
+ require "fileutils"
3
+
4
+ def fixWin7SimBug (rhoconfig)
5
+ file = rhoconfig
6
+ tmpfile = file + ".tmp"
7
+ no_deviceside_postfix_isFound = 0
8
+ File.open(file, 'r') do |f|
9
+ File.open(tmpfile, 'w') do |newf|
10
+ while line = f.gets
11
+ if line =~ /^\s*no_deviceside_postfix\s*=/
12
+ no_deviceside_postfix_isFound = 1
13
+ end
14
+ newf.puts line
15
+ end
16
+ if no_deviceside_postfix_isFound == 0
17
+ newf.puts "no_deviceside_postfix = 1"
18
+ end
19
+ end
20
+ end
21
+ FileUtils.move(tmpfile, file)
22
+ end
23
+
2
24
 
3
25
  def freplace( fname, pattern, str )
4
26
  f = File.open( fname )
@@ -132,6 +154,7 @@ namespace "config" do
132
154
  $excludeextlib = ['rexml/parsers/baseparser.rb', 'rexml/set.rb']
133
155
  $compileERB = $app_path + "/build/compileERB.rb"
134
156
  $tmpdir = $bindir +"/tmp"
157
+ $tmpdir_sim = $bindir +"/tmp_sim"
135
158
 
136
159
  $assetfolder = $app_path + "/public-" + "bb-" + $bbver
137
160
 
@@ -154,7 +177,9 @@ namespace "config" do
154
177
 
155
178
  mkdir_p $bindir unless File.exists? $bindir
156
179
  rm_rf $tmpdir
180
+ rm_rf $tmpdir_sim
157
181
  mkdir_p $tmpdir unless File.exists? $tmpdir
182
+ mkdir_p $tmpdir_sim unless File.exists? $tmpdir_sim
158
183
  mkdir_p $targetdir if not FileTest.exists? $targetdir
159
184
 
160
185
  File.open("#{$bindir}/lastver", "w") {|f| f.write($bbver)}
@@ -172,7 +197,7 @@ namespace "build" do
172
197
  def runPreverify(args)
173
198
  jdehome = $config["env"]["paths"][$bbver]["jde"]
174
199
 
175
- startdir = pwd
200
+ startdir = pwd
176
201
  chdir $tmpdir
177
202
  puts Jake.run(jdehome + "/bin/preverify.exe",args)
178
203
  chdir startdir
@@ -529,6 +554,70 @@ namespace "package" do
529
554
  create_alx_file('rhodesApp', $outfilebase)
530
555
  end
531
556
 
557
+ # desc "Package all production (all parts in one package) for simulator"
558
+ task :production_sim => ["build:bb:rhodes"] do
559
+ jdehome = $config["env"]["paths"][$bbver]["jde"]
560
+ rm_rf $tmpdir_sim
561
+ mkdir_p $tmpdir_sim
562
+
563
+ rm_rf $targetdir
564
+ mkdir_p $targetdir
565
+
566
+ Jake.unjar($preverified + "/RubyVM.jar", $tmpdir_sim)
567
+ Jake.unjar($preverified + "/RhoBundle.jar", $tmpdir_sim)
568
+ Jake.unjar($preverified + "/rhodes.jar", $tmpdir_sim)
569
+
570
+ #Changing rhoconfig.txt to work on Windows 7
571
+ if RUBY_PLATFORM =~ /(win|w)32$/
572
+ require 'win32/registry'
573
+
574
+ def getWindowsProductNameString
575
+ Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\Windows NT\CurrentVersion') do |reg|
576
+ reg_typ, reg_val = reg.read('ProductName')
577
+ return reg_val
578
+ end
579
+ end
580
+
581
+ if getWindowsProductNameString =~ /Windows 7/
582
+ fixWin7SimBug($tmpdir_sim + "/apps/rhoconfig.txt")
583
+ end
584
+ end
585
+
586
+ if $bbver =~ /^4\.[012](\..*)$/
587
+ max_size = 65536
588
+ Dir.glob( $tmpdir_sim + "/**/*" ).each do |f|
589
+ if File.size( f ) > max_size
590
+ puts "File size of " + f + " is more than " + max_size.to_s + " bytes"
591
+ puts "There is no ability to pack this file into .cod file for BB " + $bbver
592
+ puts "Please reduce its size and try again"
593
+ $stdout.flush
594
+ Process.exit
595
+ end
596
+ end
597
+ end
598
+
599
+ Jake.jar($bindir + "/" + $outfilebase + ".jar",$builddir + "/manifest.mf",$tmpdir_sim,true)
600
+
601
+ Jake.rapc($outfilebase,
602
+ $targetdir,
603
+ jdehome + "/lib/net_rim_api.jar",
604
+ $bindir + "/" + $outfilebase + ".jar",
605
+ $appname,
606
+ $app_config["vendor"],
607
+ $app_config["version"],
608
+ "resources/icon.png",
609
+ false,
610
+ true
611
+ )
612
+ unless $? == 0
613
+ puts "Error in RAPC"
614
+ exit 1
615
+ end
616
+ $stdout.flush
617
+
618
+ create_alx_file('rhodesApp', $outfilebase)
619
+ end
620
+
532
621
  task :set_dev_build do
533
622
  $dev_build = true
534
623
  end
@@ -626,6 +715,11 @@ namespace "clean" do
626
715
  rm_rf $tmpdir
627
716
  end
628
717
 
718
+ # desc "Clean temp simulator dir"
719
+ task :tempdir_sim => "config:bb" do
720
+ rm_rf $tmpdir_sim
721
+ end
722
+
629
723
  # desc "Clean all"
630
724
  task :all => [:preverified,:packaged,:tempdir] do
631
725
  rm_rf $bindir
@@ -650,7 +744,7 @@ namespace "run" do
650
744
  end
651
745
 
652
746
  desc "Builds everything, loads and starts bb sim and mds"
653
- task :bb => ["run:bb:stopmdsandsim", "package:bb:production"] do
747
+ task :bb => ["run:bb:stopmdsandsim", "package:bb:production_sim"] do
654
748
  jde = $config["env"]["paths"][$bbver]["jde"]
655
749
 
656
750
  cp_r File.join($targetdir,"/."), jde + "/simulator"
@@ -677,8 +771,8 @@ namespace "config" do
677
771
  desc "Check local blackberry configuration"
678
772
  task :checkbb => ["config:bb"] do
679
773
  javahome = $config["env"]["paths"]["java"]
680
- jdehome = $config["env"]["paths"][$bbver]["jde"]
681
- mdshome = $config["env"]["paths"][$bbver]["mds"]
774
+ jdehome = $config["env"]["paths"][$bbver]["jde"]
775
+ mdshome = $config["env"]["paths"][$bbver]["mds"]
682
776
 
683
777
  puts "BBVER: " + $bbver
684
778
  puts "JAVAHOME: " + javahome
@@ -43,8 +43,13 @@ public class NetworkAccess implements INetworkAccess {
43
43
  strDeviceside = "";
44
44
 
45
45
  if (DeviceInfo.isSimulator()) {
46
- URLsuffix = ";deviceside=true";
47
- WIFIsuffix = ";interface=wifi;deviceside=true";
46
+ if (com.rho.RhoConf.getInstance().getInt("no_deviceside_postfix") == 1) {
47
+ URLsuffix = "";
48
+ WIFIsuffix = ";interface=wifi";
49
+ } else {
50
+ URLsuffix = ";deviceside=true";
51
+ WIFIsuffix = ";interface=wifi;deviceside=true";
52
+ }
48
53
  networkConfigured = true;
49
54
  }else{
50
55
  ServiceBook sb = ServiceBook.getSB();
@@ -41,6 +41,7 @@ import com.rho.*;
41
41
  import com.rho.rubyext.GeoLocation;
42
42
  import com.rho.net.NetResponse;
43
43
  import com.rho.net.RhoConnection;
44
+ import com.rho.net.URI;
44
45
  import com.rho.sync.ClientRegister;
45
46
  import com.rho.sync.SyncThread;
46
47
  import com.rho.sync.ISyncStatusListener;
@@ -995,14 +996,18 @@ final public class RhodesApplication extends UiApplication implements SystemList
995
996
  private Hashtable cookies = new Hashtable();
996
997
 
997
998
  public String getCookie(String url) {
998
- Object c = cookies.get(url);
999
+ URI uri = new URI(url);
1000
+ String baseUrl = uri.getScheme() + "://" + uri.getHost() + "/" + uri.getPath();
1001
+ Object c = cookies.get(baseUrl);
999
1002
  if (c instanceof String)
1000
1003
  return (String)c;
1001
1004
  return null;
1002
1005
  }
1003
1006
 
1004
1007
  public void setCookie(String url, String cookie) {
1005
- cookies.put(url, cookie);
1008
+ URI uri = new URI(url);
1009
+ String baseUrl = uri.getScheme() + "://" + uri.getHost() + "/" + uri.getPath();
1010
+ cookies.put(baseUrl, cookie);
1006
1011
  }
1007
1012
 
1008
1013
  private void createBrowserControl()
@@ -260,7 +260,9 @@
260
260
  # include <asm/page.h>
261
261
 
262
262
  typedef long int fd_mask;
263
- typedef unsigned long long rlim_t;
263
+ #ifndef HAVE_RLIM_T
264
+ typedef unsigned long rlim_t;
265
+ #endif
264
266
 
265
267
  # ifndef howmany
266
268
  # define howmany(x, y) (((x) + ((y) - 1)) / (y))
@@ -657,7 +657,17 @@ public class NetRequest
657
657
  {
658
658
  String strRes = "";
659
659
  byte[] byteBuffer = new byte[1024*4];
660
- boolean bUTF8 = strContType != null && strContType.indexOf("UTF-8")>=0;
660
+ boolean bUTF8 = false;
661
+
662
+ if ( strContType != null )
663
+ {
664
+ int nCharsetPos = strContType.lastIndexOf('=');
665
+ if ( nCharsetPos > 0 )
666
+ {
667
+ String strEnc = strContType.substring(nCharsetPos+1);
668
+ bUTF8 = strEnc.equalsIgnoreCase("UTF-8");
669
+ }
670
+ }
661
671
 
662
672
  int nRead = 0;
663
673
  do{
@@ -893,6 +893,19 @@ public class RubyModule extends RubyObject {
893
893
  return RubyAPI.isConstantDefined(this, s.toString());
894
894
  }
895
895
 
896
+ public RubyValue getConstants()
897
+ {
898
+ RubyArray arRes = new RubyArray();
899
+ j2me.util.Set keys = constants_.keySet();
900
+ Iterator iter = keys.iterator();
901
+ while( iter.hasNext() )
902
+ {
903
+ arRes.add( ObjectFactory.createSymbol((String)iter.next()));
904
+ }
905
+
906
+ return arRes;
907
+ }
908
+
896
909
  //@RubyLevelMethod(name="method_defined?")
897
910
  public RubyValue isMethodDefined(RubyValue arg) {
898
911
  RubySymbol s = RubyTypesUtil.convertToSymbol(arg);
@@ -13,6 +13,10 @@ klass.defineMethod( "const_defined?", new RubyOneArgMethod(){
13
13
  protected RubyValue run(RubyValue receiver, RubyValue arg, RubyBlock block ){
14
14
  return ((RubyModule)receiver).isConstDefined(arg);}
15
15
  });
16
+ klass.defineMethod( "constants", new RubyNoArgMethod(){
17
+ protected RubyValue run(RubyValue receiver, RubyBlock block ){
18
+ return ((RubyModule)receiver).getConstants();}
19
+ });
16
20
  klass.defineMethod( "method_defined?", new RubyOneArgMethod(){
17
21
  protected RubyValue run(RubyValue receiver, RubyValue arg, RubyBlock block ){
18
22
  return ((RubyModule)receiver).isMethodDefined(arg);}
data/rhodes.gemspec CHANGED
@@ -3,7 +3,7 @@ require "lib/rhodes.rb"
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = %q{rhodes}
6
- s.version = '2.0.0.beta6'
6
+ s.version = '2.0.0.beta7'
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.authors = ["Rhomobile"]
metadata CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
6
6
  - 2
7
7
  - 0
8
8
  - 0
9
- - beta6
10
- version: 2.0.0.beta6
9
+ - beta7
10
+ version: 2.0.0.beta7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Rhomobile
@@ -159,7 +159,7 @@ files:
159
159
  - lib/extensions/fcntl/ext/Rakefile
160
160
  - lib/extensions/fcntl/ext.yml
161
161
  - lib/extensions/json/json/common.rb
162
- - lib/extensions/json/json/pure/parser.rb
162
+ - lib/extensions/json/json/pure/generator.rb
163
163
  - lib/extensions/json/json/pure.rb
164
164
  - lib/extensions/json/json/version.rb
165
165
  - lib/extensions/json/json.rb
@@ -315,7 +315,9 @@ files:
315
315
  - lib/framework/rhofsconnector.rb
316
316
  - lib/framework/rholang/lang_en.rb
317
317
  - lib/framework/rholang/localization_simplified.rb
318
+ - lib/framework/rholang/rhoerror_de.rb
318
319
  - lib/framework/rholang/rhoerror_en.rb
320
+ - lib/framework/rholang/rhomsg_de.rb
319
321
  - lib/framework/rholang/rhomsg_en.rb
320
322
  - lib/framework/rhom/rhom.rb
321
323
  - lib/framework/rhom/rhom_db_adapter.rb
@@ -1,267 +0,0 @@
1
- require 'strscan'
2
-
3
- module JSON
4
- module Pure
5
- # This class implements the JSON parser that is used to parse a JSON string
6
- # into a Ruby data structure.
7
- class Parser < StringScanner
8
- STRING = /" ((?:[^\x0-\x1f"\\] |
9
- \\["\\\/bfnrt] |
10
- \\u[0-9a-fA-F]{4} |
11
- \\[\x20-\xff])*)
12
- "/nx
13
- INTEGER = /(-?0|-?[1-9]\d*)/
14
- FLOAT = /(-?
15
- (?:0|[1-9]\d*)
16
- (?:
17
- \.\d+(?i:e[+-]?\d+) |
18
- \.\d+ |
19
- (?i:e[+-]?\d+)
20
- )
21
- )/x
22
- NAN = /NaN/
23
- INFINITY = /Infinity/
24
- MINUS_INFINITY = /-Infinity/
25
- OBJECT_OPEN = /\{/
26
- OBJECT_CLOSE = /\}/
27
- ARRAY_OPEN = /\[/
28
- ARRAY_CLOSE = /\]/
29
- PAIR_DELIMITER = /:/
30
- COLLECTION_DELIMITER = /,/
31
- TRUE = /true/
32
- FALSE = /false/
33
- NULL = /null/
34
- IGNORE = %r(
35
- (?:
36
- //[^\n\r]*[\n\r]| # line comments
37
- /\* # c-style comments
38
- (?:
39
- [^*/]| # normal chars
40
- /[^*]| # slashes that do not start a nested comment
41
- \*[^/]| # asterisks that do not end this comment
42
- /(?=\*/) # single slash before this comment's end
43
- )*
44
- \*/ # the End of this comment
45
- |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
46
- )+
47
- )mx
48
-
49
- UNPARSED = Object.new
50
-
51
- #for debug
52
- #alias_method :old_scan, :scan
53
- #def scan(arg)
54
- # res = old_scan(arg)
55
- # puts "scan : arg - #{arg}; res - #{res};"
56
- # res
57
- #end
58
-
59
- # Creates a new JSON::Pure::Parser instance for the string _source_.
60
- #
61
- # It will be configured by the _opts_ hash. _opts_ can have the following
62
- # keys:
63
- # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
64
- # structures. Disable depth checking with :max_nesting => false|nil|0,
65
- # it defaults to 19.
66
- # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
67
- # defiance of RFC 4627 to be parsed by the Parser. This option defaults
68
- # to false.
69
- # * *create_additions*: If set to false, the Parser doesn't create
70
- # additions even if a matchin class and create_id was found. This option
71
- # defaults to true.
72
- def initialize(source, opts = {})
73
- super
74
- if !opts.key?(:max_nesting) # defaults to 19
75
- @max_nesting = 19
76
- elsif opts[:max_nesting]
77
- @max_nesting = opts[:max_nesting]
78
- else
79
- @max_nesting = 0
80
- end
81
- @allow_nan = !!opts[:allow_nan]
82
- ca = true
83
- ca = opts[:create_additions] if opts.key?(:create_additions)
84
- @create_id = ca ? JSON.create_id : nil
85
- end
86
-
87
- alias source string
88
-
89
- # Parses the current JSON string _source_ and returns the complete data
90
- # structure as a result.
91
- def parse
92
- reset
93
- obj = nil
94
- until eos?
95
- case
96
- when scan(OBJECT_OPEN)
97
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
98
- @current_nesting = 1
99
- obj = parse_object
100
- when scan(ARRAY_OPEN)
101
- obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
102
- @current_nesting = 1
103
- obj = parse_array
104
- when skip(IGNORE)
105
- ;
106
- else
107
- raise ParserError, "source '#{peek(20)}' not in JSON!"
108
- end
109
- end
110
- obj or raise ParserError, "source did not contain any JSON!"
111
- obj
112
- end
113
-
114
- private
115
-
116
- # Unescape characters in strings.
117
- UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
118
- UNESCAPE_MAP.update({
119
- ?" => '"',
120
- ?\\ => '\\',
121
- ?/ => '/',
122
- ?b => "\b",
123
- ?f => "\f",
124
- ?n => "\n",
125
- ?r => "\r",
126
- ?t => "\t",
127
- ?u => nil,
128
- })
129
-
130
- def parse_string
131
- if scan(STRING)
132
- return '' if self[1].empty?
133
- self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
134
- if u = UNESCAPE_MAP[$&[1]]
135
- u
136
- else # \uXXXX
137
- bytes = ''
138
- i = 0
139
- while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
140
- bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
141
- i += 1
142
- end
143
- JSON::UTF16toUTF8.iconv(bytes)
144
- end
145
- end
146
- else
147
- UNPARSED
148
- end
149
- rescue Iconv::Failure => e
150
- raise GeneratorError, "Caught #{e.class}: #{e}"
151
- end
152
-
153
- def parse_value
154
- case
155
- when scan(FLOAT)
156
- Float(self[1])
157
- when scan(INTEGER)
158
- Integer(self[1])
159
- when scan(TRUE)
160
- true
161
- when scan(FALSE)
162
- false
163
- when scan(NULL)
164
- nil
165
- when (string = parse_string) != UNPARSED
166
- string
167
- when scan(ARRAY_OPEN)
168
- @current_nesting += 1
169
- ary = parse_array
170
- @current_nesting -= 1
171
- ary
172
- when scan(OBJECT_OPEN)
173
- @current_nesting += 1
174
- obj = parse_object
175
- @current_nesting -= 1
176
- obj
177
- when @allow_nan && scan(NAN)
178
- NaN
179
- when @allow_nan && scan(INFINITY)
180
- Infinity
181
- when @allow_nan && scan(MINUS_INFINITY)
182
- MinusInfinity
183
- else
184
- UNPARSED
185
- end
186
- end
187
-
188
- def parse_array
189
- raise NestingError, "nesting of #@current_nesting is to deep" if
190
- @max_nesting.nonzero? && @current_nesting > @max_nesting
191
- result = []
192
- delim = false
193
- until eos?
194
- case
195
- when (value = parse_value) != UNPARSED
196
- delim = false
197
- result << value
198
- skip(IGNORE)
199
- if scan(COLLECTION_DELIMITER)
200
- delim = true
201
- elsif match?(ARRAY_CLOSE)
202
- ;
203
- else
204
- raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
205
- end
206
- when scan(ARRAY_CLOSE)
207
- if delim
208
- raise ParserError, "expected next element in array at '#{peek(20)}'!"
209
- end
210
- break
211
- when skip(IGNORE)
212
- ;
213
- else
214
- raise ParserError, "unexpected token in array at '#{peek(20)}'!"
215
- end
216
- end
217
- result
218
- end
219
-
220
- def parse_object
221
- raise NestingError, "nesting of #@current_nesting is to deep" if
222
- @max_nesting.nonzero? && @current_nesting > @max_nesting
223
- result = {}
224
- delim = false
225
- until eos?
226
- case
227
- when (string = parse_string) != UNPARSED
228
- skip(IGNORE)
229
- unless scan(PAIR_DELIMITER)
230
- raise ParserError, "expected ':' in object at '#{peek(20)}'!"
231
- end
232
- skip(IGNORE)
233
- unless (value = parse_value).equal? UNPARSED
234
- result[string] = value
235
- delim = false
236
- skip(IGNORE)
237
- if scan(COLLECTION_DELIMITER)
238
- delim = true
239
- elsif match?(OBJECT_CLOSE)
240
- ;
241
- else
242
- raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
243
- end
244
- else
245
- raise ParserError, "expected value in object at '#{peek(20)}'!"
246
- end
247
- when scan(OBJECT_CLOSE)
248
- if delim
249
- raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
250
- end
251
- if @create_id and klassname = result[@create_id]
252
- klass = JSON.deep_const_get klassname
253
- break unless klass and klass.json_creatable?
254
- result = klass.json_create(result)
255
- end
256
- break
257
- when skip(IGNORE)
258
- ;
259
- else
260
- raise ParserError, "unexpected token in object at '#{peek(20)}'!"
261
- end
262
- end
263
- result
264
- end
265
- end
266
- end
267
- end