scout 5.6.7 → 5.6.8.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG.markdown +4 -0
  2. data/lib/scout/version.rb +1 -1
  3. data/vendor/json_pure/.gitignore +12 -0
  4. data/vendor/json_pure/.travis.yml +20 -0
  5. data/vendor/json_pure/CHANGES +120 -0
  6. data/vendor/json_pure/COPYING-json-jruby +57 -0
  7. data/vendor/json_pure/Gemfile +11 -0
  8. data/vendor/json_pure/README-json-jruby.markdown +33 -0
  9. data/vendor/json_pure/{README → README.rdoc} +7 -7
  10. data/vendor/json_pure/Rakefile +305 -185
  11. data/vendor/json_pure/VERSION +1 -1
  12. data/vendor/json_pure/diagrams/.keep +0 -0
  13. data/vendor/json_pure/ext/json/ext/fbuffer/fbuffer.h +181 -0
  14. data/vendor/json_pure/ext/json/ext/generator/depend +1 -0
  15. data/vendor/json_pure/ext/json/ext/generator/extconf.rb +4 -6
  16. data/vendor/json_pure/ext/json/ext/generator/generator.c +463 -369
  17. data/vendor/json_pure/ext/json/ext/generator/generator.h +44 -66
  18. data/vendor/json_pure/ext/json/ext/parser/depend +1 -0
  19. data/vendor/json_pure/ext/json/ext/parser/extconf.rb +3 -5
  20. data/vendor/json_pure/ext/json/ext/parser/parser.c +580 -311
  21. data/vendor/json_pure/ext/json/ext/parser/parser.h +14 -8
  22. data/vendor/json_pure/ext/json/ext/parser/parser.rl +242 -107
  23. data/vendor/json_pure/install.rb +8 -11
  24. data/vendor/json_pure/java/src/json/ext/ByteListTranscoder.java +167 -0
  25. data/vendor/json_pure/java/src/json/ext/Generator.java +444 -0
  26. data/vendor/json_pure/java/src/json/ext/GeneratorMethods.java +232 -0
  27. data/vendor/json_pure/java/src/json/ext/GeneratorService.java +43 -0
  28. data/vendor/json_pure/java/src/json/ext/GeneratorState.java +543 -0
  29. data/vendor/json_pure/java/src/json/ext/OptionsReader.java +114 -0
  30. data/vendor/json_pure/java/src/json/ext/Parser.java +2644 -0
  31. data/vendor/json_pure/java/src/json/ext/Parser.rl +968 -0
  32. data/vendor/json_pure/java/src/json/ext/ParserService.java +35 -0
  33. data/vendor/json_pure/java/src/json/ext/RuntimeInfo.java +121 -0
  34. data/vendor/json_pure/java/src/json/ext/StringDecoder.java +167 -0
  35. data/vendor/json_pure/java/src/json/ext/StringEncoder.java +106 -0
  36. data/vendor/json_pure/java/src/json/ext/Utils.java +89 -0
  37. data/vendor/json_pure/json-java.gemspec +23 -0
  38. data/vendor/json_pure/json.gemspec +37 -0
  39. data/vendor/json_pure/json_pure.gemspec +39 -0
  40. data/vendor/json_pure/lib/json.rb +52 -0
  41. data/vendor/json_pure/lib/json/add/bigdecimal.rb +28 -0
  42. data/vendor/json_pure/lib/json/add/complex.rb +22 -0
  43. data/vendor/json_pure/lib/json/add/core.rb +9 -146
  44. data/vendor/json_pure/lib/json/add/date.rb +34 -0
  45. data/vendor/json_pure/lib/json/add/date_time.rb +50 -0
  46. data/vendor/json_pure/lib/json/add/exception.rb +31 -0
  47. data/vendor/json_pure/lib/json/add/ostruct.rb +31 -0
  48. data/vendor/json_pure/lib/json/add/range.rb +29 -0
  49. data/vendor/json_pure/lib/json/add/rational.rb +22 -0
  50. data/vendor/json_pure/lib/json/add/regexp.rb +30 -0
  51. data/vendor/json_pure/lib/json/add/struct.rb +30 -0
  52. data/vendor/json_pure/lib/json/add/symbol.rb +25 -0
  53. data/vendor/json_pure/lib/json/add/time.rb +38 -0
  54. data/vendor/json_pure/lib/json/common.rb +157 -67
  55. data/vendor/json_pure/lib/json/ext.rb +8 -2
  56. data/vendor/json_pure/lib/json/ext/.keep +0 -0
  57. data/vendor/json_pure/lib/json/generic_object.rb +70 -0
  58. data/vendor/json_pure/lib/json/pure.rb +8 -64
  59. data/vendor/json_pure/lib/json/pure/generator.rb +183 -113
  60. data/vendor/json_pure/lib/json/pure/parser.rb +118 -66
  61. data/vendor/json_pure/lib/json/version.rb +1 -1
  62. data/vendor/json_pure/tests/fixtures/fail18.json +1 -1
  63. data/vendor/json_pure/tests/setup_variant.rb +11 -0
  64. data/vendor/json_pure/tests/test_json.rb +233 -28
  65. data/vendor/json_pure/tests/test_json_addition.rb +68 -34
  66. data/vendor/json_pure/tests/test_json_encoding.rb +11 -14
  67. data/vendor/json_pure/tests/test_json_fixtures.rb +11 -10
  68. data/vendor/json_pure/tests/test_json_generate.rb +207 -7
  69. data/vendor/json_pure/tests/test_json_generic_object.rb +75 -0
  70. data/vendor/json_pure/tests/test_json_string_matching.rb +39 -0
  71. data/vendor/json_pure/tests/test_json_unicode.rb +3 -7
  72. data/vendor/json_pure/tools/fuzz.rb +1 -1
  73. data/vendor/json_pure/tools/server.rb +1 -0
  74. metadata +87 -94
  75. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +0 -52
  76. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +0 -1000
  77. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +0 -1001
  78. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +0 -900
  79. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +0 -901
  80. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +0 -1000
  81. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +0 -1001
  82. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +0 -261
  83. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +0 -1000
  84. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +0 -1001
  85. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +0 -1000
  86. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +0 -1001
  87. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +0 -1000
  88. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +0 -1001
  89. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +0 -262
  90. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +0 -1000
  91. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +0 -1001
  92. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +0 -82
  93. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +0 -34
  94. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +0 -900
  95. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +0 -901
  96. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +0 -81
  97. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +0 -1000
  98. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +0 -1001
  99. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +0 -82
  100. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +0 -1000
  101. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +0 -1001
  102. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +0 -82
  103. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +0 -1000
  104. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +0 -1001
  105. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +0 -82
  106. data/vendor/json_pure/benchmarks/generator2_benchmark.rb +0 -222
  107. data/vendor/json_pure/benchmarks/generator_benchmark.rb +0 -224
  108. data/vendor/json_pure/benchmarks/ohai.json +0 -1216
  109. data/vendor/json_pure/benchmarks/ohai.ruby +0 -1
  110. data/vendor/json_pure/benchmarks/parser2_benchmark.rb +0 -251
  111. data/vendor/json_pure/benchmarks/parser_benchmark.rb +0 -259
  112. data/vendor/json_pure/bin/edit_json.rb +0 -9
  113. data/vendor/json_pure/bin/prettify_json.rb +0 -75
  114. data/vendor/json_pure/lib/json/Array.xpm +0 -21
  115. data/vendor/json_pure/lib/json/FalseClass.xpm +0 -21
  116. data/vendor/json_pure/lib/json/Hash.xpm +0 -21
  117. data/vendor/json_pure/lib/json/Key.xpm +0 -73
  118. data/vendor/json_pure/lib/json/NilClass.xpm +0 -21
  119. data/vendor/json_pure/lib/json/Numeric.xpm +0 -28
  120. data/vendor/json_pure/lib/json/String.xpm +0 -96
  121. data/vendor/json_pure/lib/json/TrueClass.xpm +0 -21
  122. data/vendor/json_pure/lib/json/add/rails.rb +0 -58
  123. data/vendor/json_pure/lib/json/editor.rb +0 -1371
  124. data/vendor/json_pure/lib/json/json.xpm +0 -1499
  125. data/vendor/json_pure/tests/test_json_rails.rb +0 -144
