json-jruby 1.1.2-universal-java-1.5

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.
Files changed (50) hide show
  1. data/lib/json.rb +235 -0
  2. data/lib/json/add/core.rb +127 -0
  3. data/lib/json/add/rails.rb +58 -0
  4. data/lib/json/common.rb +354 -0
  5. data/lib/json/ext.rb +13 -0
  6. data/lib/json/ext/generator.jar +0 -0
  7. data/lib/json/ext/parser.jar +0 -0
  8. data/lib/json/pure.rb +75 -0
  9. data/lib/json/pure/generator.rb +394 -0
  10. data/lib/json/pure/parser.rb +259 -0
  11. data/lib/json/version.rb +9 -0
  12. data/tests/fixtures/fail1.json +1 -0
  13. data/tests/fixtures/fail10.json +1 -0
  14. data/tests/fixtures/fail11.json +1 -0
  15. data/tests/fixtures/fail12.json +1 -0
  16. data/tests/fixtures/fail13.json +1 -0
  17. data/tests/fixtures/fail14.json +1 -0
  18. data/tests/fixtures/fail18.json +1 -0
  19. data/tests/fixtures/fail19.json +1 -0
  20. data/tests/fixtures/fail2.json +1 -0
  21. data/tests/fixtures/fail20.json +1 -0
  22. data/tests/fixtures/fail21.json +1 -0
  23. data/tests/fixtures/fail22.json +1 -0
  24. data/tests/fixtures/fail23.json +1 -0
  25. data/tests/fixtures/fail24.json +1 -0
  26. data/tests/fixtures/fail25.json +1 -0
  27. data/tests/fixtures/fail27.json +2 -0
  28. data/tests/fixtures/fail28.json +2 -0
  29. data/tests/fixtures/fail3.json +1 -0
  30. data/tests/fixtures/fail4.json +1 -0
  31. data/tests/fixtures/fail5.json +1 -0
  32. data/tests/fixtures/fail6.json +1 -0
  33. data/tests/fixtures/fail7.json +1 -0
  34. data/tests/fixtures/fail8.json +1 -0
  35. data/tests/fixtures/fail9.json +1 -0
  36. data/tests/fixtures/pass1.json +56 -0
  37. data/tests/fixtures/pass15.json +1 -0
  38. data/tests/fixtures/pass16.json +1 -0
  39. data/tests/fixtures/pass17.json +1 -0
  40. data/tests/fixtures/pass2.json +1 -0
  41. data/tests/fixtures/pass26.json +1 -0
  42. data/tests/fixtures/pass3.json +6 -0
  43. data/tests/runner.rb +26 -0
  44. data/tests/test_json.rb +294 -0
  45. data/tests/test_json_addition.rb +144 -0
  46. data/tests/test_json_fixtures.rb +30 -0
  47. data/tests/test_json_generate.rb +100 -0
  48. data/tests/test_json_rails.rb +114 -0
  49. data/tests/test_json_unicode.rb +61 -0
  50. metadata +99 -0
