json_pure 1.2.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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_integer(FBuffer *fb, int 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,23 +1,76 @@
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
-
9
- #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
+ }
10
42
 
11
- #define option_given_p(opts, key) RTEST(rb_funcall((opts), i_key_p, 1, (key)))
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
+ }
12
68
 
13
69
  #ifdef HAVE_RUBY_ENCODING_H
14
- #include "ruby/encoding.h"
15
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
16
- static VALUE mEncoding_ASCII_8BIT, mEncoding_UTF_8, mEncoding_UTF_16BE,
17
- mEncoding_UTF_16LE, mEncoding_UTF_32BE, mEncoding_UTF_32LE;
70
+ static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
71
+ CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
18
72
  static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
19
73
  #else
20
- #define FORCE_UTF8(obj)
21
74
  static ID i_iconv;
22
75
  #endif
23
76
 
@@ -28,40 +81,12 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
28
81
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
29
82
  i_array_class, i_key_p, i_deep_const_get;
30
83
 
31
- #define MinusInfinity "-Infinity"
32
-
33
- typedef struct JSON_ParserStruct {
34
- VALUE Vsource;
35
- char *source;
36
- long len;
37
- char *memo;
38
- VALUE create_id;
39
- int max_nesting;
40
- int current_nesting;
41
- int allow_nan;
42
- int parsing_name;
43
- int symbolize_names;
44
- VALUE object_class;
45
- VALUE array_class;
46
- } JSON_Parser;
47
-
48
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
49
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
50
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
51
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
52
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
53
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
54
-
55
- #define GET_STRUCT \
56
- JSON_Parser *json; \
57
- Data_Get_Struct(self, JSON_Parser, json);
58
84
 
85
+ #line 108 "parser.rl"
59
86
 
60
- #line 83 "parser.rl"
61
87
 
62
88
 
63
-
64
- #line 65 "parser.c"
89
+ #line 90 "parser.c"
65
90
  static const int JSON_object_start = 1;
66
91
  static const int JSON_object_first_final = 27;
67
92
  static const int JSON_object_error = 0;
@@ -69,7 +94,7 @@ static const int JSON_object_error = 0;
69
94
  static const int JSON_object_en_main = 1;
70
95
 
71
96
 
72
- #line 118 "parser.rl"
97
+ #line 143 "parser.rl"
73
98
 
74
99
 
75
100
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -85,14 +110,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
85
110
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
86
111
 
87
112
 
88
- #line 89 "parser.c"
113
+ #line 114 "parser.c"
89
114
  {
90
115
  cs = JSON_object_start;
91
116
  }
92
117
 
93
- #line 133 "parser.rl"
118
+ #line 158 "parser.rl"
94
119
 
