scout 5.1.2 → 5.1.3

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 (41) hide show
  1. data/CHANGELOG +5 -0
  2. data/lib/scout.rb +1 -1
  3. data/lib/scout/server.rb +4 -1
  4. data/vendor/json_pure/CHANGES +43 -0
  5. data/vendor/json_pure/{RUBY → COPYING} +1 -1
  6. data/vendor/json_pure/GPL +7 -7
  7. data/vendor/json_pure/README +319 -39
  8. data/vendor/json_pure/Rakefile +69 -47
  9. data/vendor/json_pure/VERSION +1 -1
  10. data/vendor/json_pure/benchmarks/generator2_benchmark.rb +222 -0
  11. data/vendor/json_pure/benchmarks/generator_benchmark.rb +64 -5
  12. data/vendor/json_pure/benchmarks/ohai.json +1216 -0
  13. data/vendor/json_pure/benchmarks/ohai.ruby +1 -0
  14. data/vendor/json_pure/benchmarks/parser2_benchmark.rb +251 -0
  15. data/vendor/json_pure/benchmarks/parser_benchmark.rb +67 -5
  16. data/vendor/json_pure/ext/json/ext/generator/extconf.rb +9 -4
  17. data/vendor/json_pure/ext/json/ext/generator/generator.c +831 -409
  18. data/vendor/json_pure/ext/json/ext/generator/generator.h +170 -0
  19. data/vendor/json_pure/ext/json/ext/parser/extconf.rb +8 -4
  20. data/vendor/json_pure/ext/json/ext/parser/parser.c +292 -186
  21. data/vendor/json_pure/ext/json/ext/parser/parser.h +71 -0
  22. data/vendor/json_pure/ext/json/ext/parser/parser.rl +218 -112
  23. data/vendor/json_pure/lib/json/add/core.rb +20 -7
  24. data/vendor/json_pure/lib/json/add/rails.rb +2 -2
  25. data/vendor/json_pure/lib/json/common.rb +85 -42
  26. data/vendor/json_pure/lib/json/pure.rb +3 -3
  27. data/vendor/json_pure/lib/json/pure/generator.rb +112 -90
  28. data/vendor/json_pure/lib/json/pure/parser.rb +42 -4
  29. data/vendor/json_pure/lib/json/version.rb +1 -1
  30. data/vendor/json_pure/tests/test_json.rb +46 -18
  31. data/vendor/json_pure/tests/test_json_addition.rb +4 -6
  32. data/vendor/json_pure/tests/test_json_encoding.rb +68 -0
  33. data/vendor/json_pure/tests/test_json_generate.rb +30 -14
  34. data/vendor/json_pure/tests/test_json_rails.rb +5 -7
  35. data/vendor/json_pure/tests/test_json_unicode.rb +20 -6
  36. metadata +26 -15
  37. data/vendor/json_pure/doc-templates/main.txt +0 -283
  38. data/vendor/json_pure/ext/json/ext/generator/unicode.c +0 -182
  39. data/vendor/json_pure/ext/json/ext/generator/unicode.h +0 -53
  40. data/vendor/json_pure/ext/json/ext/parser/unicode.c +0 -154
  41. data/vendor/json_pure/ext/json/ext/parser/unicode.h +0 -58
@@ -0,0 +1,170 @@
1
+ #ifndef _GENERATOR_H_
2
+ #define _GENERATOR_H_
3
+
4
+ #include <string.h>
5
+ #include <assert.h>
6
+ #include <math.h>
7
+
8
+ #include "ruby.h"
9
+
10
+ #if HAVE_RUBY_RE_H
11
+ #include "ruby/re.h"
12
+ #endif
13
+
14
+ #if HAVE_RE_H
15
+ #include "re.h"
16
+ #endif
17
+
18
+ #ifdef HAVE_RUBY_ENCODING_H
19
+ #include "ruby/encoding.h"
20
+ #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
21
+ #else
22
+ #define FORCE_UTF8(obj)
23
+ #endif
24
+
25
+ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
26
+
27
+ #ifndef RHASH_SIZE
28
+ #define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
29
+ #endif
30
+
31
+ #ifndef RFLOAT_VALUE
32
+ #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
33
+ #endif
34
+
35
+ #ifndef RARRAY_PTR
36
+ #define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr
37
+ #endif
38
+ #ifndef RARRAY_LEN
39
+ #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
40
+ #endif
41
+ #ifndef RSTRING_PTR
42
+ #define RSTRING_PTR(string) RSTRING(string)->ptr
43
+ #endif
44
+ #ifndef RSTRING_LEN
45
+ #define RSTRING_LEN(string) RSTRING(string)->len
46
+ #endif
47
+
48
+ #define RSTRING_PAIR(string) RSTRING_PTR(string), RSTRING_LEN(string)
49
+
50
+ /* fbuffer implementation */
51
+
52
+ typedef struct FBufferStruct {
53
+ unsigned int initial_length;
54
+ char *ptr;
55
+ unsigned int len;
56
+ unsigned int capa;
57
+ } FBuffer;
58
+
59
+ #define FBUFFER_INITIAL_LENGTH 4096
60
+
61
+ #define FBUFFER_PTR(fb) (fb->ptr)
62
+ #define FBUFFER_LEN(fb) (fb->len)
63
+ #define FBUFFER_CAPA(fb) (fb->capa)
64
+ #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
65
+
66
+ static char *fstrndup(const char *ptr, int len);
67
+ static FBuffer *fbuffer_alloc();
68
+ static FBuffer *fbuffer_alloc_with_length(unsigned initial_length);
69
+ static void fbuffer_free(FBuffer *fb);
70
+ static void fbuffer_free_only_buffer(FBuffer *fb);
71
+ static void fbuffer_clear(FBuffer *fb);
72
+ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len);
73
+ static void fbuffer_append_long(FBuffer *fb, long number);
74
+ static void fbuffer_append_char(FBuffer *fb, char newchr);
75
+ static FBuffer *fbuffer_dup(FBuffer *fb);
76
+
77
+ /* unicode defintions */
78
+
79
+ #define UNI_STRICT_CONVERSION 1
80
+
81
+ typedef unsigned long UTF32; /* at least 32 bits */
82
+ typedef unsigned short UTF16; /* at least 16 bits */
83
+ typedef unsigned char UTF8; /* typically 8 bits */
84
+
85
+ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
86
+ #define UNI_MAX_BMP (UTF32)0x0000FFFF
87
+ #define UNI_MAX_UTF16 (UTF32)0x0010FFFF
88
+ #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
89
+ #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
90
+
91
+ #define UNI_SUR_HIGH_START (UTF32)0xD800
92
+ #define UNI_SUR_HIGH_END (UTF32)0xDBFF
93
+ #define UNI_SUR_LOW_START (UTF32)0xDC00
94
+ #define UNI_SUR_LOW_END (UTF32)0xDFFF
95
+
96
+ static const int halfShift = 10; /* used for shifting by 10 bits */
97
+
98
+ static const UTF32 halfBase = 0x0010000UL;
99
+ static const UTF32 halfMask = 0x3FFUL;
100
+
101
+ static unsigned char isLegalUTF8(const UTF8 *source, int length);
102
+ static void unicode_escape(char *buf, UTF16 character);
103
+ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
104
+ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
105
+ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
106
+
107
+ /* ruby api and some helpers */
108
+
109
+ typedef struct JSON_Generator_StateStruct {
110
+ char *indent;
111
+ long indent_len;
112
+ char *space;
113
+ long space_len;
114
+ char *space_before;
115
+ long space_before_len;
116
+ char *object_nl;
117
+ long object_nl_len;
118
+ char *array_nl;
119
+ long array_nl_len;
120
+ FBuffer *array_delim;
121
+ FBuffer *object_delim;
122
+ FBuffer *object_delim2;
123
+ long max_nesting;
124
+ char allow_nan;
125
+ char ascii_only;
126
+ } JSON_Generator_State;
127
+
128
+ #define GET_STATE(self) \
129
+ JSON_Generator_State *state; \
130
+ Data_Get_Struct(self, JSON_Generator_State, state)
131
+
132
+ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
133
+ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self);
134
+ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self);
135
+ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self);
136
+ static VALUE mString_included_s(VALUE self, VALUE modul);
137
+ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self);
138
+ static VALUE mString_to_json_raw_object(VALUE self);
139
+ static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self);
140
+ static VALUE mString_Extend_json_create(VALUE self, VALUE o);
141
+ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self);
142
+ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self);
143
+ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self);
144
+ static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self);
145
+ static void State_free(JSON_Generator_State *state);
146
+ static JSON_Generator_State *State_allocate();
147
+ static VALUE cState_s_allocate(VALUE klass);
148
+ static VALUE cState_configure(VALUE self, VALUE opts);
149
+ static VALUE cState_to_h(VALUE self);
150
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
151
+ static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth);
152
+ static VALUE cState_generate(VALUE self, VALUE obj);
153
+ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self);
154
+ static VALUE cState_from_state_s(VALUE self, VALUE opts);
155
+ static VALUE cState_indent(VALUE self);
156
+ static VALUE cState_indent_set(VALUE self, VALUE indent);
157
+ static VALUE cState_space(VALUE self);
158
+ static VALUE cState_space_set(VALUE self, VALUE space);
159
+ static VALUE cState_space_before(VALUE self);
160
+ static VALUE cState_space_before_set(VALUE self, VALUE space_before);
161
+ static VALUE cState_object_nl(VALUE self);
162
+ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl);
163
+ static VALUE cState_array_nl(VALUE self);
164
+ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl);
165
+ static VALUE cState_max_nesting(VALUE self);
166
+ static VALUE cState_max_nesting_set(VALUE self, VALUE depth);
167
+ static VALUE cState_allow_nan_p(VALUE self);
168
+ static VALUE cState_ascii_only_p(VALUE self);
169
+
170
+ #endif
@@ -1,11 +1,15 @@
1
1
  require 'mkmf'
2
2
  require 'rbconfig'
3
3
 
4
+ unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3')
5
+ $CFLAGS << ' -O3'
6
+ end
4
7
  if CONFIG['CC'] =~ /gcc/
5
- $CFLAGS += ' -Wall'
6
- #$CFLAGS += ' -O0 -ggdb'
8
+ $CFLAGS << ' -Wall'
9
+ #unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O0 -ggdb')
10
+ # $CFLAGS << ' -O0 -ggdb'
11
+ #end
7
12
  end
8
13
 
9
- have_header("ruby/st.h") || have_header("st.h")
10
14
  have_header("re.h")
11
- create_makefile 'parser'
15
+ create_makefile 'json/ext/parser'
@@ -1,68 +1,92 @@
1
1
 
2
2
  #line 1 "parser.rl"
3
- #include "ruby.h"
4
- #include "unicode.h"
5
- #if HAVE_RE_H
6
- #include "re.h"
7
- #endif
8
- #if HAVE_RUBY_ST_H
9
- #include "ruby/st.h"
10
- #endif
11
- #if HAVE_ST_H
12
- #include "st.h"
13
- #endif
14
-
15
- #define EVIL 0x666
3
+ #include "parser.h"
4
+
5
+ /* unicode */
6
+
7
+ static const char digit_values[256] = {
8
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
11
+ -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
12
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
13
+ 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
14
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
16
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
17
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
21
+ -1, -1, -1, -1, -1, -1, -1
22
+ };
23
+
24
+ static UTF32 unescape_unicode(const unsigned char *p)
25
+ {
26
+ char b;
27
+ UTF32 result = 0;
28
+ b = digit_values[p[0]];
29
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
30
+ result = (result << 4) | b;
31
+ b = digit_values[p[1]];
32
+ result = (result << 4) | b;
33
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
34
+ b = digit_values[p[2]];
35
+ result = (result << 4) | b;
36
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
37
+ b = digit_values[p[3]];
38
+ result = (result << 4) | b;
39
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
40
+ return result;
41
+ }
16
42
 
17
- #ifndef RHASH_TBL
18
- #define RHASH_TBL(hsh) (RHASH(hsh)->tbl)
19
- #endif
43
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
44
+ {
45
+ int len = 1;
46
+ if (ch <= 0x7F) {
47
+ buf[0] = (char) ch;
48
+ } else if (ch <= 0x07FF) {
49
+ buf[0] = (char) ((ch >> 6) | 0xC0);
50
+ buf[1] = (char) ((ch & 0x3F) | 0x80);
51
+ len++;
52
+ } else if (ch <= 0xFFFF) {
53
+ buf[0] = (char) ((ch >> 12) | 0xE0);
54
+ buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
55
+ buf[2] = (char) ((ch & 0x3F) | 0x80);
56
+ len += 2;
57
+ } else if (ch <= 0x1fffff) {
58
+ buf[0] =(char) ((ch >> 18) | 0xF0);
59
+ buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
60
+ buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
61
+ buf[3] =(char) ((ch & 0x3F) | 0x80);
62
+ len += 3;
63
+ } else {
64
+ buf[0] = '?';
65
+ }
66
+ return len;
67
+ }
20
68
 
21
69
  #ifdef HAVE_RUBY_ENCODING_H
22
- #include "ruby/encoding.h"
23
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
70
+ static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
71
+ CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
72
+ static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
24
73
  #else
25
- #define FORCE_UTF8(obj)
74
+ static ID i_iconv;
26
75
  #endif
27
76
 
28
77
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
29
78
  static VALUE CNaN, CInfinity, CMinusInfinity;
30
79
 
31
80
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
32
- i_chr, i_max_nesting, i_allow_nan, i_object_class, i_array_class;
33
-
34
- #define MinusInfinity "-Infinity"
35
-
36
- typedef struct JSON_ParserStruct {
37
- VALUE Vsource;
38
- char *source;
39
- long len;
40
- char *memo;
41
- VALUE create_id;
42
- int max_nesting;
43
- int current_nesting;
44
- int allow_nan;
45
- VALUE object_class;
46
- VALUE array_class;
47
- } JSON_Parser;
81
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
82
+ i_array_class, i_key_p, i_deep_const_get;
48
83
 
49
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
50
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
51
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
52
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
53
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
54
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
55
84
 
56
- #define GET_STRUCT \
57
- JSON_Parser *json; \
58
- Data_Get_Struct(self, JSON_Parser, json);
59
-
60
-
61
- #line 84 "parser.rl"
85
+ #line 108 "parser.rl"
62
86
 
63
87
 
64
88
 
65
- #line 66 "parser.c"
89
+ #line 90 "parser.c"
66
90
  static const int JSON_object_start = 1;
67
91
  static const int JSON_object_first_final = 27;
68
92
  static const int JSON_object_error = 0;
@@ -70,7 +94,7 @@ static const int JSON_object_error = 0;
70
94
  static const int JSON_object_en_main = 1;
71
95
 
72
96
 
73
- #line 117 "parser.rl"
97
+ #line 143 "parser.rl"
74
98
 
75
99
 
76
100
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -80,20 +104,20 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
80
104
  VALUE object_class = json->object_class;
81
105
 
82
106
  if (json->max_nesting && json->current_nesting > json->max_nesting) {
83
- rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting);
107
+ rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
84
108
  }
85
109
 
86
110
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
87
111
 
88
112
 
89
- #line 90 "parser.c"
113
+ #line 114 "parser.c"
90
114
  {
91
115
  cs = JSON_object_start;
92
116
  }
93
117
 
94
- #line 132 "parser.rl"
118
+ #line 158 "parser.rl"
95
119
 
96
- #line 97 "parser.c"
120
+ #line 121 "parser.c"
97
121
  {
98
122
  if ( p == pe )
99
123
  goto _test_eof;
@@ -121,9 +145,12 @@ case 2:
121
145
  goto st2;
122
146
  goto st0;
123
147
  tr2:
124
- #line 103 "parser.rl"
148
+ #line 127 "parser.rl"
125
149
  {
126
- char *np = JSON_parse_string(json, p, pe, &last_name);
150
+ char *np;
151
+ json->parsing_name = 1;
152
+ np = JSON_parse_string(json, p, pe, &last_name);
153
+ json->parsing_name = 0;
127
154
  if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
128
155
  }
129
156
  goto st3;
@@ -131,7 +158,7 @@ st3:
131
158
  if ( ++p == pe )
132
159
  goto _test_eof3;
133
160
  case 3:
134
- #line 135 "parser.c"
161
+ #line 161 "parser.c"
135
162
  switch( (*p) ) {
136
163
  case 13: goto st3;
137
164
  case 32: goto st3;
@@ -198,7 +225,7 @@ case 8:
198
225
  goto st8;
199
226
  goto st0;
200
227
  tr11:
201
- #line 92 "parser.rl"
228
+ #line 116 "parser.rl"
202
229
  {
203
230
  VALUE v = Qnil;
204
231
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -214,7 +241,7 @@ st9:
214
241
  if ( ++p == pe )
215
242
  goto _test_eof9;
216
243
  case 9:
217
- #line 218 "parser.c"
244
+ #line 244 "parser.c"
218
245
  switch( (*p) ) {
219
246
  case 13: goto st9;
220
247
  case 32: goto st9;
@@ -303,14 +330,14 @@ case 18:
303
330
  goto st9;
304
331
  goto st18;
305
332
  tr4:
306
- #line 108 "parser.rl"
333
+ #line 134 "parser.rl"
307
334
  { p--; {p++; cs = 27; goto _out;} }
308
335
  goto st27;
309
336
  st27:
310
337
  if ( ++p == pe )
311
338
  goto _test_eof27;
312
339
  case 27:
313
- #line 314 "parser.c"
340
+ #line 340 "parser.c"
314
341
  goto st0;
315
342
  st19:
316
343
  if ( ++p == pe )
@@ -408,13 +435,13 @@ case 26:
408
435
  _out: {}
409
436
  }
410
437
 
411
- #line 133 "parser.rl"
438
+ #line 159 "parser.rl"
412
439
 
413
440
  if (cs >= JSON_object_first_final) {
414
441
  if (RTEST(json->create_id)) {
415
442
  VALUE klassname = rb_hash_aref(*result, json->create_id);
416
443
  if (!NIL_P(klassname)) {
417
- VALUE klass = rb_path2class(StringValueCStr(klassname));
444
+ VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
418
445
  if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
419
446
  *result = rb_funcall(klass, i_json_create, 1, *result);
420
447
  }
@@ -427,7 +454,7 @@ case 26:
427
454
  }
428
455
 
429
456
 
430
- #line 431 "parser.c"
457
+ #line 457 "parser.c"
431
458
  static const int JSON_value_start = 1;
432
459
  static const int JSON_value_first_final = 21;
433
460
  static const int JSON_value_error = 0;
@@ -435,7 +462,7 @@ static const int JSON_value_error = 0;
435
462
  static const int JSON_value_en_main = 1;
436
463
 
437
464
 
438
- #line 231 "parser.rl"
465
+ #line 257 "parser.rl"
439
466
 
440
467
 
441
468
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -443,14 +470,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
443
470
  int cs = EVIL;
444
471
 
445
472
 
446
- #line 447 "parser.c"
473
+ #line 473 "parser.c"
447
474
  {
448
475
  cs = JSON_value_start;
449
476
  }
450
477
 
451
- #line 238 "parser.rl"
478
+ #line 264 "parser.rl"
452
479
 
453
- #line 454 "parser.c"
480
+ #line 480 "parser.c"
454
481
  {
455
482
  if ( p == pe )
456
483
  goto _test_eof;
@@ -475,14 +502,14 @@ st0:
475
502
  cs = 0;
476
503
  goto _out;
477
504
  tr0:
478
- #line 179 "parser.rl"
505
+ #line 205 "parser.rl"
479
506
  {
480
507
  char *np = JSON_parse_string(json, p, pe, result);
481
508
  if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
482
509
  }
483
510
  goto st21;
484
511
  tr2:
485
- #line 184 "parser.rl"
512
+ #line 210 "parser.rl"
486
513
  {
487
514
  char *np;
488
515
  if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
@@ -502,7 +529,7 @@ tr2:
502
529
  }
503
530
  goto st21;
504
531
  tr5:
505
- #line 202 "parser.rl"
532
+ #line 228 "parser.rl"
506
533
  {
507
534
  char *np;
508
535
  json->current_nesting++;
@@ -512,7 +539,7 @@ tr5:
512
539
  }
513
540
  goto st21;
514
541
  tr9:
515
- #line 210 "parser.rl"
542
+ #line 236 "parser.rl"
516
543
  {
517
544
  char *np;
518
545
  json->current_nesting++;
@@ -522,7 +549,7 @@ tr9:
522
549
  }
523
550
  goto st21;
524
551
  tr16:
525
- #line 172 "parser.rl"
552
+ #line 198 "parser.rl"
526
553
  {
527
554
  if (json->allow_nan) {
528
555
  *result = CInfinity;
@@ -532,7 +559,7 @@ tr16:
532
559
  }
533
560
  goto st21;
534
561
  tr18:
535
- #line 165 "parser.rl"
562
+ #line 191 "parser.rl"
536
563
  {
537
564
  if (json->allow_nan) {
538
565
  *result = CNaN;
@@ -542,19 +569,19 @@ tr18:
542
569
  }
543
570
  goto st21;
544
571
  tr22:
545
- #line 159 "parser.rl"
572
+ #line 185 "parser.rl"
546
573
  {
547
574
  *result = Qfalse;
548
575
  }
549
576
  goto st21;
550
577
  tr25:
551
- #line 156 "parser.rl"
578
+ #line 182 "parser.rl"
552
579
  {
553
580
  *result = Qnil;
554
581
  }
555
582
  goto st21;
556
583
  tr28:
557
- #line 162 "parser.rl"
584
+ #line 188 "parser.rl"
558
585
  {
559
586
  *result = Qtrue;
560
587
  }
@@ -563,9 +590,9 @@ st21:
563
590
  if ( ++p == pe )
564
591
  goto _test_eof21;
565
592
  case 21:
566
- #line 218 "parser.rl"
593
+ #line 244 "parser.rl"
567
594
  { p--; {p++; cs = 21; goto _out;} }
568
- #line 569 "parser.c"
595
+ #line 595 "parser.c"
569
596
  goto st0;
570
597
  st2:
571
598
  if ( ++p == pe )
@@ -726,7 +753,7 @@ case 20:
726
753
  _out: {}
727
754
  }
728
755
 
729
- #line 239 "parser.rl"
756
+ #line 265 "parser.rl"
730
757
 
731
758
  if (cs >= JSON_value_first_final) {
732
759
  return p;
@@ -736,7 +763,7 @@ case 20:
736
763
  }
737
764
 
738
765
 
739
- #line 740 "parser.c"
766
+ #line 766 "parser.c"
740
767
  static const int JSON_integer_start = 1;
741
768
  static const int JSON_integer_first_final = 5;
742
769
  static const int JSON_integer_error = 0;
@@ -744,7 +771,7 @@ static const int JSON_integer_error = 0;
744
771
  static const int JSON_integer_en_main = 1;
745
772
 
746
773
 
747
- #line 255 "parser.rl"
774
+ #line 281 "parser.rl"
748
775
 
749
776
 
750
777
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -752,15 +779,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
752
779
  int cs = EVIL;
753
780
 
754
781
 
755
- #line 756 "parser.c"
782
+ #line 782 "parser.c"
756
783
  {
757
784
  cs = JSON_integer_start;
758
785
  }
759
786
 
760
- #line 262 "parser.rl"
787
+ #line 288 "parser.rl"
761
788
  json->memo = p;
762
789
 
763
- #line 764 "parser.c"
790
+ #line 790 "parser.c"
764
791
  {
765
792
  if ( p == pe )
766
793
  goto _test_eof;
@@ -794,14 +821,14 @@ case 3:
794
821
  goto st0;
795
822
  goto tr4;
796
823
  tr4:
797
- #line 252 "parser.rl"
824
+ #line 278 "parser.rl"
798
825
  { p--; {p++; cs = 5; goto _out;} }
799
826
  goto st5;
800
827
  st5:
801
828
  if ( ++p == pe )
802
829
  goto _test_eof5;
803
830
  case 5:
804
- #line 805 "parser.c"
831
+ #line 831 "parser.c"
805
832
  goto st0;
806
833
  st4:
807
834
  if ( ++p == pe )
@@ -820,7 +847,7 @@ case 4:
820
847
  _out: {}
821
848
  }
822
849
 
823
- #line 264 "parser.rl"
850
+ #line 290 "parser.rl"
824
851
 
825
852
  if (cs >= JSON_integer_first_final) {
826
853
  long len = p - json->memo;
@@ -832,7 +859,7 @@ case 4:
832
859
  }
833
860
 
834
861
 
835
- #line 836 "parser.c"
862
+ #line 862 "parser.c"
836
863
  static const int JSON_float_start = 1;
837
864
  static const int JSON_float_first_final = 10;
838
865
  static const int JSON_float_error = 0;
@@ -840,7 +867,7 @@ static const int JSON_float_error = 0;
840
867
  static const int JSON_float_en_main = 1;
841
868
 
842
869
 
843
- #line 286 "parser.rl"
870
+ #line 312 "parser.rl"
844
871
 
845
872
 
846
873
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -848,15 +875,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
848
875
  int cs = EVIL;
849
876
 
850
877
 
851
- #line 852 "parser.c"
878
+ #line 878 "parser.c"
852
879
  {
853
880
  cs = JSON_float_start;
854
881
  }
855
882
 
856
- #line 293 "parser.rl"
883
+ #line 319 "parser.rl"
857
884
  json->memo = p;
858
885
 
859
- #line 860 "parser.c"
886
+ #line 886 "parser.c"
860
887
  {
861
888
  if ( p == pe )
862
889
  goto _test_eof;
@@ -914,14 +941,14 @@ case 5:
914
941
  goto st0;
915
942
  goto tr7;
916
943
  tr7:
917
- #line 280 "parser.rl"
944
+ #line 306 "parser.rl"
918
945
  { p--; {p++; cs = 10; goto _out;} }
919
946
  goto st10;
920
947
  st10:
921
948
  if ( ++p == pe )
922
949
  goto _test_eof10;
923
950
  case 10:
924
- #line 925 "parser.c"
951
+ #line 951 "parser.c"
925
952
  goto st0;
926
953
  st6:
927
954
  if ( ++p == pe )
@@ -982,7 +1009,7 @@ case 9:
982
1009
  _out: {}
983
1010
  }
984
1011
 
985
- #line 295 "parser.rl"
1012
+ #line 321 "parser.rl"
986
1013
 
987
1014
  if (cs >= JSON_float_first_final) {
988
1015
  long len = p - json->memo;
@@ -995,7 +1022,7 @@ case 9:
995
1022
 
996
1023
 
997
1024
 
998
- #line 999 "parser.c"
1025
+ #line 1025 "parser.c"
999
1026
  static const int JSON_array_start = 1;
1000
1027
  static const int JSON_array_first_final = 17;
1001
1028
  static const int JSON_array_error = 0;
@@ -1003,7 +1030,7 @@ static const int JSON_array_error = 0;
1003
1030
  static const int JSON_array_en_main = 1;
1004
1031
 
1005
1032
 
1006
- #line 331 "parser.rl"
1033
+ #line 357 "parser.rl"
1007
1034
 
1008
1035
 
1009
1036
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -1012,19 +1039,19 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
1012
1039
  VALUE array_class = json->array_class;
1013
1040
 
1014
1041
  if (json->max_nesting && json->current_nesting > json->max_nesting) {
1015
- rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting);
1042
+ rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1016
1043
  }
1017
1044
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1018
1045
 
1019
1046
 
1020
- #line 1021 "parser.c"
1047
+ #line 1047 "parser.c"
1021
1048
  {
1022
1049
  cs = JSON_array_start;
1023
1050
  }
1024
1051
 
1025
- #line 344 "parser.rl"
1052
+ #line 370 "parser.rl"
1026
1053
 
1027
- #line 1028 "parser.c"
1054
+ #line 1054 "parser.c"
1028
1055
  {
1029
1056
  if ( p == pe )
1030
1057
  goto _test_eof;
@@ -1063,7 +1090,7 @@ case 2:
1063
1090
  goto st2;
1064
1091
  goto st0;
1065
1092
  tr2:
1066
- #line 312 "parser.rl"
1093
+ #line 338 "parser.rl"
1067
1094
  {
1068
1095
  VALUE v = Qnil;
1069
1096
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -1079,7 +1106,7 @@ st3:
1079
1106
  if ( ++p == pe )
1080
1107
  goto _test_eof3;
1081
1108
  case 3:
1082
- #line 1083 "parser.c"
1109
+ #line 1109 "parser.c"
1083
1110
  switch( (*p) ) {
1084
1111
  case 13: goto st3;
1085
1112
  case 32: goto st3;
@@ -1179,14 +1206,14 @@ case 12:
1179
1206
  goto st3;
1180
1207
  goto st12;
1181
1208
  tr4:
1182
- #line 323 "parser.rl"
1209
+ #line 349 "parser.rl"
1183
1210
  { p--; {p++; cs = 17; goto _out;} }
1184
1211
  goto st17;
1185
1212
  st17:
1186
1213
  if ( ++p == pe )
1187
1214
  goto _test_eof17;
1188
1215
  case 17:
1189
- #line 1190 "parser.c"
1216
+ #line 1216 "parser.c"
1190
1217
  goto st0;
1191
1218
  st13:
1192
1219
  if ( ++p == pe )
@@ -1242,73 +1269,88 @@ case 16:
1242
1269
  _out: {}
1243
1270
  }
1244
1271
 
1245
- #line 345 "parser.rl"
1272
+ #line 371 "parser.rl"
1246
1273
 
1247
1274
  if(cs >= JSON_array_first_final) {
1248
1275
  return p + 1;
1249
1276
  } else {
1250
1277
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1278
+ return NULL;
1251
1279
  }
1252
1280
  }
1253
1281
 
1254
- static VALUE json_string_unescape(char *p, char *pe)
1282
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1255
1283
  {
1256
- VALUE result = rb_str_buf_new(pe - p + 1);
1257
-
1258
- while (p < pe) {
1259
- if (*p == '\\') {
1260
- p++;
1261
- if (p >= pe) return Qnil; /* raise an exception later, \ at end */
1262
- switch (*p) {
1284
+ char *p = string, *pe = string, *unescape;
1285
+ int unescape_len;
1286
+
1287
+ while (pe < stringEnd) {
1288
+ if (*pe == '\\') {
1289
+ unescape = (char *) "?";
1290
+ unescape_len = 1;
1291
+ if (pe > p) rb_str_buf_cat(result, p, pe - p);
1292
+ switch (*++pe) {
1293
+ case 'n':
1294
+ unescape = (char *) "\n";
1295
+ break;
1296
+ case 'r':
1297
+ unescape = (char *) "\r";
1298
+ break;
1299
+ case 't':
1300
+ unescape = (char *) "\t";
1301
+ break;
1263
1302
  case '"':
1303
+ unescape = (char *) "\"";
1304
+ break;
1264
1305
  case '\\':
1265
- rb_str_buf_cat(result, p, 1);
1266
- p++;
1306
+ unescape = (char *) "\\";
1267
1307
  break;
1268
1308
  case 'b':
1269
- rb_str_buf_cat2(result, "\b");
1270
- p++;
1309
+ unescape = (char *) "\b";
1271
1310
  break;
1272
1311
  case 'f':
1273
- rb_str_buf_cat2(result, "\f");
1274
- p++;
1275
- break;
1276
- case 'n':
1277
- rb_str_buf_cat2(result, "\n");
1278
- p++;
1279
- break;
1280
- case 'r':
1281
- rb_str_buf_cat2(result, "\r");
1282
- p++;
1283
- break;
1284
- case 't':
1285
- rb_str_buf_cat2(result, "\t");
1286
- p++;
1312
+ unescape = (char *) "\f";
1287
1313
  break;
1288
1314
  case 'u':
1289
- if (p > pe - 4) {
1315
+ if (pe > stringEnd - 4) {
1290
1316
  return Qnil;
1291
1317
  } else {
1292
- p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
1318
+ char buf[4];
1319
+ UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1320
+ pe += 3;
1321
+ if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1322
+ pe++;
1323
+ if (pe > stringEnd - 6) return Qnil;
1324
+ if (pe[0] == '\\' && pe[1] == 'u') {
1325
+ UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1326
+ ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1327
+ | (sur & 0x3FF));
1328
+ pe += 5;
1329
+ } else {
1330
+ unescape = (char *) "?";
1331
+ break;
1332
+ }
1333
+ }
1334
+ unescape_len = convert_UTF32_to_UTF8(buf, ch);
1335
+ unescape = buf;
1293
1336
  }
1294
1337
  break;
1295
1338
  default:
1296
- rb_str_buf_cat(result, p, 1);
1297
- p++;
1298
- break;
1339
+ p = pe;
1340
+ continue;
1299
1341
  }
1342
+ rb_str_buf_cat(result, unescape, unescape_len);
1343
+ p = ++pe;
1300
1344
  } else {
1301
- char *q = p;
1302
- while (*q != '\\' && q < pe) q++;
1303
- rb_str_buf_cat(result, p, q - p);
1304
- p = q;
1345
+ pe++;
1305
1346
  }
1306
1347
  }
1348
+ rb_str_buf_cat(result, p, pe - p);
1307
1349
  return result;
1308
1350
  }
1309
1351
 
1310
1352
 
1311
- #line 1312 "parser.c"
1353
+ #line 1353 "parser.c"
1312
1354
  static const int JSON_string_start = 1;
1313
1355
  static const int JSON_string_first_final = 8;
1314
1356
  static const int JSON_string_error = 0;
@@ -1316,24 +1358,24 @@ static const int JSON_string_error = 0;
1316
1358
  static const int JSON_string_en_main = 1;
1317
1359
 
1318
1360
 
1319
- #line 429 "parser.rl"
1361
+ #line 470 "parser.rl"
1320
1362
 
1321
1363
 
1322
1364
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1323
1365
  {
1324
1366
  int cs = EVIL;
1325
1367
 
1326
- *result = rb_str_new("", 0);
1368
+ *result = rb_str_buf_new(0);
1327
1369
 
1328
- #line 1329 "parser.c"
1370
+ #line 1370 "parser.c"
1329
1371
  {
1330
1372
  cs = JSON_string_start;
1331
1373
  }
1332
1374
 
1333
- #line 437 "parser.rl"
1375
+ #line 478 "parser.rl"
1334
1376
  json->memo = p;
1335
1377
 
1336
- #line 1337 "parser.c"
1378
+ #line 1378 "parser.c"
1337
1379
  {
1338
1380
  if ( p == pe )
1339
1381
  goto _test_eof;
@@ -1358,9 +1400,9 @@ case 2:
1358
1400
  goto st0;
1359
1401
  goto st2;
1360
1402
  tr2:
1361
- #line 415 "parser.rl"
1403
+ #line 456 "parser.rl"
1362
1404
  {
1363
- *result = json_string_unescape(json->memo + 1, p);
1405
+ *result = json_string_unescape(*result, json->memo + 1, p);
1364
1406
  if (NIL_P(*result)) {
1365
1407
  p--;
1366
1408
  {p++; cs = 8; goto _out;}
@@ -1369,14 +1411,14 @@ tr2:
1369
1411
  {p = (( p + 1))-1;}
1370
1412
  }
1371
1413
  }
1372
- #line 426 "parser.rl"
1414
+ #line 467 "parser.rl"
1373
1415
  { p--; {p++; cs = 8; goto _out;} }
1374
1416
  goto st8;
1375
1417
  st8:
1376
1418
  if ( ++p == pe )
1377
1419
  goto _test_eof8;
1378
1420
  case 8:
1379
- #line 1380 "parser.c"
1421
+ #line 1421 "parser.c"
1380
1422
  goto st0;
1381
1423
  st3:
1382
1424
  if ( ++p == pe )
@@ -1452,8 +1494,11 @@ case 7:
1452
1494
  _out: {}
1453
1495
  }
1454
1496
 
1455
- #line 439 "parser.rl"
1497
+ #line 480 "parser.rl"
1456
1498
 
1499
+ if (json->symbolize_names && json->parsing_name) {
1500
+ *result = rb_str_intern(*result);
1501
+ }
1457
1502
  if (cs >= JSON_string_first_final) {
1458
1503
  return p + 1;
1459
1504
  } else {
@@ -1463,7 +1508,7 @@ case 7:
1463
1508
 
1464
1509
 
1465
1510
 
1466
- #line 1467 "parser.c"
1511
+ #line 1511 "parser.c"
1467
1512
  static const int JSON_start = 1;
1468
1513
  static const int JSON_first_final = 10;
1469
1514
  static const int JSON_error = 0;
@@ -1471,7 +1516,7 @@ static const int JSON_error = 0;
1471
1516
  static const int JSON_en_main = 1;
1472
1517
 
1473
1518
 
1474
- #line 473 "parser.rl"
1519
+ #line 517 "parser.rl"
1475
1520
 
1476
1521
 
1477
1522
  /*
@@ -1486,6 +1531,54 @@ static const int JSON_en_main = 1;
1486
1531
  *
1487
1532
  */
1488
1533
 
1534
+ static VALUE convert_encoding(VALUE source)
1535
+ {
1536
+ char *ptr = RSTRING_PTR(source);
1537
+ long len = RSTRING_LEN(source);
1538
+ if (len < 2) {
1539
+ rb_raise(eParserError, "A JSON text must at least contain two octets!");
1540
+ }
1541
+ #ifdef HAVE_RUBY_ENCODING_H
1542
+ {
1543
+ VALUE encoding = rb_funcall(source, i_encoding, 0);
1544
+ if (encoding == CEncoding_ASCII_8BIT) {
1545
+ if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1546
+ source = rb_str_dup(source);
1547
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
1548
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1549
+ } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1550
+ source = rb_str_dup(source);
1551
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
1552
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1553
+ } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1554
+ source = rb_str_dup(source);
1555
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
1556
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1557
+ } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1558
+ source = rb_str_dup(source);
1559
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
1560
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1561
+ } else {
1562
+ FORCE_UTF8(source);
1563
+ }
1564
+ } else {
1565
+ source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
1566
+ }
1567
+ }
1568
+ #else
1569
+ if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1570
+ source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1571
+ } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1572
+ source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1573
+ } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1574
+ source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1575
+ } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1576
+ source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1577
+ }
1578
+ #endif
1579
+ return source;
1580
+ }
1581
+
1489
1582
  /*
1490
1583
  * call-seq: new(source, opts => {})
1491
1584
  *
@@ -1503,6 +1596,9 @@ static const int JSON_en_main = 1;
1503
1596
  * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
1504
1597
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1505
1598
  * false.
1599
+ * * *symbolize_names*: If set to true, returns symbols for the names
1600
+ * (keys) in a JSON object. Otherwise strings are returned, which is also
1601
+ * the default.
1506
1602
  * * *create_additions*: If set to false, the Parser doesn't create
1507
1603
  * additions even if a matchin class and create_id was found. This option
1508
1604
  * defaults to true.
@@ -1514,21 +1610,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1514
1610
  char *ptr;
1515
1611
  long len;
1516
1612
  VALUE source, opts;
1517
- GET_STRUCT;
1613
+ GET_PARSER;
1518
1614
  rb_scan_args(argc, argv, "11", &source, &opts);
1519
- source = StringValue(source);
1615
+ source = convert_encoding(StringValue(source));
1520
1616
  ptr = RSTRING_PTR(source);
1521
1617
  len = RSTRING_LEN(source);
1522
- if (len < 2) {
1523
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
1524
- }
1525
1618
  if (!NIL_P(opts)) {
1526
1619
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1527
1620
  if (NIL_P(opts)) {
1528
1621
  rb_raise(rb_eArgError, "opts needs to be like a hash");
1529
1622
  } else {
1530
1623
  VALUE tmp = ID2SYM(i_max_nesting);
1531
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
1624
+ if (option_given_p(opts, tmp)) {
1532
1625
  VALUE max_nesting = rb_hash_aref(opts, tmp);
1533
1626
  if (RTEST(max_nesting)) {
1534
1627
  Check_Type(max_nesting, T_FIXNUM);
@@ -1540,14 +1633,21 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1540
1633
  json->max_nesting = 19;
1541
1634
  }
1542
1635
  tmp = ID2SYM(i_allow_nan);
1543
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
1636
+ if (option_given_p(opts, tmp)) {
1544
1637
  VALUE allow_nan = rb_hash_aref(opts, tmp);
1545
1638
  json->allow_nan = RTEST(allow_nan) ? 1 : 0;
1546
1639
  } else {
1547
1640
  json->allow_nan = 0;
1548
1641
  }
1642
+ tmp = ID2SYM(i_symbolize_names);
1643
+ if (option_given_p(opts, tmp)) {
1644
+ VALUE symbolize_names = rb_hash_aref(opts, tmp);
1645
+ json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
1646
+ } else {
1647
+ json->symbolize_names = 0;
1648
+ }
1549
1649
  tmp = ID2SYM(i_create_additions);
1550
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
1650
+ if (option_given_p(opts, tmp)) {
1551
1651
  VALUE create_additions = rb_hash_aref(opts, tmp);
1552
1652
  if (RTEST(create_additions)) {
1553
1653
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
@@ -1558,13 +1658,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1558
1658
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1559
1659
  }
1560
1660
  tmp = ID2SYM(i_object_class);
1561
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
1661
+ if (option_given_p(opts, tmp)) {
1562
1662
  json->object_class = rb_hash_aref(opts, tmp);
1563
1663
  } else {
1564
1664
  json->object_class = Qnil;
1565
1665
  }
1566
1666
  tmp = ID2SYM(i_array_class);
1567
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
1667
+ if (option_given_p(opts, tmp)) {
1568
1668
  json->array_class = rb_hash_aref(opts, tmp);
1569
1669
  } else {
1570
1670
  json->array_class = Qnil;
@@ -1578,18 +1678,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1578
1678
  json->array_class = Qnil;
1579
1679
  }
1580
1680
  json->current_nesting = 0;
1581
- /*
1582
- Convert these?
1583
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1584
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1585
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1586
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1587
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1588
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1589
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1590
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1591
- }
1592
- */
1593
1681
  json->len = len;
1594
1682
  json->source = ptr;
1595
1683
  json->Vsource = source;
@@ -1607,19 +1695,19 @@ static VALUE cParser_parse(VALUE self)
1607
1695
  char *p, *pe;
1608
1696
  int cs = EVIL;
1609
1697
  VALUE result = Qnil;
1610
- GET_STRUCT;
1698
+ GET_PARSER;
1611
1699
 
1612
1700
 
1613
- #line 1614 "parser.c"
1701
+ #line 1701 "parser.c"
1614
1702
  {
1615
1703
  cs = JSON_start;
1616
1704
  }
1617
1705
 
1618
- #line 611 "parser.rl"
1706
+ #line 698 "parser.rl"
1619
1707
  p = json->source;
1620
1708
  pe = p + json->len;
1621
1709
 
1622
- #line 1623 "parser.c"
1710
+ #line 1710 "parser.c"
1623
1711
  {
1624
1712
  if ( p == pe )
1625
1713
  goto _test_eof;
@@ -1675,7 +1763,7 @@ case 5:
1675
1763
  goto st1;
1676
1764
  goto st5;
1677
1765
  tr3:
1678
- #line 462 "parser.rl"
1766
+ #line 506 "parser.rl"
1679
1767
  {
1680
1768
  char *np;
1681
1769
  json->current_nesting = 1;
@@ -1684,7 +1772,7 @@ tr3:
1684
1772
  }
1685
1773
  goto st10;
1686
1774
  tr4:
1687
- #line 455 "parser.rl"
1775
+ #line 499 "parser.rl"
1688
1776
  {
1689
1777
  char *np;
1690
1778
  json->current_nesting = 1;
@@ -1696,7 +1784,7 @@ st10:
1696
1784
  if ( ++p == pe )
1697
1785
  goto _test_eof10;
1698
1786
  case 10:
1699
- #line 1700 "parser.c"
1787
+ #line 1787 "parser.c"
1700
1788
  switch( (*p) ) {
1701
1789
  case 13: goto st10;
1702
1790
  case 32: goto st10;
@@ -1753,16 +1841,17 @@ case 9:
1753
1841
  _out: {}
1754
1842
  }
1755
1843
 
1756
- #line 614 "parser.rl"
1844
+ #line 701 "parser.rl"
1757
1845
 
1758
1846
  if (cs >= JSON_first_final && p == pe) {
1759
1847
  return result;
1760
1848
  } else {
1761
1849
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1850
+ return Qnil;
1762
1851
  }
1763
1852
  }
1764
1853
 
1765
- inline static JSON_Parser *JSON_allocate()
1854
+ static JSON_Parser *JSON_allocate()
1766
1855
  {
1767
1856
  JSON_Parser *json = ALLOC(JSON_Parser);
1768
1857
  MEMZERO(json, JSON_Parser, 1);
@@ -1796,7 +1885,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
1796
1885
  */
1797
1886
  static VALUE cParser_source(VALUE self)
1798
1887
  {
1799
- GET_STRUCT;
1888
+ GET_PARSER;
1800
1889
  return rb_str_dup(json->Vsource);
1801
1890
  }
1802
1891
 
@@ -1824,6 +1913,23 @@ void Init_parser()
1824
1913
  i_chr = rb_intern("chr");
1825
1914
  i_max_nesting = rb_intern("max_nesting");
1826
1915
  i_allow_nan = rb_intern("allow_nan");
1916
+ i_symbolize_names = rb_intern("symbolize_names");
1827
1917
  i_object_class = rb_intern("object_class");
1828
1918
  i_array_class = rb_intern("array_class");
1919
+ i_key_p = rb_intern("key?");
1920
+ i_deep_const_get = rb_intern("deep_const_get");
1921
+ #ifdef HAVE_RUBY_ENCODING_H
1922
+ CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1923
+ CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
1924
+ CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
1925
+ CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
1926
+ CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
1927
+ CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
1928
+ i_encoding = rb_intern("encoding");
1929
+ i_encode = rb_intern("encode");
1930
+ i_encode_bang = rb_intern("encode!");
1931
+ i_force_encoding = rb_intern("force_encoding");
1932
+ #else
1933
+ i_iconv = rb_intern("iconv");
1934
+ #endif
1829
1935
  }