@@ -3,24 +3,23 @@
3
3
 
4
4
  #include "ruby.h"
5
5
 
6
- #if HAVE_RE_H
6
+ #ifndef HAVE_RUBY_RE_H
7
7
  #include "re.h"
8
8
  #endif
9
9
 
10
- #ifdef HAVE_RUBY_ENCODING_H
11
- #include "ruby/encoding.h"
12
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
10
+ #ifdef HAVE_RUBY_ST_H
11
+ #include "ruby/st.h"
13
12
  #else
14
- #define FORCE_UTF8(obj)
13
+ #include "st.h"
15
14
  #endif
16
15
 
17
16
  #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
18
17
 
19
18
  /* unicode */
20
19
 
21
- typedef unsigned long UTF32; /* at least 32 bits */
22
- typedef unsigned short UTF16; /* at least 16 bits */
23
- typedef unsigned char UTF8; /* typically 8 bits */
20
+ typedef unsigned long UTF32; /* at least 32 bits */
21
+ typedef unsigned short UTF16; /* at least 16 bits */
22
+ typedef unsigned char UTF8; /* typically 8 bits */
24
23
 
25
24
  #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
26
25
  #define UNI_SUR_HIGH_START (UTF32)0xD800
@@ -39,11 +38,18 @@ typedef struct JSON_ParserStruct {
39
38
  int allow_nan;
40
39
  int parsing_name;
41
40
  int symbolize_names;
41
+ int quirks_mode;
42
42
  VALUE object_class;
43
43
  VALUE array_class;
44
+ int create_additions;
45
+ VALUE match_string;
46
+ FBuffer *fbuffer;
44
47
  } JSON_Parser;