95
- #line 96 "parser.c"
120
+ #line 121 "parser.c"
96
121
  {
97
122
  if ( p == pe )
98
123
  goto _test_eof;
@@ -120,7 +145,7 @@ case 2:
120
145
  goto st2;
121
146
  goto st0;
122
147
  tr2:
123
- #line 102 "parser.rl"
148
+ #line 127 "parser.rl"
124
149
  {
125
150
  json->parsing_name = 1;
126
151
  char *np = JSON_parse_string(json, p, pe, &last_name);
@@ -132,7 +157,7 @@ st3:
132
157
  if ( ++p == pe )
133
158
  goto _test_eof3;
134
159
  case 3:
135
- #line 136 "parser.c"
160
+ #line 161 "parser.c"
136
161
  switch( (*p) ) {
137
162
  case 13: goto st3;
138
163
  case 32: goto st3;
@@ -199,7 +224,7 @@ case 8:
199
224
  goto st8;
200
225
  goto st0;
201
226
  tr11:
202
- #line 91 "parser.rl"
227
+ #line 116 "parser.rl"
203
228
  {
204
229
  VALUE v = Qnil;
205
230
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -215,7 +240,7 @@ st9:
215
240
  if ( ++p == pe )
216
241
  goto _test_eof9;
217
242
  case 9:
218
- #line 219 "parser.c"
243
+ #line 244 "parser.c"
219
244
  switch( (*p) ) {
220
245
  case 13: goto st9;
221
246
  case 32: goto st9;
@@ -304,14 +329,14 @@ case 18:
304
329
  goto st9;
305
330
  goto st18;
306
331
  tr4:
307
- #line 109 "parser.rl"
332
+ #line 134 "parser.rl"
308
333
  { p--; {p++; cs = 27; goto _out;} }
309
334
  goto st27;
310
335
  st27:
311
336
  if ( ++p == pe )
312
337
  goto _test_eof27;
313
338
  case 27:
314
- #line 315 "parser.c"
339
+ #line 340 "parser.c"
315
340
  goto st0;
316
341
  st19:
317
342
  if ( ++p == pe )
@@ -409,7 +434,7 @@ case 26:
409
434
  _out: {}
410
435
  }
411
436
 
412
- #line 134 "parser.rl"
437
+ #line 159 "parser.rl"
413
438
 
414
439
  if (cs >= JSON_object_first_final) {
415
440
  if (RTEST(json->create_id)) {
@@ -428,7 +453,7 @@ case 26:
428
453
  }
429
454
 
430
455
 
431
- #line 432 "parser.c"
456
+ #line 457 "parser.c"
432
457
  static const int JSON_value_start = 1;
433
458
  static const int JSON_value_first_final = 21;
434
459
  static const int JSON_value_error = 0;
@@ -436,7 +461,7 @@ static const int JSON_value_error = 0;
436
461
  static const int JSON_value_en_main = 1;
437
462
 
438
463
 
439
- #line 232 "parser.rl"
464
+ #line 257 "parser.rl"
440
465
 
441
466
 
442
467
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -444,14 +469,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
444
469
  int cs = EVIL;
445
470
 
446
471
 
447
- #line 448 "parser.c"
472
+ #line 473 "parser.c"
448
473
  {
449
474
  cs = JSON_value_start;
450
475
  }
451
476
 
452
- #line 239 "parser.rl"
477
+ #line 264 "parser.rl"
453
478
 
454
- #line 455 "parser.c"
479
+ #line 480 "parser.c"
455
480
  {
456
481
  if ( p == pe )
457
482
  goto _test_eof;
@@ -476,14 +501,14 @@ st0:
476
501
  cs = 0;
477
502
  goto _out;
478
503
  tr0:
479
- #line 180 "parser.rl"
504
+ #line 205 "parser.rl"
480
505
  {
481
506
  char *np = JSON_parse_string(json, p, pe, result);
482
507
  if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
483
508
  }
484
509
  goto st21;
485
510
  tr2:
486
- #line 185 "parser.rl"
511
+ #line 210 "parser.rl"
487
512
  {
488
513
  char *np;
489
514
  if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
@@ -503,7 +528,7 @@ tr2:
503
528
  }
504
529
  goto st21;
505
530
  tr5:
506
- #line 203 "parser.rl"
531
+ #line 228 "parser.rl"
507
532
  {
508
533
  char *np;
509
534
  json->current_nesting++;
@@ -513,7 +538,7 @@ tr5:
513
538
  }
514
539
  goto st21;
515
540
  tr9:
516
- #line 211 "parser.rl"
541
+ #line 236 "parser.rl"
517
542
  {
518
543
  char *np;
519
544
  json->current_nesting++;
@@ -523,7 +548,7 @@ tr9:
523
548
  }
524
549
  goto st21;
525
550
  tr16:
526
- #line 173 "parser.rl"
551
+ #line 198 "parser.rl"
527
552
  {
528
553
  if (json->allow_nan) {
529
554
  *result = CInfinity;
@@ -533,7 +558,7 @@ tr16:
533
558
  }
534
559
  goto st21;
535
560
  tr18:
536
- #line 166 "parser.rl"
561
+ #line 191 "parser.rl"
537
562
  {
538
563
  if (json->allow_nan) {
539
564
  *result = CNaN;
@@ -543,19 +568,19 @@ tr18:
543
568
  }
544
569
  goto st21;
545
570
  tr22:
546
- #line 160 "parser.rl"
571
+ #line 185 "parser.rl"
547
572
  {
548
573
  *result = Qfalse;
549
574
  }
550
575
  goto st21;
551
576
  tr25:
552
- #line 157 "parser.rl"
577
+ #line 182 "parser.rl"
553
578
  {
554
579
  *result = Qnil;
555
580
  }
556
581
  goto st21;
557
582
  tr28:
558
- #line 163 "parser.rl"
583
+ #line 188 "parser.rl"
559
584
  {
560
585
  *result = Qtrue;
561
586
  }
@@ -564,9 +589,9 @@ st21:
564
589
  if ( ++p == pe )
565
590
  goto _test_eof21;
566
591
  case 21:
567
- #line 219 "parser.rl"
592
+ #line 244 "parser.rl"
568
593
  { p--; {p++; cs = 21; goto _out;} }
569
- #line 570 "parser.c"
594
+ #line 595 "parser.c"
570
595
  goto st0;
571
596
  st2:
572
597
  if ( ++p == pe )
@@ -727,7 +752,7 @@ case 20:
727
752
  _out: {}
728
753
  }
729
754
 
730
- #line 240 "parser.rl"
755
+ #line 265 "parser.rl"
731
756
 
732
757
  if (cs >= JSON_value_first_final) {
733
758
  return p;
@@ -737,7 +762,7 @@ case 20:
737
762
  }
738
763
 
739
764
 
740
- #line 741 "parser.c"
765
+ #line 766 "parser.c"
741
766
  static const int JSON_integer_start = 1;
742
767
  static const int JSON_integer_first_final = 5;
743
768
  static const int JSON_integer_error = 0;
@@ -745,7 +770,7 @@ static const int JSON_integer_error = 0;
745
770
  static const int JSON_integer_en_main = 1;
746
771
 
747
772
 
748
- #line 256 "parser.rl"
773
+ #line 281 "parser.rl"
749
774
 
750
775
 
751
776
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -753,15 +778,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
753
778
  int cs = EVIL;
754
779
 
755
780
 
756
- #line 757 "parser.c"
781
+ #line 782 "parser.c"
757
782
  {
758
783
  cs = JSON_integer_start;
759
784
  }
760
785
 
761
- #line 263 "parser.rl"
786
+ #line 288 "parser.rl"
762
787
  json->memo = p;
763
788
 
764
- #line 765 "parser.c"
789
+ #line 790 "parser.c"
765
790
  {
766
791
  if ( p == pe )
767
792
  goto _test_eof;
@@ -795,14 +820,14 @@ case 3:
795
820
  goto st0;
796
821
  goto tr4;
797
822
  tr4:
798
- #line 253 "parser.rl"
823
+ #line 278 "parser.rl"
799
824
  { p--; {p++; cs = 5; goto _out;} }
800
825
  goto st5;
801
826
  st5:
802
827
  if ( ++p == pe )
803
828
  goto _test_eof5;
804
829
  case 5:
805
- #line 806 "parser.c"
830
+ #line 831 "parser.c"
806
831
  goto st0;
807
832
  st4:
808
833
  if ( ++p == pe )
@@ -821,7 +846,7 @@ case 4:
821
846
  _out: {}
822
847
  }
823
848
 
824
- #line 265 "parser.rl"
849
+ #line 290 "parser.rl"
825
850
 
826
851
  if (cs >= JSON_integer_first_final) {
827
852
  long len = p - json->memo;
@@ -833,7 +858,7 @@ case 4:
833
858
  }
834
859
 
835
860
 
836
- #line 837 "parser.c"
861
+ #line 862 "parser.c"
837
862
  static const int JSON_float_start = 1;
838
863
  static const int JSON_float_first_final = 10;
839
864
  static const int JSON_float_error = 0;
@@ -841,7 +866,7 @@ static const int JSON_float_error = 0;
841
866
  static const int JSON_float_en_main = 1;
842
867
 
843
868
 
844
- #line 287 "parser.rl"
869
+ #line 312 "parser.rl"
845
870
 
846
871
 
847
872
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -849,15 +874,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
849
874
  int cs = EVIL;
850
875
 
851
876
 
852
- #line 853 "parser.c"
877
+ #line 878 "parser.c"
853
878
  {
854
879
  cs = JSON_float_start;
855
880
  }
856
881
 
857
- #line 294 "parser.rl"
882
+ #line 319 "parser.rl"
858
883
  json->memo = p;
859
884
 
860
- #line 861 "parser.c"
885
+ #line 886 "parser.c"
861
886
  {
862
887
  if ( p == pe )
863
888
  goto _test_eof;
@@ -915,14 +940,14 @@ case 5:
915
940
  goto st0;
916
941
  goto tr7;
917
942
  tr7:
918
- #line 281 "parser.rl"
943
+ #line 306 "parser.rl"
919
944
  { p--; {p++; cs = 10; goto _out;} }
920
945
  goto st10;
921
946
  st10:
922
947
  if ( ++p == pe )
923
948
  goto _test_eof10;
924
949
  case 10:
925
- #line 926 "parser.c"
950
+ #line 951 "parser.c"
926
951
  goto st0;
927
952
  st6:
928
953
  if ( ++p == pe )
@@ -983,7 +1008,7 @@ case 9:
983
1008
  _out: {}
984
1009
  }
985
1010
 
986
- #line 296 "parser.rl"
1011
+ #line 321 "parser.rl"
987
1012
 
988
1013
  if (cs >= JSON_float_first_final) {
989
1014
  long len = p - json->memo;
@@ -996,7 +1021,7 @@ case 9:
996
1021
 
997
1022
 
998
1023
 
999
- #line 1000 "parser.c"
1024
+ #line 1025 "parser.c"
1000
1025
  static const int JSON_array_start = 1;
1001
1026
  static const int JSON_array_first_final = 17;
1002
1027
  static const int JSON_array_error = 0;
@@ -1004,7 +1029,7 @@ static const int JSON_array_error = 0;
1004
1029
  static const int JSON_array_en_main = 1;
1005
1030
 
1006
1031
 
1007
- #line 332 "parser.rl"
1032
+ #line 357 "parser.rl"
1008
1033
 
1009
1034
 
1010
1035
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -1018,14 +1043,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
1018
1043
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1019
1044
 
1020
1045
 
1021
- #line 1022 "parser.c"
1046
+ #line 1047 "parser.c"
1022
1047
  {
1023
1048
  cs = JSON_array_start;
1024
1049
  }
1025
1050
 
1026
- #line 345 "parser.rl"
1051
+ #line 370 "parser.rl"
1027
1052
 
1028
- #line 1029 "parser.c"
1053
+ #line 1054 "parser.c"
1029
1054
  {
1030
1055
  if ( p == pe )
1031
1056
  goto _test_eof;
@@ -1064,7 +1089,7 @@ case 2:
1064
1089
  goto st2;
1065
1090
  goto st0;
1066
1091
  tr2:
1067
- #line 313 "parser.rl"
1092
+ #line 338 "parser.rl"
1068
1093
  {
1069
1094
  VALUE v = Qnil;
1070
1095
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -1080,7 +1105,7 @@ st3:
1080
1105
  if ( ++p == pe )
1081
1106
  goto _test_eof3;
1082
1107
  case 3:
1083
- #line 1084 "parser.c"
1108
+ #line 1109 "parser.c"
1084
1109
  switch( (*p) ) {
1085
1110
  case 13: goto st3;
1086
1111
  case 32: goto st3;
@@ -1180,14 +1205,14 @@ case 12:
1180
1205
  goto st3;
1181
1206
  goto st12;
1182
1207
  tr4:
1183
- #line 324 "parser.rl"
1208
+ #line 349 "parser.rl"
1184
1209
  { p--; {p++; cs = 17; goto _out;} }
1185
1210
  goto st17;
1186
1211
  st17:
1187
1212
  if ( ++p == pe )
1188
1213
  goto _test_eof17;
1189
1214
  case 17:
1190
- #line 1191 "parser.c"
1215
+ #line 1216 "parser.c"
1191
1216
  goto st0;
1192
1217
  st13:
1193
1218
  if ( ++p == pe )
@@ -1243,73 +1268,88 @@ case 16:
1243
1268
  _out: {}
1244
1269
  }
1245
1270
 
1246
- #line 346 "parser.rl"
1271
+ #line 371 "parser.rl"
1247
1272
 
1248
1273
  if(cs >= JSON_array_first_final) {
1249
1274
  return p + 1;
1250
1275
  } else {
1251
1276
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1277
+ return NULL;
1252
1278
  }
1253
1279
  }
1254
1280
 
1255
- static VALUE json_string_unescape(char *p, char *pe)
1281
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1256
1282
  {
1257
- VALUE result = rb_str_buf_new(pe - p + 1);
1258
-
1259
- while (p < pe) {
1260
- if (*p == '\\') {
1261
- p++;
1262
- if (p >= pe) return Qnil; /* raise an exception later, \ at end */
1263
- switch (*p) {
1283
+ char *p = string, *pe = string, *unescape;
1284
+ int unescape_len;
1285
+
1286
+ while (pe < stringEnd) {
1287
+ if (*pe == '\\') {
1288
+ unescape = (char *) "?";
1289
+ unescape_len = 1;
1290
+ if (pe > p) rb_str_buf_cat(result, p, pe - p);
1291
+ switch (*++pe) {
1292
+ case 'n':
1293
+ unescape = (char *) "\n";
1294
+ break;
1295
+ case 'r':
1296
+ unescape = (char *) "\r";
1297
+ break;
1298
+ case 't':
1299
+ unescape = (char *) "\t";
1300
+ break;
1264
1301
  case '"':
1302
+ unescape = (char *) "\"";
1303
+ break;
1265
1304
  case '\\':
1266
- rb_str_buf_cat(result, p, 1);
1267
- p++;
1305
+ unescape = (char *) "\\";
1268
1306
  break;
1269
1307
  case 'b':
1270
- rb_str_buf_cat2(result, "\b");
1271
- p++;
1308
+ unescape = (char *) "\b";
1272
1309
  break;
1273
1310
  case 'f':
1274
- rb_str_buf_cat2(result, "\f");
1275
- p++;
1276
- break;
1277
- case 'n':
1278
- rb_str_buf_cat2(result, "\n");
1279
- p++;
1280
- break;
1281
- case 'r':
1282
- rb_str_buf_cat2(result, "\r");
1283
- p++;
1284
- break;
1285
- case 't':
1286
- rb_str_buf_cat2(result, "\t");
1287
- p++;
1311
+ unescape = (char *) "\f";
1288
1312
  break;
1289
1313
  case 'u':
1290
- if (p > pe - 4) {
1314
+ if (pe > stringEnd - 4) {
1291
1315
  return Qnil;
1292
1316
  } else {
1293
- p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
1317
+ char buf[4];
1318
+ UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1319
+ pe += 3;
1320
+ if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1321
+ pe++;
1322
+ if (pe > stringEnd - 6) return Qnil;
1323
+ if (pe[0] == '\\' && pe[1] == 'u') {
1324
+ UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1325
+ ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1326
+ | (sur & 0x3FF));
1327
+ pe += 5;
1328
+ } else {
1329
+ unescape = (char *) "?";
1330
+ break;
1331
+ }
1332
+ }
1333
+ unescape_len = convert_UTF32_to_UTF8(buf, ch);
1334
+ unescape = buf;
1294
1335
  }
1295
1336
  break;
1296
1337
  default:
1297
- rb_str_buf_cat(result, p, 1);
1298
- p++;
1299
- break;
1338
+ p = pe;
1339
+ continue;
1300
1340
  }
1341
+ rb_str_buf_cat(result, unescape, unescape_len);
1342
+ p = ++pe;
1301
1343
  } else {
1302
- char *q = p;
1303
- while (*q != '\\' && q < pe) q++;
1304
- rb_str_buf_cat(result, p, q - p);
1305
- p = q;
1344
+ pe++;
1306
1345
  }
1307
1346
  }
1347
+ rb_str_buf_cat(result, p, pe - p);
1308
1348
  return result;
1309
1349
  }
1310
1350
 
1311
1351
 
1312
- #line 1313 "parser.c"
1352
+ #line 1353 "parser.c"
1313
1353
  static const int JSON_string_start = 1;
1314
1354
  static const int JSON_string_first_final = 8;
1315
1355
  static const int JSON_string_error = 0;
@@ -1317,24 +1357,24 @@ static const int JSON_string_error = 0;
1317
1357
  static const int JSON_string_en_main = 1;
1318
1358
 
1319
1359
 
1320
- #line 430 "parser.rl"
1360
+ #line 470 "parser.rl"
1321
1361
 
1322
1362
 
1323
1363
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1324
1364
  {
1325
1365
  int cs = EVIL;
1326
1366
 
1327
- *result = rb_str_new("", 0);
1367
+ *result = rb_str_buf_new(0);
1328
1368
 
1329
- #line 1330 "parser.c"
1369
+ #line 1370 "parser.c"
1330
1370
  {
1331
1371
  cs = JSON_string_start;
1332
1372
  }
1333
1373
 
1334
- #line 438 "parser.rl"
1374
+ #line 478 "parser.rl"
1335
1375
  json->memo = p;
1336
1376
 
1337
- #line 1338 "parser.c"
1377
+ #line 1378 "parser.c"
1338
1378
  {
1339
1379
  if ( p == pe )
1340
1380
  goto _test_eof;
@@ -1359,25 +1399,25 @@ case 2:
1359
1399
  goto st0;
1360
1400
  goto st2;
1361
1401
  tr2:
1362
- #line 416 "parser.rl"
1402
+ #line 456 "parser.rl"
1363
1403
  {
1364
- *result = json_string_unescape(json->memo + 1, p);
1365
- if (NIL_P(*result)) {
1366
- p--;
1367
- {p++; cs = 8; goto _out;}
1368
- } else {
1369
- FORCE_UTF8(*result);
1370
- {p = (( p + 1))-1;}
1371
- }
1372
- }
1373
- #line 427 "parser.rl"
1404
+ *result = json_string_unescape(*result, json->memo + 1, p);
1405
+ if (NIL_P(*result)) {
1406
+ p--;
1407
+ {p++; cs = 8; goto _out;}
1408
+ } else {
1409
+ FORCE_UTF8(*result);
1410
+ {p = (( p + 1))-1;}
1411
+ }
1412
+ }
1413
+ #line 467 "parser.rl"
1374
1414
  { p--; {p++; cs = 8; goto _out;} }
1375
1415
  goto st8;
1376
1416
  st8:
1377
1417
  if ( ++p == pe )
1378
1418
  goto _test_eof8;
1379
1419
  case 8:
1380
- #line 1381 "parser.c"
1420
+ #line 1421 "parser.c"
1381
1421
  goto st0;
1382
1422
  st3:
1383
1423
  if ( ++p == pe )
@@ -1453,7 +1493,7 @@ case 7:
1453
1493
  _out: {}
1454
1494
  }
1455
1495
 
1456
- #line 440 "parser.rl"
1496
+ #line 480 "parser.rl"
1457
1497
 
1458
1498
  if (json->symbolize_names && json->parsing_name) {
1459
1499
  *result = rb_str_intern(*result);
@@ -1467,7 +1507,7 @@ case 7:
1467
1507
 
1468
1508
 
1469
1509
 
1470
- #line 1471 "parser.c"
1510
+ #line 1511 "parser.c"
1471
1511
  static const int JSON_start = 1;
1472
1512
  static const int JSON_first_final = 10;
1473
1513
  static const int JSON_error = 0;
@@ -1475,7 +1515,7 @@ static const int JSON_error = 0;
1475
1515
  static const int JSON_en_main = 1;
1476
1516
 
1477
1517
 
1478
- #line 477 "parser.rl"
1518
+ #line 517 "parser.rl"
1479
1519
 
1480
1520
 
1481
1521
  /*
@@ -1490,7 +1530,7 @@ static const int JSON_en_main = 1;
1490
1530
  *
1491
1531
  */
1492
1532
 
1493
- inline static VALUE convert_encoding(VALUE source)
1533
+ static VALUE convert_encoding(VALUE source)
1494
1534
  {
1495
1535
  char *ptr = RSTRING_PTR(source);
1496
1536
  long len = RSTRING_LEN(source);
@@ -1500,28 +1540,28 @@ inline static VALUE convert_encoding(VALUE source)
1500
1540
  #ifdef HAVE_RUBY_ENCODING_H
1501
1541
  {
1502
1542
  VALUE encoding = rb_funcall(source, i_encoding, 0);
1503
- if (encoding == mEncoding_ASCII_8BIT) {
1543
+ if (encoding == CEncoding_ASCII_8BIT) {
1504
1544
  if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1505
1545
  source = rb_str_dup(source);
1506
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32BE);
1507
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1546
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
1547
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1508
1548
  } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1509
1549
  source = rb_str_dup(source);
1510
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16BE);
1511
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1550
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
1551
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1512
1552
  } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1513
1553
  source = rb_str_dup(source);
1514
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32LE);
1515
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1554
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
1555
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1516
1556
  } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1517
1557
  source = rb_str_dup(source);
1518
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16LE);
1519
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1558
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
1559
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1520
1560
  } else {
1521
- source = rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_8);
1561
+ FORCE_UTF8(source);
1522
1562
  }
1523
1563
  } else {
1524
- source = rb_funcall(source, i_encode, 1, mEncoding_UTF_8);
1564
+ source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
1525
1565
  }
1526
1566
  }
1527
1567
  #else
@@ -1569,7 +1609,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1569
1609
  char *ptr;
1570
1610
  long len;
1571
1611
  VALUE source, opts;
1572
- GET_STRUCT;
1612
+ GET_PARSER;
1573
1613
  rb_scan_args(argc, argv, "11", &source, &opts);
1574
1614
  source = convert_encoding(StringValue(source));
1575
1615
  ptr = RSTRING_PTR(source);
@@ -1654,19 +1694,19 @@ static VALUE cParser_parse(VALUE self)
1654
1694
  char *p, *pe;
1655
1695
  int cs = EVIL;
1656
1696
  VALUE result = Qnil;
1657
- GET_STRUCT;
1697
+ GET_PARSER;
1658
1698
 
1659
1699
 
1660
- #line 1661 "parser.c"
1700
+ #line 1701 "parser.c"
1661
1701
  {
1662
1702
  cs = JSON_start;
1663
1703
  }
1664
1704
 
1665
- #line 658 "parser.rl"
1705
+ #line 698 "parser.rl"
1666
1706
  p = json->source;
1667
1707
  pe = p + json->len;
1668
1708
 
1669
- #line 1670 "parser.c"
1709
+ #line 1710 "parser.c"
1670
1710
  {
1671
1711
  if ( p == pe )
1672
1712
  goto _test_eof;
@@ -1722,7 +1762,7 @@ case 5:
1722
1762
  goto st1;
1723
1763
  goto st5;
1724
1764
  tr3:
1725
- #line 466 "parser.rl"
1765
+ #line 506 "parser.rl"
1726
1766
  {
1727
1767
  char *np;
1728
1768
  json->current_nesting = 1;
@@ -1731,7 +1771,7 @@ tr3:
1731
1771
  }
1732
1772
  goto st10;
1733
1773
  tr4:
1734
- #line 459 "parser.rl"
1774
+ #line 499 "parser.rl"
1735
1775
  {
1736
1776
  char *np;
1737
1777
  json->current_nesting = 1;
@@ -1743,7 +1783,7 @@ st10:
1743
1783
  if ( ++p == pe )
1744
1784
  goto _test_eof10;
1745
1785
  case 10:
1746
- #line 1747 "parser.c"
1786
+ #line 1787 "parser.c"
1747
1787
  switch( (*p) ) {
1748
1788
  case 13: goto st10;
1749
1789
  case 32: goto st10;
@@ -1800,16 +1840,17 @@ case 9:
1800
1840
  _out: {}
1801
1841
  }
1802
1842
 
1803
- #line 661 "parser.rl"
1843
+ #line 701 "parser.rl"
1804
1844
 
1805
1845
  if (cs >= JSON_first_final && p == pe) {
1806
1846
  return result;
1807
1847
  } else {
1808
1848
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1849
+ return Qnil;
1809
1850
  }
1810
1851
  }
1811
1852
 
1812
- inline static JSON_Parser *JSON_allocate()
1853
+ static JSON_Parser *JSON_allocate()
1813
1854
  {
1814
1855
  JSON_Parser *json = ALLOC(JSON_Parser);
1815
1856
  MEMZERO(json, JSON_Parser, 1);
@@ -1843,7 +1884,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
1843
1884
  */
1844
1885
  static VALUE cParser_source(VALUE self)
1845
1886
  {
1846
- GET_STRUCT;
1887
+ GET_PARSER;
1847
1888
  return rb_str_dup(json->Vsource);
1848
1889
  }
1849
1890
 
@@ -1877,12 +1918,12 @@ void Init_parser()
1877
1918
  i_key_p = rb_intern("key?");
1878
1919
  i_deep_const_get = rb_intern("deep_const_get");
1879
1920
  #ifdef HAVE_RUBY_ENCODING_H
1880
- mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1881
- mEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
1882
- mEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
1883
- mEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
1884
- mEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
1885
- mEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
1921
+ CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1922
+ CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
1923
+ CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
1924
+ CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
1925
+ CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
1926
+ CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
1886
1927
  i_encoding = rb_intern("encoding");
1887
1928
  i_encode = rb_intern("encode");
1888
1929
  i_encode_bang = rb_intern("encode!");