@@ -0,0 +1,259 @@
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
+ # Creates a new JSON::Pure::Parser instance for the string _source_.
52
+ #
53
+ # It will be configured by the _opts_ hash. _opts_ can have the following
54
+ # keys:
55
+ # * *max_nesting*: The maximum depth of nesting allowed in the parsed data
56
+ # structures. Disable depth checking with :max_nesting => false|nil|0,
57
+ # it defaults to 19.
58
+ # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
59
+ # defiance of RFC 4627 to be parsed by the Parser. This option defaults
60
+ # to false.
61
+ # * *create_additions*: If set to false, the Parser doesn't create
62
+ # additions even if a matchin class and create_id was found. This option
63
+ # defaults to true.
64
+ def initialize(source, opts = {})
65
+ super
66
+ if !opts.key?(:max_nesting) # defaults to 19
67
+ @max_nesting = 19
68
+ elsif opts[:max_nesting]
69
+ @max_nesting = opts[:max_nesting]
70
+ else
71
+ @max_nesting = 0
72
+ end
73
+ @allow_nan = !!opts[:allow_nan]
74
+ ca = true
75
+ ca = opts[:create_additions] if opts.key?(:create_additions)
76
+ @create_id = ca ? JSON.create_id : nil
77
+ end
78
+
79
+ alias source string
80
+
81
+ # Parses the current JSON string _source_ and returns the complete data
82
+ # structure as a result.
83
+ def parse
84
+ reset
85
+ obj = nil
86
+ until eos?
87
+ case
88
+ when scan(OBJECT_OPEN)
89
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
90
+ @current_nesting = 1
91
+ obj = parse_object
92
+ when scan(ARRAY_OPEN)
93
+ obj and raise ParserError, "source '#{peek(20)}' not in JSON!"
94
+ @current_nesting = 1
95
+ obj = parse_array
96
+ when skip(IGNORE)
97
+ ;
98
+ else
99
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
100
+ end
101
+ end
102
+ obj or raise ParserError, "source did not contain any JSON!"
103
+ obj
104
+ end
105
+
106
+ private
107
+
108
+ # Unescape characters in strings.
109
+ UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
110
+ UNESCAPE_MAP.update({
111
+ ?" => '"',
112
+ ?\\ => '\\',
113
+ ?/ => '/',
114
+ ?b => "\b",
115
+ ?f => "\f",
116
+ ?n => "\n",
117
+ ?r => "\r",
118
+ ?t => "\t",
119
+ ?u => nil,
120
+ })
121
+
122
+ def parse_string
123
+ if scan(STRING)
124
+ return '' if self[1].empty?
125
+ self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
126
+ if u = UNESCAPE_MAP[c[1]]
127
+ u
128
+ else # \uXXXX
129
+ bytes = ''
130
+ i = 0
131
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
132
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
133
+ i += 1
134
+ end
135
+ JSON::UTF16toUTF8.iconv(bytes)
136
+ end
137
+ end
138
+ else
139
+ UNPARSED
140
+ end
141
+ rescue Iconv::Failure => e
142
+ raise GeneratorError, "Caught #{e.class}: #{e}"
143
+ end
144
+
145
+ def parse_value
146
+ case
147
+ when scan(FLOAT)
148
+ Float(self[1])
149
+ when scan(INTEGER)
150
+ Integer(self[1])
151
+ when scan(TRUE)
152
+ true
153
+ when scan(FALSE)
154
+ false
155
+ when scan(NULL)
156
+ nil
157
+ when (string = parse_string) != UNPARSED
158
+ string
159
+ when scan(ARRAY_OPEN)
160
+ @current_nesting += 1
161
+ ary = parse_array
162
+ @current_nesting -= 1
163
+ ary
164
+ when scan(OBJECT_OPEN)
165
+ @current_nesting += 1
166
+ obj = parse_object
167
+ @current_nesting -= 1
168
+ obj
169
+ when @allow_nan && scan(NAN)
170
+ NaN
171
+ when @allow_nan && scan(INFINITY)
172
+ Infinity
173
+ when @allow_nan && scan(MINUS_INFINITY)
174
+ MinusInfinity
175
+ else
176
+ UNPARSED
177
+ end
178
+ end
179
+
180
+ def parse_array
181
+ raise NestingError, "nesting of #@current_nesting is to deep" if
182
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
183
+ result = []
184
+ delim = false
185
+ until eos?
186
+ case
187
+ when (value = parse_value) != UNPARSED
188
+ delim = false
189
+ result << value
190
+ skip(IGNORE)
191
+ if scan(COLLECTION_DELIMITER)
192
+ delim = true
193
+ elsif match?(ARRAY_CLOSE)
194
+ ;
195
+ else
196
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
197
+ end
198
+ when scan(ARRAY_CLOSE)
199
+ if delim
200
+ raise ParserError, "expected next element in array at '#{peek(20)}'!"
201
+ end
202
+ break
203
+ when skip(IGNORE)
204
+ ;
205
+ else
206
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
207
+ end
208
+ end
209
+ result
210
+ end
211
+
212
+ def parse_object
213
+ raise NestingError, "nesting of #@current_nesting is to deep" if
214
+ @max_nesting.nonzero? && @current_nesting > @max_nesting
215
+ result = {}
216
+ delim = false
217
+ until eos?
218
+ case
219
+ when (string = parse_string) != UNPARSED
220
+ skip(IGNORE)
221
+ unless scan(PAIR_DELIMITER)
222
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
223
+ end
224
+ skip(IGNORE)
225
+ unless (value = parse_value).equal? UNPARSED
226
+ result[string] = value
227
+ delim = false
228
+ skip(IGNORE)
229
+ if scan(COLLECTION_DELIMITER)
230
+ delim = true
231
+ elsif match?(OBJECT_CLOSE)
232
+ ;
233
+ else
234
+ raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!"
235
+ end
236
+ else
237
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
238
+ end
239
+ when scan(OBJECT_CLOSE)
240
+ if delim
241
+ raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!"
242
+ end
243
+ if @create_id and klassname = result[@create_id]
244
+ klass = JSON.deep_const_get klassname
245
+ break unless klass and klass.json_creatable?
246
+ result = klass.json_create(result)
247
+ end
248
+ break
249
+ when skip(IGNORE)
250
+ ;
251
+ else
252
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
253
+ end
254
+ end
255
+ result
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,9 @@
1
+ module JSON
2
+ # JSON version
3
+ VERSION = '1.1.2'
4
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
7
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
8
+ VARIANT_BINARY = false
9
+ end
@@ -0,0 +1 @@
1
+ "A JSON payload should be an object or array, not a string."
@@ -0,0 +1 @@
1
+ {"Extra value after close": true} "misplaced quoted value"
@@ -0,0 +1 @@
1
+ {"Illegal expression": 1 + 2}
@@ -0,0 +1 @@
1
+ {"Illegal invocation": alert()}
@@ -0,0 +1 @@
1
+ {"Numbers cannot have leading zeroes": 013}
@@ -0,0 +1 @@
1
+ {"Numbers cannot be hex": 0x14}
@@ -0,0 +1 @@
1
+ [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
@@ -0,0 +1 @@
1
+ {"Missing colon" null}
@@ -0,0 +1 @@
1
+ ["Unclosed array"
@@ -0,0 +1 @@
1
+ {"Double colon":: null}
@@ -0,0 +1 @@
1
+ {"Comma instead of colon", null}
@@ -0,0 +1 @@
1
+ ["Colon instead of comma": false]
@@ -0,0 +1 @@
1
+ ["Bad value", truth]
@@ -0,0 +1 @@
1
+ ['single quote']
@@ -0,0 +1 @@
1
+ ["tab character in string "]
@@ -0,0 +1,2 @@
1
+ ["line
2
+ break"]
@@ -0,0 +1,2 @@
1
+ ["line\
2
+ break"]
@@ -0,0 +1 @@
1
+ {unquoted_key: "keys must be quoted"}
@@ -0,0 +1 @@
1
+ ["extra comma",]
@@ -0,0 +1 @@
1
+ ["double extra comma",,]
@@ -0,0 +1 @@
1
+ [ , "<-- missing value"]
@@ -0,0 +1 @@
1
+ ["Comma after the close"],
@@ -0,0 +1 @@
1
+ ["Extra close"]]
@@ -0,0 +1 @@
1
+ {"Extra comma": true,}
@@ -0,0 +1,56 @@
1
+ [
2
+ "JSON Test Pattern pass1",
3
+ {"object with 1 member":["array with 1 element"]},
4
+ {},
5
+ [],
6
+ -42,
7
+ true,
8
+ false,
9
+ null,
10
+ {
11
+ "integer": 1234567890,
12
+ "real": -9876.543210,
13
+ "e": 0.123456789e-12,
14
+ "E": 1.234567890E+34,
15
+ "": 23456789012E666,
16
+ "zero": 0,
17
+ "one": 1,
18
+ "space": " ",
19
+ "quote": "\"",
20
+ "backslash": "\\",
21
+ "controls": "\b\f\n\r\t",
22
+ "slash": "/ & \/",
23
+ "alpha": "abcdefghijklmnopqrstuvwyz",
24
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
25
+ "digit": "0123456789",
26
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
27
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
28
+ "true": true,
29
+ "false": false,
30
+ "null": null,
31
+ "array":[ ],
32
+ "object":{ },
33
+ "address": "50 St. James Street",
34
+ "url": "http://www.JSON.org/",
35
+ "comment": "// /* <!-- --",
36
+ "# -- --> */": " ",
37
+ " s p a c e d " :[1,2 , 3
38
+
39
+ ,
40
+
41
+ 4 , 5 , 6 ,7 ],
42
+ "compact": [1,2,3,4,5,6,7],
43
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
44
+ "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
45
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
46
+ : "A key can be any string"
47
+ },
48
+ 0.5 ,98.6
49
+ ,
50
+ 99.44
51
+ ,
52
+
53
+ 1066
54
+
55
+
56
+ ,"rosebud"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \x15"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \'"]
@@ -0,0 +1 @@
1
+ ["Illegal backslash escape: \017"]
@@ -0,0 +1 @@
1
+ [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
@@ -0,0 +1 @@
1
+ ["tab\ character\ in\ string\ "]
@@ -0,0 +1,6 @@
1
+ {
2
+ "JSON Test Pattern pass3": {
3
+ "The outermost value": "must be an object or array.",
4
+ "In this test": "It is an object."
5
+ }
6
+ }
data/tests/runner.rb ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit/ui/console/testrunner'
4
+ require 'test/unit/testsuite'
5
+ $:.unshift File.expand_path(File.dirname($0))
6
+ $:.unshift 'tests'
7
+ require 'test_json'
8
+ require 'test_json_generate'
9
+ require 'test_json_unicode'
10
+ require 'test_json_addition'
11
+ require 'test_json_rails'
12
+ require 'test_json_fixtures'
13
+
14
+ class TS_AllTests
15
+ def self.suite
16
+ suite = Test::Unit::TestSuite.new name
17
+ suite << TC_JSONGenerate.suite
18
+ suite << TC_JSON.suite
19
+ suite << TC_JSONUnicode.suite
20
+ suite << TC_JSONAddition.suite
21
+ suite << TC_JSONRails.suite
22
+ suite << TC_JSONFixtures.suite
23
+ end
24
+ end
25
+ Test::Unit::UI::Console::TestRunner.run(TS_AllTests)
26
+ # vim: set et sw=2 ts=2: