json 1.2.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

@@ -0,0 +1,71 @@
1
+ #ifndef _PARSER_H_
2
+ #define _PARSER_H_
3
+
4
+ #include "ruby.h"
5
+
6
+ #if HAVE_RE_H
7
+ #include "re.h"
8
+ #endif
9
+
10
+ #ifdef HAVE_RUBY_ENCODING_H
11
+ #include "ruby/encoding.h"
12
+ #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
13
+ #else
14
+ #define FORCE_UTF8(obj)
15
+ #endif
16
+
17
+ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
18
+
19
+ /* unicode */
20
+
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 */
24
+
25
+ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
26
+ #define UNI_SUR_HIGH_START (UTF32)0xD800
27
+ #define UNI_SUR_HIGH_END (UTF32)0xDBFF
28
+ #define UNI_SUR_LOW_START (UTF32)0xDC00
29
+ #define UNI_SUR_LOW_END (UTF32)0xDFFF
30
+
31
+ typedef struct JSON_ParserStruct {
32
+ VALUE Vsource;
33
+ char *source;
34
+ long len;
35
+ char *memo;
36
+ VALUE create_id;
37
+ int max_nesting;
38
+ int current_nesting;
39
+ int allow_nan;
40
+ int parsing_name;
41
+ int symbolize_names;
42
+ VALUE object_class;
43
+ VALUE array_class;
44
+ } JSON_Parser;
45
+
46
+ #define GET_PARSER \
47
+ JSON_Parser *json; \
48
+ Data_Get_Struct(self, JSON_Parser, json)
49
+
50
+ #define MinusInfinity "-Infinity"
51
+ #define EVIL 0x666
52
+
53
+ static UTF32 unescape_unicode(const unsigned char *p);
54
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
55
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
56
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
57
+ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
58
+ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
59
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
60
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
61
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
62
+ static VALUE convert_encoding(VALUE source);
63
+ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
64
+ static VALUE cParser_parse(VALUE self);
65
+ static JSON_Parser *JSON_allocate();
66
+ static void JSON_mark(JSON_Parser *json);
67
+ static void JSON_free(JSON_Parser *json);
68
+ static VALUE cJSON_parser_s_allocate(VALUE klass);
69
+ static VALUE cParser_source(VALUE self);
70
+
71
+ #endif
@@ -1,21 +1,74 @@
1
- #include "ruby.h"
2
- #include "unicode.h"
3
- #if HAVE_RE_H
4
- #include "re.h"
5
- #endif
6
-
7
- #define EVIL 0x666
1
+ #include "parser.h"
2
+
3
+ /* unicode */
4
+
5
+ static const char digit_values[256] = {
6
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
7
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
9
+ -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
10
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
11
+ 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -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
+ -1, -1, -1, -1, -1, -1, -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
20
+ };
21
+
22
+ static UTF32 unescape_unicode(const unsigned char *p)
23
+ {
24
+ char b;
25
+ UTF32 result = 0;
26
+ b = digit_values[p[0]];
27
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
28
+ result = (result << 4) | b;
29
+ b = digit_values[p[1]];
30
+ result = (result << 4) | b;
31
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
32
+ b = digit_values[p[2]];
33
+ result = (result << 4) | b;
34
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
35
+ b = digit_values[p[3]];
36
+ result = (result << 4) | b;
37
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
38
+ return result;
39
+ }
8
40
 
9
- #define option_given_p(opts, key) RTEST(rb_funcall((opts), i_key_p, 1, (key)))
41
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
42
+ {
43
+ int len = 1;
44
+ if (ch <= 0x7F) {
45
+ buf[0] = (char) ch;
46
+ } else if (ch <= 0x07FF) {
47
+ buf[0] = (char) ((ch >> 6) | 0xC0);
48
+ buf[1] = (char) ((ch & 0x3F) | 0x80);
49
+ len++;
50
+ } else if (ch <= 0xFFFF) {
51
+ buf[0] = (char) ((ch >> 12) | 0xE0);
52
+ buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
53
+ buf[2] = (char) ((ch & 0x3F) | 0x80);
54
+ len += 2;
55
+ } else if (ch <= 0x1fffff) {
56
+ buf[0] =(char) ((ch >> 18) | 0xF0);
57
+ buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
58
+ buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
59
+ buf[3] =(char) ((ch & 0x3F) | 0x80);
60
+ len += 3;
61
+ } else {
62
+ buf[0] = '?';
63
+ }
64
+ return len;
65
+ }
10
66
 