45
48
 
46
49
  #define GET_PARSER \
50
+ GET_PARSER_INIT; \
51
+ if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
52
+ #define GET_PARSER_INIT \
47
53
  JSON_Parser *json; \
48
54
  Data_Get_Struct(self, JSON_Parser, json)
49
55
 
@@ -1,8 +1,9 @@
1
+ #include "../fbuffer/fbuffer.h"
1
2
  #include "parser.h"
2
3
 
3
4
  /* unicode */
4
5
 
5
- static const char digit_values[256] = {
6
+ static const char digit_values[256] = {
6
7
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
7
8
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8
9
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -38,7 +39,7 @@ static UTF32 unescape_unicode(const unsigned char *p)
38
39
  return result;
39
40
  }
40
41
 
41
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
42
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
42
43
  {
43
44
  int len = 1;
44
45
  if (ch <= 0x7F) {
@@ -67,7 +68,7 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
67
68
  #ifdef HAVE_RUBY_ENCODING_H
68
69
  static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
69
70
  CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
70
- static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
71
+ static ID i_encoding, i_encode;
71
72
  #else
72
73
  static ID i_iconv;
73
74
  #endif
@@ -76,8 +77,9 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
76
77
  static VALUE CNaN, CInfinity, CMinusInfinity;
77
78
 
78
79
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
79
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
80
- i_array_class, i_key_p, i_deep_const_get;
80
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
81
+ i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
82
+ i_match_string, i_aset, i_aref, i_leftshift;
81
83
 
82
84
  %%{
83
85
  machine JSON_common;
@@ -97,7 +99,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
97
99
  VNaN = 'NaN';
98
100
  VInfinity = 'Infinity';
99
101
  VMinusInfinity = '-Infinity';
100
- begin_value = [nft"\-[{NI] | digit;
102
+ begin_value = [nft\"\-\[\{NI] | digit;
101
103
  begin_object = '{';
102
104
  end_object = '}';
103
105
  begin_array = '[';
@@ -115,11 +117,15 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
115
117
 
116
118
  action parse_value {
117
119
  VALUE v = Qnil;
118
- char *np = JSON_parse_value(json, fpc, pe, &v);
120
+ char *np = JSON_parse_value(json, fpc, pe, &v);
119
121
  if (np == NULL) {
120
122
  fhold; fbreak;
121
123
  } else {
122
- rb_hash_aset(*result, last_name, v);
124
+ if (NIL_P(json->object_class)) {
125
+ rb_hash_aset(*result, last_name, v);
126
+ } else {
127
+ rb_funcall(*result, i_aset, 2, last_name, v);
128
+ }
123
129
  fexec np;
124
130
  }
125
131
  }
@@ -134,13 +140,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
134
140
 
135
141
  action exit { fhold; fbreak; }
136
142
 
137
- a_pair = ignore* begin_name >parse_name
138
- ignore* name_separator ignore*
139
- begin_value >parse_value;
143
+ pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
144
+ next_pair = ignore* value_separator pair;
140
145
 
141
- main := begin_object
142
- (a_pair (ignore* value_separator a_pair)*)?
143
- ignore* end_object @exit;
146
+ main := (
147
+ begin_object
148
+ (pair (next_pair)*)? ignore*
149
+ end_object
150
+ ) @exit;
144
151
  }%%
145
152
 
146
153
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -159,11 +166,16 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
159
166
  %% write exec;
160
167
 
161
168
  if (cs >= JSON_object_first_final) {
162
- if (RTEST(json->create_id)) {
163
- VALUE klassname = rb_hash_aref(*result, json->create_id);
169
+ if (json->create_additions) {
170
+ VALUE klassname;
171
+ if (NIL_P(json->object_class)) {
172
+ klassname = rb_hash_aref(*result, json->create_id);
173
+ } else {
174
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
175
+ }
164
176
  if (!NIL_P(klassname)) {
165
177
  VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
166
- if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
178
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
167
179
  *result = rb_funcall(klass, i_json_create, 1, *result);
168
180
  }
169
181
  }
@@ -174,6 +186,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
174
186
  }
175
187
  }
176
188
 
189
+
177
190
  %%{
178
191
  machine JSON_value;
179
192
  include JSON_common;
@@ -210,7 +223,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
210
223
 
211
224
  action parse_number {
212
225
  char *np;
213
- if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
226
+ if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
214
227
  if (json->allow_nan) {
215
228
  *result = CMinusInfinity;
216
229
  fexec p + 10;
@@ -226,7 +239,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
226
239
  fhold; fbreak;
227
240
  }
228
241
 
229
- action parse_array {
242
+ action parse_array {
230
243
  char *np;
231
244
  json->current_nesting++;
232
245
  np = JSON_parse_array(json, fpc, pe, result);
@@ -234,7 +247,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
234
247
  if (np == NULL) { fhold; fbreak; } else fexec np;
235
248
  }
236
249
 
237
- action parse_object {
250
+ action parse_object {
238
251
  char *np;
239
252
  json->current_nesting++;
240
253
  np = JSON_parse_object(json, fpc, pe, result);
@@ -278,7 +291,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
278
291
 
279
292
  action exit { fhold; fbreak; }
280
293
 
281
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
294
+ main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
282
295
  }%%
283
296
 
284
297
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -291,7 +304,10 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
291
304
 
292
305
  if (cs >= JSON_integer_first_final) {
293
306
  long len = p - json->memo;
294
- *result = rb_Integer(rb_str_new(json->memo, len));
307
+ fbuffer_clear(json->fbuffer);
308
+ fbuffer_append(json->fbuffer, json->memo, len);
309
+ fbuffer_append_char(json->fbuffer, '\0');
310
+ *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
295
311
  return p + 1;
296
312
  } else {
297
313
  return NULL;
@@ -309,7 +325,7 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
309
325
  main := '-'? (
310
326
  (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
311
327
  | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
312
- ) (^[0-9Ee.\-] @exit );
328
+ ) (^[0-9Ee.\-]? @exit );
313
329
  }%%
314
330
 
315
331
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -322,7 +338,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
322
338
 
323
339
  if (cs >= JSON_float_first_final) {
324
340
  long len = p - json->memo;
325
- *result = rb_Float(rb_str_new(json->memo, len));
341
+ fbuffer_clear(json->fbuffer);
342
+ fbuffer_append(json->fbuffer, json->memo, len);
343
+ fbuffer_append_char(json->fbuffer, '\0');
344
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
326
345
  return p + 1;
327
346
  } else {
328
347
  return NULL;
@@ -338,11 +357,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
338
357
 
339
358
  action parse_value {
340
359
  VALUE v = Qnil;
341
- char *np = JSON_parse_value(json, fpc, pe, &v);
360
+ char *np = JSON_parse_value(json, fpc, pe, &v);
342
361
  if (np == NULL) {
343
362
  fhold; fbreak;
344
363
  } else {
345
- rb_ary_push(*result, v);
364
+ if (NIL_P(json->array_class)) {
365
+ rb_ary_push(*result, v);
366
+ } else {
367
+ rb_funcall(*result, i_leftshift, 1, v);
368
+ }
346
369
  fexec np;
347
370
  }
348
371
  }
@@ -382,6 +405,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
382
405
  {
383
406
  char *p = string, *pe = string, *unescape;
384
407
  int unescape_len;
408
+ char buf[4];
385
409
 
386
410
  while (pe < stringEnd) {
387
411
  if (*pe == '\\') {
@@ -411,10 +435,9 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
411
435
  unescape = (char *) "\f";
412
436
  break;
413
437
  case 'u':
414
- if (pe > stringEnd - 4) {
438
+ if (pe > stringEnd - 4) {
415
439
  return Qnil;
416
440
  } else {
417
- char buf[4];
418
441
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
419
442
  pe += 3;
420
443
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
@@ -457,28 +480,52 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
457
480
  action parse_string {
458
481
  *result = json_string_unescape(*result, json->memo + 1, p);
459
482
  if (NIL_P(*result)) {
460
- fhold;
461
- fbreak;
462
- } else {
463
- FORCE_UTF8(*result);
464
- fexec p + 1;
465
- }
466
- }
483
+ fhold;
484
+ fbreak;
485
+ } else {
486
+ FORCE_UTF8(*result);
487
+ fexec p + 1;
488
+ }
489
+ }
467
490
 
468
491
  action exit { fhold; fbreak; }
469
492
 
470
- main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^(["\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
493
+ main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
471
494
  }%%
472
495
 
496
+ static int
497
+ match_i(VALUE regexp, VALUE klass, VALUE memo)
498
+ {
499
+ if (regexp == Qundef) return ST_STOP;
500
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
501
+ RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
502
+ rb_ary_push(memo, klass);
503
+ return ST_STOP;
504
+ }
505
+ return ST_CONTINUE;
506
+ }
507
+
473
508
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
474
509
  {
475
510
  int cs = EVIL;
511
+ VALUE match_string;
476
512
 
477
513
  *result = rb_str_buf_new(0);
478
514
  %% write init;
479
515
  json->memo = p;
480
516
  %% write exec;
481
517
 
518
+ if (json->create_additions && RTEST(match_string = json->match_string)) {
519
+ VALUE klass;
520
+ VALUE memo = rb_ary_new2(2);
521
+ rb_ary_push(memo, *result);
522
+ rb_hash_foreach(match_string, match_i, memo);
523
+ klass = rb_ary_entry(memo, 1);
524
+ if (RTEST(klass)) {
525
+ *result = rb_funcall(klass, i_json_create, 1, *result);
526
+ }
527
+ }
528
+
482
529
  if (json->symbolize_names && json->parsing_name) {
483
530
  *result = rb_str_intern(*result);
484
531
  }
@@ -489,35 +536,7 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
489
536
  }
490
537
  }
491
538
 
492
-
493
- %%{
494
- machine JSON;
495
-
496
- write data;
497
-
498
- include JSON_common;
499
-
500
- action parse_object {
501
- char *np;
502
- json->current_nesting = 1;
503
- np = JSON_parse_object(json, fpc, pe, &result);
504
- if (np == NULL) { fhold; fbreak; } else fexec np;
505
- }
506
-
507
- action parse_array {
508
- char *np;
509
- json->current_nesting = 1;
510
- np = JSON_parse_array(json, fpc, pe, &result);
511
- if (np == NULL) { fhold; fbreak; } else fexec np;
512
- }
513
-
514
- main := ignore* (
515
- begin_object >parse_object |
516
- begin_array >parse_array
517
- ) ignore*;
518
- }%%
519
-
520
- /*
539
+ /*
521
540
  * Document-class: JSON::Ext::Parser
522
541
  *
523
542
  * This is the JSON parser implemented as a C extension. It can be configured
@@ -541,22 +560,15 @@ static VALUE convert_encoding(VALUE source)
541
560
  VALUE encoding = rb_funcall(source, i_encoding, 0);
542
561
  if (encoding == CEncoding_ASCII_8BIT) {
543
562
  if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
544
- source = rb_str_dup(source);
545
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
546
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
563
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
547
564
  } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
548
- source = rb_str_dup(source);
549
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
550
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
565
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
551
566
  } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
552
- source = rb_str_dup(source);
553
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
554
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
567
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
555
568
  } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
556
- source = rb_str_dup(source);
557
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
558
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
569
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
559
570
  } else {
571
+ source = rb_str_dup(source);
560
572
  FORCE_UTF8(source);
561
573
  }
562
574
  } else {
@@ -590,7 +602,7 @@ static VALUE convert_encoding(VALUE source)
590
602
  * _opts_ can have the following keys:
591
603
  * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
592
604
  * structures. Disable depth checking with :max_nesting => false|nil|0, it
593
- * defaults to 19.
605
+ * defaults to 100.
594
606
  * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
595
607
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
596
608
  * false.
@@ -605,14 +617,13 @@ static VALUE convert_encoding(VALUE source)
605
617
  */
606
618
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
607
619
  {
608
- char *ptr;
609
- long len;
610
620
  VALUE source, opts;
611
- GET_PARSER;
621
+ GET_PARSER_INIT;
622
+
623
+ if (json->Vsource) {
624
+ rb_raise(rb_eTypeError, "already initialized instance");
625
+ }
612
626
  rb_scan_args(argc, argv, "11", &source, &opts);
613
- source = convert_encoding(StringValue(source));
614
- ptr = RSTRING_PTR(source);
615
- len = RSTRING_LEN(source);
616
627
  if (!NIL_P(opts)) {
617
628
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
618
629
  if (NIL_P(opts)) {
@@ -628,30 +639,36 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
628
639
  json->max_nesting = 0;
629
640
  }
630
641
  } else {
631
- json->max_nesting = 19;
642
+ json->max_nesting = 100;
632
643
  }
633
644
  tmp = ID2SYM(i_allow_nan);
634
645
  if (option_given_p(opts, tmp)) {
635
- VALUE allow_nan = rb_hash_aref(opts, tmp);
636
- json->allow_nan = RTEST(allow_nan) ? 1 : 0;
646
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
637
647
  } else {
638
648
  json->allow_nan = 0;
639
649
  }
640
650
  tmp = ID2SYM(i_symbolize_names);
641
651
  if (option_given_p(opts, tmp)) {
642
- VALUE symbolize_names = rb_hash_aref(opts, tmp);
643
- json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
652
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
644
653
  } else {
645
654
  json->symbolize_names = 0;
646
655
  }
656
+ tmp = ID2SYM(i_quirks_mode);
657
+ if (option_given_p(opts, tmp)) {
658
+ VALUE quirks_mode = rb_hash_aref(opts, tmp);
659
+ json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
660
+ } else {
661
+ json->quirks_mode = 0;
662
+ }
647
663
  tmp = ID2SYM(i_create_additions);
648
664
  if (option_given_p(opts, tmp)) {
649
- VALUE create_additions = rb_hash_aref(opts, tmp);
650
- if (RTEST(create_additions)) {
651
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
652
- } else {
653
- json->create_id = Qnil;
654
- }
665
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
666
+ } else {
667
+ json->create_additions = 0;
668
+ }
669
+ tmp = ID2SYM(i_create_id);
670
+ if (option_given_p(opts, tmp)) {
671
+ json->create_id = rb_hash_aref(opts, tmp);
655
672
  } else {
656
673
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
657
674
  }
@@ -667,28 +684,62 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
667
684
  } else {
668
685
  json->array_class = Qnil;
669
686
  }
687
+ tmp = ID2SYM(i_match_string);
688
+ if (option_given_p(opts, tmp)) {
689
+ VALUE match_string = rb_hash_aref(opts, tmp);
690
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
691
+ } else {
692
+ json->match_string = Qnil;
693
+ }
670
694
  }
671
695
  } else {
672
- json->max_nesting = 19;
696
+ json->max_nesting = 100;
673
697
  json->allow_nan = 0;
698
+ json->create_additions = 1;
674
699
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
675
700
  json->object_class = Qnil;
676
701
  json->array_class = Qnil;
677
702
  }
703
+ source = rb_convert_type(source, T_STRING, "String", "to_str");
704
+ if (!json->quirks_mode) {
705
+ source = convert_encoding(StringValue(source));
706
+ }
678
707
  json->current_nesting = 0;
679
- json->len = len;
680
- json->source = ptr;
708
+ StringValue(source);
709
+ json->len = RSTRING_LEN(source);
710
+ json->source = RSTRING_PTR(source);;
681
711
  json->Vsource = source;
682
712
  return self;
683
713
  }
684
714
 
685
- /*
686
- * call-seq: parse()
687
- *
688
- * Parses the current JSON text _source_ and returns the complete data
689
- * structure as a result.
690
- */
691
- static VALUE cParser_parse(VALUE self)
715
+ %%{
716
+ machine JSON;
717
+
718
+ write data;
719
+
720
+ include JSON_common;
721
+
722
+ action parse_object {
723
+ char *np;
724
+ json->current_nesting = 1;
725
+ np = JSON_parse_object(json, fpc, pe, &result);
726
+ if (np == NULL) { fhold; fbreak; } else fexec np;
727
+ }
728
+
729
+ action parse_array {
730
+ char *np;
731
+ json->current_nesting = 1;
732
+ np = JSON_parse_array(json, fpc, pe, &result);
733
+ if (np == NULL) { fhold; fbreak; } else fexec np;
734
+ }
735
+
736
+ main := ignore* (
737
+ begin_object >parse_object |
738
+ begin_array >parse_array
739
+ ) ignore*;
740
+ }%%
741
+
742
+ static VALUE cParser_parse_strict(VALUE self)
692
743
  {
693
744
  char *p, *pe;
694
745
  int cs = EVIL;
@@ -708,10 +759,67 @@ static VALUE cParser_parse(VALUE self)
708
759
  }
709
760
  }
710
761
 
762
+
763
+ %%{
764
+ machine JSON_quirks_mode;
765
+
766
+ write data;
767
+
768
+ include JSON_common;
769
+
770
+ action parse_value {
771
+ char *np = JSON_parse_value(json, fpc, pe, &result);
772
+ if (np == NULL) { fhold; fbreak; } else fexec np;
773
+ }
774
+
775
+ main := ignore* (
776
+ begin_value >parse_value
777
+ ) ignore*;
778
+ }%%
779
+
780
+ static VALUE cParser_parse_quirks_mode(VALUE self)
781
+ {
782
+ char *p, *pe;
783
+ int cs = EVIL;
784
+ VALUE result = Qnil;
785
+ GET_PARSER;
786
+
787
+ %% write init;
788
+ p = json->source;
789
+ pe = p + json->len;
790
+ %% write exec;
791
+
792
+ if (cs >= JSON_quirks_mode_first_final && p == pe) {
793
+ return result;
794
+ } else {
795
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
796
+ return Qnil;
797
+ }
798
+ }
799
+
800
+ /*
801
+ * call-seq: parse()
802
+ *
803
+ * Parses the current JSON text _source_ and returns the complete data
804
+ * structure as a result.
805
+ */
806
+ static VALUE cParser_parse(VALUE self)
807
+ {
808
+ GET_PARSER;
809
+
810
+ if (json->quirks_mode) {
811
+ return cParser_parse_quirks_mode(self);
812
+ } else {
813
+ return cParser_parse_strict(self);
814
+ }
815
+ }
816
+
817
+
711
818
  static JSON_Parser *JSON_allocate()
712
819
  {
713
820
  JSON_Parser *json = ALLOC(JSON_Parser);
714
821
  MEMZERO(json, JSON_Parser, 1);
822
+ json->fbuffer = fbuffer_alloc(0);
715
823
  return json;
716
824
  }
717
825
 
@@ -721,10 +829,12 @@ static void JSON_mark(JSON_Parser *json)
721
829
  rb_gc_mark_maybe(json->create_id);
722
830
  rb_gc_mark_maybe(json->object_class);
723
831
  rb_gc_mark_maybe(json->array_class);
832
+ rb_gc_mark_maybe(json->match_string);
724
833
  }
725
834
 
726
835
  static void JSON_free(JSON_Parser *json)
727
836
  {
837
+ fbuffer_free(json->fbuffer);
728
838
  ruby_xfree(json);
729
839
  }
730
840
 
@@ -746,6 +856,18 @@ static VALUE cParser_source(VALUE self)
746
856
  return rb_str_dup(json->Vsource);
747
857
  }
748
858
 
859
+ /*
860
+ * call-seq: quirks_mode?()
861
+ *
862
+ * Returns a true, if this parser is in quirks_mode, false otherwise.
863
+ */
864
+ static VALUE cParser_quirks_mode_p(VALUE self)
865
+ {
866
+ GET_PARSER;
867
+ return json->quirks_mode ? Qtrue : Qfalse;
868
+ }
869
+
870
+
749
871
  void Init_parser()
750
872
  {
751
873
  rb_require("json/common");
@@ -758,6 +880,7 @@ void Init_parser()
758
880
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
759
881
  rb_define_method(cParser, "parse", cParser_parse, 0);
760
882
  rb_define_method(cParser, "source", cParser_source, 0);
883
+ rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
761
884
 
762
885
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
763
886
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -771,10 +894,16 @@ void Init_parser()
771
894
  i_max_nesting = rb_intern("max_nesting");
772
895
  i_allow_nan = rb_intern("allow_nan");
773
896
  i_symbolize_names = rb_intern("symbolize_names");
897
+ i_quirks_mode = rb_intern("quirks_mode");
774
898
  i_object_class = rb_intern("object_class");
775
899
  i_array_class = rb_intern("array_class");
900
+ i_match = rb_intern("match");
901
+ i_match_string = rb_intern("match_string");
776
902
  i_key_p = rb_intern("key?");
777
903
  i_deep_const_get = rb_intern("deep_const_get");
904
+ i_aset = rb_intern("[]=");
905
+ i_aref = rb_intern("[]");
906
+ i_leftshift = rb_intern("<<");
778
907
  #ifdef HAVE_RUBY_ENCODING_H
779
908
  CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
780
909
  CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
@@ -784,9 +913,15 @@ void Init_parser()
784
913
  CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
785
914
  i_encoding = rb_intern("encoding");
786
915
  i_encode = rb_intern("encode");
787
- i_encode_bang = rb_intern("encode!");
788
- i_force_encoding = rb_intern("force_encoding");
789
916
  #else
790
917
  i_iconv = rb_intern("iconv");
791
918
  #endif
792
919
  }
920
+
921
+ /*
922
+ * Local variables:
923
+ * mode: c
924
+ * c-file-style: ruby
925
+ * indent-tabs-mode: nil
926
+ * End:
927
+ */