11
67
  #ifdef HAVE_RUBY_ENCODING_H
12
- #include "ruby/encoding.h"
13
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
14
- static VALUE mEncoding_ASCII_8BIT, mEncoding_UTF_8, mEncoding_UTF_16BE,
15
- mEncoding_UTF_16LE, mEncoding_UTF_32BE, mEncoding_UTF_32LE;
68
+ static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
69
+ CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
16
70
  static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
17
71
  #else
18
- #define FORCE_UTF8(obj)
19
72
  static ID i_iconv;
20
73
  #endif
21
74
 
@@ -26,34 +79,6 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
26
79
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
27
80
  i_array_class, i_key_p, i_deep_const_get;
28
81
 
29
- #define MinusInfinity "-Infinity"
30
-
31
- typedef struct JSON_ParserStruct {
32
- VALUE Vsource;
33
- char *source;
34
- long len;
35
- char *memo;
36
- VALUE create_id;
37
- int max_nesting;
38
- int current_nesting;
39
- int allow_nan;
40
- int parsing_name;
41
- int symbolize_names;
42
- VALUE object_class;
43
- VALUE array_class;
44
- } JSON_Parser;
45
-
46
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
47
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
48
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
49
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
50
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
51
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
52
-
53
- #define GET_STRUCT \
54
- JSON_Parser *json; \
55
- Data_Get_Struct(self, JSON_Parser, json);
56
-
57
82
  %%{
58
83
  machine JSON_common;
59
84
 
@@ -348,62 +373,77 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
348
373
  return p + 1;
349
374
  } else {
350
375
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
376
+ return NULL;
351
377
  }
352
378
  }
353
379
 
354
- static VALUE json_string_unescape(char *p, char *pe)
380
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
355
381
  {
356
- VALUE result = rb_str_buf_new(pe - p + 1);
357
-
358
- while (p < pe) {
359
- if (*p == '\\') {
360
- p++;
361
- if (p >= pe) return Qnil; /* raise an exception later, \ at end */
362
- switch (*p) {
382
+ char *p = string, *pe = string, *unescape;
383
+ int unescape_len;
384
+
385
+ while (pe < stringEnd) {
386
+ if (*pe == '\\') {
387
+ unescape = (char *) "?";
388
+ unescape_len = 1;
389
+ if (pe > p) rb_str_buf_cat(result, p, pe - p);
390
+ switch (*++pe) {
391
+ case 'n':
392
+ unescape = (char *) "\n";
393
+ break;
394
+ case 'r':
395
+ unescape = (char *) "\r";
396
+ break;
397
+ case 't':
398
+ unescape = (char *) "\t";
399
+ break;
363
400
  case '"':
401
+ unescape = (char *) "\"";
402
+ break;
364
403
  case '\\':
365
- rb_str_buf_cat(result, p, 1);
366
- p++;
404
+ unescape = (char *) "\\";
367
405
  break;
368
406
  case 'b':
369
- rb_str_buf_cat2(result, "\b");
370
- p++;
407
+ unescape = (char *) "\b";
371
408
  break;
372
409
  case 'f':
373
- rb_str_buf_cat2(result, "\f");
374
- p++;
375
- break;
376
- case 'n':
377
- rb_str_buf_cat2(result, "\n");
378
- p++;
379
- break;
380
- case 'r':
381
- rb_str_buf_cat2(result, "\r");
382
- p++;
383
- break;
384
- case 't':
385
- rb_str_buf_cat2(result, "\t");
386
- p++;
410
+ unescape = (char *) "\f";
387
411
  break;
388
412
  case 'u':
389
- if (p > pe - 4) {
413
+ if (pe > stringEnd - 4) {
390
414
  return Qnil;
391
415
  } else {
392
- p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
416
+ char buf[4];
417
+ UTF32 ch = unescape_unicode((unsigned char *) ++pe);
418
+ pe += 3;
419
+ if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
420
+ pe++;
421
+ if (pe > stringEnd - 6) return Qnil;
422
+ if (pe[0] == '\\' && pe[1] == 'u') {
423
+ UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
424
+ ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
425
+ | (sur & 0x3FF));
426
+ pe += 5;
427
+ } else {
428
+ unescape = (char *) "?";
429
+ break;
430
+ }
431
+ }
432
+ unescape_len = convert_UTF32_to_UTF8(buf, ch);
433
+ unescape = buf;
393
434
  }
394
435
  break;
395
436
  default:
396
- rb_str_buf_cat(result, p, 1);
397
- p++;
398
- break;
437
+ p = pe;
438
+ continue;
399
439
  }
440
+ rb_str_buf_cat(result, unescape, unescape_len);
441
+ p = ++pe;
400
442
  } else {
401
- char *q = p;
402
- while (*q != '\\' && q < pe) q++;
403
- rb_str_buf_cat(result, p, q - p);
404
- p = q;
443
+ pe++;
405
444
  }
406
445
  }
446
+ rb_str_buf_cat(result, p, pe - p);
407
447
  return result;
408
448
  }
409
449
 
@@ -414,15 +454,15 @@ static VALUE json_string_unescape(char *p, char *pe)
414
454
  write data;
415
455
 
416
456
  action parse_string {
417
- *result = json_string_unescape(json->memo + 1, p);
418
- if (NIL_P(*result)) {
419
- fhold;
420
- fbreak;
421
- } else {
422
- FORCE_UTF8(*result);
423
- fexec p + 1;
424
- }
425
- }
457
+ *result = json_string_unescape(*result, json->memo + 1, p);
458
+ if (NIL_P(*result)) {
459
+ fhold;
460
+ fbreak;
461
+ } else {
462
+ FORCE_UTF8(*result);
463
+ fexec p + 1;
464
+ }
465
+ }
426
466
 
427
467
  action exit { fhold; fbreak; }
428
468
 
@@ -433,7 +473,7 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
433
473
  {
434
474
  int cs = EVIL;
435
475
 
436
- *result = rb_str_new("", 0);
476
+ *result = rb_str_buf_new(0);
437
477
  %% write init;
438
478
  json->memo = p;
439
479
  %% write exec;
@@ -488,7 +528,7 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
488
528
  *
489
529
  */
490
530
 
491
- inline static VALUE convert_encoding(VALUE source)
531
+ static VALUE convert_encoding(VALUE source)
492
532
  {
493
533
  char *ptr = RSTRING_PTR(source);
494
534
  long len = RSTRING_LEN(source);
@@ -498,28 +538,28 @@ inline static VALUE convert_encoding(VALUE source)
498
538
  #ifdef HAVE_RUBY_ENCODING_H
499
539
  {
500
540
  VALUE encoding = rb_funcall(source, i_encoding, 0);
501
- if (encoding == mEncoding_ASCII_8BIT) {
541
+ if (encoding == CEncoding_ASCII_8BIT) {
502
542
  if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
503
543
  source = rb_str_dup(source);
504
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32BE);
505
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
544
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
545
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
506
546
  } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
507
547
  source = rb_str_dup(source);
508
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16BE);
509
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
548
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
549
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
510
550
  } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
511
551
  source = rb_str_dup(source);
512
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32LE);
513
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
552
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
553
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
514
554
  } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
515
555
  source = rb_str_dup(source);
516
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16LE);
517
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
556
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
557
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
518
558
  } else {
519
- source = rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_8);
559
+ FORCE_UTF8(source);
520
560
  }
521
561
  } else {
522
- source = rb_funcall(source, i_encode, 1, mEncoding_UTF_8);
562
+ source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
523
563
  }
524
564
  }
525
565
  #else
@@ -567,7 +607,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
567
607
  char *ptr;
568
608
  long len;
569
609
  VALUE source, opts;
570
- GET_STRUCT;
610
+ GET_PARSER;
571
611
  rb_scan_args(argc, argv, "11", &source, &opts);
572
612
  source = convert_encoding(StringValue(source));
573
613
  ptr = RSTRING_PTR(source);
@@ -652,7 +692,7 @@ static VALUE cParser_parse(VALUE self)
652
692
  char *p, *pe;
653
693
  int cs = EVIL;
654
694
  VALUE result = Qnil;
655
- GET_STRUCT;
695
+ GET_PARSER;
656
696
 
657
697
  %% write init;
658
698
  p = json->source;
@@ -663,10 +703,11 @@ static VALUE cParser_parse(VALUE self)
663
703
  return result;
664
704
  } else {
665
705
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
706
+ return Qnil;
666
707
  }
667
708
  }
668
709
 
669
- inline static JSON_Parser *JSON_allocate()
710
+ static JSON_Parser *JSON_allocate()
670
711
  {
671
712
  JSON_Parser *json = ALLOC(JSON_Parser);
672
713
  MEMZERO(json, JSON_Parser, 1);
@@ -700,7 +741,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
700
741
  */
701
742
  static VALUE cParser_source(VALUE self)
702
743
  {
703
- GET_STRUCT;
744
+ GET_PARSER;
704
745
  return rb_str_dup(json->Vsource);
705
746
  }
706
747
 
@@ -734,12 +775,12 @@ void Init_parser()
734
775
  i_key_p = rb_intern("key?");
735
776
  i_deep_const_get = rb_intern("deep_const_get");
736
777
  #ifdef HAVE_RUBY_ENCODING_H
737
- mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
738
- mEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
739
- mEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
740
- mEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
741
- mEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
742
- mEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
778
+ CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
779
+ CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
780
+ CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
781
+ CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
782
+ CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
783
+ CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
743
784
  i_encoding = rb_intern("encoding");
744
785
  i_encode = rb_intern("encode");
745
786
  i_encode_bang = rb_intern("encode!");
@@ -63,6 +63,20 @@ module JSON
63
63
  end
64
64
  self.state = generator::State
65
65
  const_set :State, self.state
66
+ const_set :SAFE_STATE_PROTOTYPE, State.new.freeze
67
+ const_set :FAST_STATE_PROTOTYPE, State.new(
68
+ :indent => '',
69
+ :space => '',
70
+ :object_nl => "",
71
+ :array_nl => "",
72
+ :max_nesting => false
73
+ ).freeze
74
+ const_set :PRETTY_STATE_PROTOTYPE, State.new(
75
+ :indent => ' ',
76
+ :space => ' ',
77
+ :object_nl => "\n",
78
+ :array_nl => "\n"
79
+ ).freeze
66
80
  end
67
81
 
68
82
  # Returns the JSON generator modul, that is used by JSON. This might be
@@ -95,15 +109,15 @@ module JSON
95
109
  # deep.
96
110
  class NestingError < ParserError; end
97
111
 
112
+ # :stopdoc:
113
+ class CircularDatastructure < NestingError; end
114
+ # :startdoc:
115
+
98
116
  # This exception is raised, if a generator or unparser error occurs.
99
117
  class GeneratorError < JSONError; end
100
118
  # For backwards compatibility
101
119
  UnparserError = GeneratorError
102
120
 
103
- # If a circular data structure is encountered while unparsing
104
- # this exception is raised.
105
- class CircularDatastructure < GeneratorError; end
106
-
107
121
  # This exception is raised, if the required unicode support is missing on the
108
122
  # system. Usually this means, that the iconv library is not installed.
109
123
  class MissingUnicodeSupport < JSONError; end
@@ -129,7 +143,7 @@ module JSON
129
143
  # * *object_class*: Defaults to Hash
130
144
  # * *array_class*: Defaults to Array
131
145
  def parse(source, opts = {})
132
- JSON.parser.new(source, opts).parse
146
+ Parser.new(source, opts).parse
133
147
  end
134
148
 
135
149
  # Parse the JSON document _source_ into a Ruby data structure and return it.
@@ -149,10 +163,10 @@ module JSON
149
163
  # defaults to true.
150
164
  def parse!(source, opts = {})
151
165
  opts = {
152
- :max_nesting => false,
153
- :allow_nan => true
166
+ :max_nesting => false,
167
+ :allow_nan => true
154
168
  }.update(opts)
155
- JSON.parser.new(source, opts).parse
169
+ Parser.new(source, opts).parse
156
170
  end
157
171
 
158
172
  # Generate a JSON document from the Ruby data structure _obj_ and return
@@ -171,8 +185,6 @@ module JSON
171
185
  # * *space_before*: a string that is put before a : pair delimiter (default: ''),
172
186
  # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
173
187
  # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
174
- # * *check_circular*: true if checking for circular data structures
175
- # should be done (the default), false otherwise.
176
188
  # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
177
189
  # generated, otherwise an exception is thrown, if these values are
178
190
  # encountered. This options defaults to false.
@@ -183,17 +195,21 @@ module JSON
183
195
  # See also the fast_generate for the fastest creation method with the least
184
196
  # amount of sanity checks, and the pretty_generate method for some
185
197
  # defaults for a pretty output.
186
- def generate(obj, state = nil)
187
- if state
188
- state = State.from_state(state)
198
+ def generate(obj, opts = nil)
199
+ if opts
200
+ if opts.respond_to? :to_hash
201
+ opts = opts.to_hash
202
+ elsif opts.respond_to? :to_h
203
+ opts = opts.to_h
204
+ else
205
+ raise TypeError, "can't convert #{opts.class} into Hash"
206
+ end
207
+ state = SAFE_STATE_PROTOTYPE.dup
208
+ state = state.configure(opts)
189
209
  else
190
- state = State.new
191
- end
192
- result = obj.to_json(state)
193
- if result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
194
- raise GeneratorError, "only generation of JSON objects or arrays allowed"
210
+ state = SAFE_STATE_PROTOTYPE
195
211
  end
196
- result
212
+ state.generate(obj)
197
213
  end
198
214
 
199
215
  # :stopdoc:
@@ -208,12 +224,21 @@ module JSON
208
224
  #
209
225
  # *WARNING*: Be careful not to pass any Ruby data structures with circles as
210
226
  # _obj_ argument, because this will cause JSON to go into an infinite loop.
211
- def fast_generate(obj)
212
- result = obj.to_json(nil)
213
- if result !~ /\A(?:\[.*\]|\{.*\})\Z/
214
- raise GeneratorError, "only generation of JSON objects or arrays allowed"
227
+ def fast_generate(obj, opts = nil)
228
+ if opts
229
+ if opts.respond_to? :to_hash
230
+ opts = opts.to_hash
231
+ elsif opts.respond_to? :to_h
232
+ opts = opts.to_h
233
+ else
234
+ raise TypeError, "can't convert #{opts.class} into Hash"
235
+ end
236
+ state = FAST_STATE_PROTOTYPE.dup
237
+ state.configure(opts)
238
+ else
239
+ state = FAST_STATE_PROTOTYPE
215
240
  end
216
- result
241
+ state.generate(obj)
217
242
  end
218
243
 
219
244
  # :stopdoc:
@@ -229,13 +254,6 @@ module JSON
229
254
  # The _opts_ argument can be used to configure the generator, see the
230
255
  # generate method for a more detailed explanation.
231
256
  def pretty_generate(obj, opts = nil)
232
- state = JSON.state.new(
233
- :indent => ' ',
234
- :space => ' ',
235
- :object_nl => "\n",
236
- :array_nl => "\n",
237
- :check_circular => true
238
- )
239
257
  if opts
240
258
  if opts.respond_to? :to_hash
241
259
  opts = opts.to_hash
@@ -244,13 +262,12 @@ module JSON
244
262
  else
245
263
  raise TypeError, "can't convert #{opts.class} into Hash"
246
264
  end
265
+ state = PRETTY_STATE_PROTOTYPE.dup
247
266
  state.configure(opts)
267
+ else
268
+ state = PRETTY_STATE_PROTOTYPE
248
269
  end
249
- result = obj.to_json(state)
250
- if result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
251
- raise GeneratorError, "only generation of JSON objects or arrays allowed"
252
- end
253
- result
270
+ state.generate(obj)
254
271
  end
255
272
 
256
273
  # :stopdoc: