json 1.4.3 → 1.4.4

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.

data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ 2010-08-06 (1.4.4)
2
+ * Fixes build problem for rubinius under OS X, http://github.com/flori/json/issues/closed#issue/25
3
+ * Fixes crashes described in http://github.com/flori/json/issues/closed#issue/21 and
4
+ http://github.com/flori/json/issues/closed#issue/23
1
5
  2010-05-05 (1.4.3)
2
6
  * Fixed some test assertions, from Ruby r27587 and r27590, patch by nobu.
3
7
  * Fixed issue http://github.com/flori/json/issues/#issue/20 reported by
data/README CHANGED
@@ -11,13 +11,11 @@ will be two variants available:
11
11
  generated by the ragel state machine compiler
12
12
  http://www.cs.queensu.ca/~thurston/ragel .
13
13
 
14
- Both variants of the JSON generator escape all non-ASCII and control characters
15
- with \uXXXX escape sequences, and support UTF-16 surrogate pairs in order to be
16
- able to generate the whole range of unicode code points. This means that
17
- generated JSON document is encoded as UTF-8 (because ASCII is a subset of
18
- UTF-8) and at the same time avoids decoding problems for receiving endpoints,
19
- that don't expect UTF-8 encoded texts. On the negative side this may lead to a
20
- bit longer strings than necessarry.
14
+ Both variants of the JSON generator generate UTF-8 character sequences by
15
+ default. If an :ascii_only option with a true value is given, they escape all
16
+ non-ASCII and control characters with \uXXXX escape sequences, and support
17
+ UTF-16 surrogate pairs in order to be able to generate the whole range of
18
+ unicode code points.
21
19
 
22
20
  All strings, that are to be encoded as JSON strings, should be UTF-8 byte
23
21
  sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8
data/Rakefile CHANGED
@@ -174,7 +174,7 @@ task :benchmark => [ :benchmark_parser, :benchmark_generator ]
174
174
 
175
175
  desc "Create RDOC documentation"
176
176
  task :doc => [ :version, EXT_PARSER_SRC ] do
177
- sh "rdoc -o doc -t '#{PKG_TITLE}' -m README README lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}"
177
+ sh "sdoc -o doc -t '#{PKG_TITLE}' -m README README lib/json.rb #{FileList['lib/json/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}"
178
178
  end
179
179
 
180
180
  if defined?(Gem) and defined?(Rake::GemPackageTask)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.3
1
+ 1.4.4
@@ -11,6 +11,10 @@ if CONFIG['CC'] =~ /gcc/
11
11
  #end
12
12
  end
13
13
 
14
- have_header("ruby/re.h") || have_header("re.h")
15
- have_header("ruby/encoding.h")
14
+ if RUBY_VERSION < "1.9"
15
+ have_header("re.h")
16
+ else
17
+ have_header("ruby/re.h")
18
+ have_header("ruby/encoding.h")
19
+ end
16
20
  create_makefile 'json/ext/generator'
@@ -6,14 +6,15 @@ static ID i_encoding, i_encode;
6
6
  #endif
7
7
 
8
8
  static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
9
- mHash, mArray, mInteger, mFloat, mString, mString_Extend,
9
+ mHash, mArray, mFixnum, mBignum, mFloat, mString, mString_Extend,
10
10
  mTrueClass, mFalseClass, mNilClass, eGeneratorError,
11
- eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE;
11
+ eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
12
+ i_SAFE_STATE_PROTOTYPE;
12
13
 
13
14
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
14
15
  i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
15
16
  i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send,
16
- i_respond_to_p, i_match;
17
+ i_respond_to_p, i_match, i_keys;
17
18
 
18
19
  /*
19
20
  * Copyright 2001-2004 Unicode, Inc.
@@ -339,7 +340,7 @@ static void fbuffer_inc_capa(FBuffer *fb, unsigned int requested)
339
340
  for (required = fb->capa; requested > required - fb->len; required <<= 1);
340
341
 
341
342
  if (required > fb->capa) {
342
- fb->ptr = (char *) REALLOC_N((long*) fb->ptr, char, required);
343
+ REALLOC_N(fb->ptr, char, required);
343
344
  fb->capa = required;
344
345
  }
345
346
  }
@@ -426,11 +427,7 @@ static FBuffer *fbuffer_dup(FBuffer *fb)
426
427
  */
427
428
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
428
429
  {
429
- VALUE state, depth;
430
-
431
- rb_scan_args(argc, argv, "02", &state, &depth);
432
- state = cState_from_state_s(cState, state);
433
- return cState_partial_generate(state, self, depth);
430
+ GENERATE_JSON(object);
434
431
  }
435
432
 
436
433
  /*
@@ -443,10 +440,7 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
443
440
  * _depth_ is used to find out nesting depth, to indent accordingly.
444
441
  */
445
442
  static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
446
- VALUE state, depth;
447
- rb_scan_args(argc, argv, "02", &state, &depth);
448
- state = cState_from_state_s(cState, state);
449
- return cState_partial_generate(state, self, depth);
443
+ GENERATE_JSON(array);
450
444
  }
451
445
 
452
446
  /*
@@ -454,12 +448,19 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
454
448
  *
455
449
  * Returns a JSON string representation for this Integer number.
456
450
  */
457
- static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
451
+ static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
458
452
  {
459
- VALUE state, depth;
460
- rb_scan_args(argc, argv, "02", &state, &depth);
461
- state = cState_from_state_s(cState, state);
462
- return cState_partial_generate(state, self, depth);
453
+ GENERATE_JSON(fixnum);
454
+ }
455
+
456
+ /*
457
+ * call-seq: to_json(*)
458
+ *
459
+ * Returns a JSON string representation for this Integer number.
460
+ */
461
+ static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
462
+ {
463
+ GENERATE_JSON(bignum);
463
464
  }
464
465
 
465
466
  /*
@@ -469,10 +470,7 @@ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
469
470
  */
470
471
  static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
471
472
  {
472
- VALUE state, depth;
473
- rb_scan_args(argc, argv, "02", &state, &depth);
474
- state = cState_from_state_s(cState, state);
475
- return cState_partial_generate(state, self, depth);
473
+ GENERATE_JSON(float);
476
474
  }
477
475
 
478
476
  /*
@@ -494,10 +492,7 @@ static VALUE mString_included_s(VALUE self, VALUE modul) {
494
492
  */
495
493
  static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
496
494
  {
497
- VALUE state, depth;
498
- rb_scan_args(argc, argv, "02", &state, &depth);
499
- state = cState_from_state_s(cState, state);
500
- return cState_partial_generate(state, self, depth);
495
+ GENERATE_JSON(string);
501
496
  }
502
497
 
503
498
  /*
@@ -552,10 +547,7 @@ static VALUE mString_Extend_json_create(VALUE self, VALUE o)
552
547
  */
553
548
  static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
554
549
  {
555
- VALUE state, depth;
556
- rb_scan_args(argc, argv, "02", &state, &depth);
557
- state = cState_from_state_s(cState, state);
558
- return cState_partial_generate(state, self, depth);
550
+ GENERATE_JSON(true);
559
551
  }
560
552
 
561
553
  /*
@@ -565,10 +557,7 @@ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
565
557
  */
566
558
  static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
567
559
  {
568
- VALUE state, depth;
569
- rb_scan_args(argc, argv, "02", &state, &depth);
570
- state = cState_from_state_s(cState, state);
571
- return cState_partial_generate(state, self, depth);
560
+ GENERATE_JSON(false);
572
561
  }
573
562
 
574
563
  /*
@@ -577,10 +566,7 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
577
566
  */
578
567
  static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
579
568
  {
580
- VALUE state, depth;
581
- rb_scan_args(argc, argv, "02", &state, &depth);
582
- state = cState_from_state_s(cState, state);
583
- return cState_partial_generate(state, self, depth);
569
+ GENERATE_JSON(null);
584
570
  }
585
571
 
586
572
  /*
@@ -616,6 +602,7 @@ static void State_free(JSON_Generator_State *state)
616
602
  static JSON_Generator_State *State_allocate()
617
603
  {
618
604
  JSON_Generator_State *state = ALLOC(JSON_Generator_State);
605
+ MEMZERO(state, JSON_Generator_State, 1);
619
606
  return state;
620
607
  }
621
608
 
@@ -735,127 +722,172 @@ static VALUE cState_aref(VALUE self, VALUE name)
735
722
  }
736
723
  }
737
724
 
738
- static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
725
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
739
726
  {
740
- VALUE tmp;
741
- VALUE klass = CLASS_OF(obj);
742
- if (klass == rb_cHash) {
743
- char *object_nl = state->object_nl;
744
- long object_nl_len = state->object_nl_len;
745
- char *indent = state->indent;
746
- long indent_len = state->indent_len;
747
- long max_nesting = state->max_nesting;
748
- char *delim = FBUFFER_PTR(state->object_delim);
749
- long delim_len = FBUFFER_LEN(state->object_delim);
750
- char *delim2 = FBUFFER_PTR(state->object_delim2);
751
- long delim2_len = FBUFFER_LEN(state->object_delim2);
752
- int i, j;
753
- VALUE key, key_to_s, keys;
754
- depth++;
755
- if (max_nesting != 0 && depth > max_nesting) {
756
- fbuffer_free(buffer);
757
- rb_raise(eNestingError, "nesting of %ld is too deep", depth);
758
- }
759
- fbuffer_append_char(buffer, '{');
760
- keys = rb_funcall(obj, rb_intern("keys"), 0);
761
- for(i = 0; i < RARRAY_LEN(keys); i++) {
762
- if (i > 0) fbuffer_append(buffer, delim, delim_len);
763
- if (object_nl) {
764
- fbuffer_append(buffer, object_nl, object_nl_len);
765
- }
766
- if (indent) {
767
- for (j = 0; j < depth; j++) {
768
- fbuffer_append(buffer, indent, indent_len);
769
- }
770
- }
771
- key = rb_ary_entry(keys, i);
772
- key_to_s = rb_funcall(key, i_to_s, 0);
773
- Check_Type(key_to_s, T_STRING);
774
- generate_json(buffer, Vstate, state, key_to_s, depth);
775
- fbuffer_append(buffer, delim2, delim2_len);
776
- generate_json(buffer, Vstate, state, rb_hash_aref(obj, key), depth);
777
- }
778
- depth--;
727
+ char *object_nl = state->object_nl;
728
+ long object_nl_len = state->object_nl_len;
729
+ char *indent = state->indent;
730
+ long indent_len = state->indent_len;
731
+ long max_nesting = state->max_nesting;
732
+ char *delim = FBUFFER_PTR(state->object_delim);
733
+ long delim_len = FBUFFER_LEN(state->object_delim);
734
+ char *delim2 = FBUFFER_PTR(state->object_delim2);
735
+ long delim2_len = FBUFFER_LEN(state->object_delim2);
736
+ int i, j;
737
+ VALUE key, key_to_s, keys;
738
+ depth++;
739
+ if (max_nesting != 0 && depth > max_nesting) {
740
+ fbuffer_free(buffer);
741
+ rb_raise(eNestingError, "nesting of %ld is too deep", depth);
742
+ }
743
+ fbuffer_append_char(buffer, '{');
744
+ keys = rb_funcall(obj, i_keys, 0);
745
+ for(i = 0; i < RARRAY_LEN(keys); i++) {
746
+ if (i > 0) fbuffer_append(buffer, delim, delim_len);
779
747
  if (object_nl) {
780
748
  fbuffer_append(buffer, object_nl, object_nl_len);
781
- if (indent) {
782
- for (j = 0; j < depth; j++) {
783
- fbuffer_append(buffer, indent, indent_len);
784
- }
749
+ }
750
+ if (indent) {
751
+ for (j = 0; j < depth; j++) {
752
+ fbuffer_append(buffer, indent, indent_len);
785
753
  }
786
754
  }
787
- fbuffer_append_char(buffer, '}');
788
- } else if (klass == rb_cArray) {
789
- char *array_nl = state->array_nl;
790
- long array_nl_len = state->array_nl_len;
791
- char *indent = state->indent;
792
- long indent_len = state->indent_len;
793
- long max_nesting = state->max_nesting;
794
- char *delim = FBUFFER_PTR(state->array_delim);
795
- long delim_len = FBUFFER_LEN(state->array_delim);
796
- int i, j;
797
- depth++;
798
- if (max_nesting != 0 && depth > max_nesting) {
799
- fbuffer_free(buffer);
800
- rb_raise(eNestingError, "nesting of %ld is too deep", depth);
755
+ key = rb_ary_entry(keys, i);
756
+ key_to_s = rb_funcall(key, i_to_s, 0);
757
+ Check_Type(key_to_s, T_STRING);
758
+ generate_json(buffer, Vstate, state, key_to_s, depth);
759
+ fbuffer_append(buffer, delim2, delim2_len);
760
+ generate_json(buffer, Vstate, state, rb_hash_aref(obj, key), depth);
761
+ }
762
+ depth--;
763
+ if (object_nl) {
764
+ fbuffer_append(buffer, object_nl, object_nl_len);
765
+ if (indent) {
766
+ for (j = 0; j < depth; j++) {
767
+ fbuffer_append(buffer, indent, indent_len);
768
+ }
801
769
  }
802
- fbuffer_append_char(buffer, '[');
803
- if (array_nl) fbuffer_append(buffer, array_nl, array_nl_len);
804
- for(i = 0; i < RARRAY_LEN(obj); i++) {
805
- if (i > 0) fbuffer_append(buffer, delim, delim_len);
806
- if (indent) {
807
- for (j = 0; j < depth; j++) {
808
- fbuffer_append(buffer, indent, indent_len);
809
- }
770
+ }
771
+ fbuffer_append_char(buffer, '}');
772
+ }
773
+
774
+ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
775
+ {
776
+ char *array_nl = state->array_nl;
777
+ long array_nl_len = state->array_nl_len;
778
+ char *indent = state->indent;
779
+ long indent_len = state->indent_len;
780
+ long max_nesting = state->max_nesting;
781
+ char *delim = FBUFFER_PTR(state->array_delim);
782
+ long delim_len = FBUFFER_LEN(state->array_delim);
783
+ int i, j;
784
+ depth++;
785
+ if (max_nesting != 0 && depth > max_nesting) {
786
+ fbuffer_free(buffer);
787
+ rb_raise(eNestingError, "nesting of %ld is too deep", depth);
788
+ }
789
+ fbuffer_append_char(buffer, '[');
790
+ if (array_nl) fbuffer_append(buffer, array_nl, array_nl_len);
791
+ for(i = 0; i < RARRAY_LEN(obj); i++) {
792
+ if (i > 0) fbuffer_append(buffer, delim, delim_len);
793
+ if (indent) {
794
+ for (j = 0; j < depth; j++) {
795
+ fbuffer_append(buffer, indent, indent_len);
810
796
  }
811
- generate_json(buffer, Vstate, state, rb_ary_entry(obj, i), depth);
812
797
  }
813
- depth--;
814
- if (array_nl) {
815
- fbuffer_append(buffer, array_nl, array_nl_len);
816
- if (indent) {
817
- for (j = 0; j < depth; j++) {
818
- fbuffer_append(buffer, indent, indent_len);
819
- }
798
+ generate_json(buffer, Vstate, state, rb_ary_entry(obj, i), depth);
799
+ }
800
+ depth--;
801
+ if (array_nl) {
802
+ fbuffer_append(buffer, array_nl, array_nl_len);
803
+ if (indent) {
804
+ for (j = 0; j < depth; j++) {
805
+ fbuffer_append(buffer, indent, indent_len);
820
806
  }
821
807
  }
822
- fbuffer_append_char(buffer, ']');
823
- } else if (klass == rb_cString) {
824
- fbuffer_append_char(buffer, '"');
808
+ }
809
+ fbuffer_append_char(buffer, ']');
810
+ }
811
+
812
+ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
813
+ {
814
+ fbuffer_append_char(buffer, '"');
825
815
  #ifdef HAVE_RUBY_ENCODING_H
826
- obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
816
+ obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
827
817
  #endif
828
- if (state->ascii_only) {
829
- convert_UTF8_to_JSON_ASCII(buffer, obj);
830
- } else {
831
- convert_UTF8_to_JSON(buffer, obj);
818
+ if (state->ascii_only) {
819
+ convert_UTF8_to_JSON_ASCII(buffer, obj);
820
+ } else {
821
+ convert_UTF8_to_JSON(buffer, obj);
822
+ }
823
+ fbuffer_append_char(buffer, '"');
824
+ }
825
+
826
+ static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
827
+ {
828
+ fbuffer_append(buffer, "null", 4);
829
+ }
830
+
831
+ static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
832
+ {
833
+ fbuffer_append(buffer, "false", 5);
834
+ }
835
+
836
+ static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
837
+ {
838
+ fbuffer_append(buffer, "true", 4);
839
+ }
840
+
841
+ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
842
+ {
843
+ fbuffer_append_long(buffer, FIX2LONG(obj));
844
+ }
845
+
846
+ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
847
+ {
848
+ VALUE tmp = rb_funcall(obj, i_to_s, 0);
849
+ fbuffer_append(buffer, RSTRING_PAIR(tmp));
850
+ }
851
+
852
+ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
853
+ {
854
+ double value = RFLOAT_VALUE(obj);
855
+ char allow_nan = state->allow_nan;
856
+ VALUE tmp = rb_funcall(obj, i_to_s, 0);
857
+ if (!allow_nan) {
858
+ if (isinf(value)) {
859
+ fbuffer_free(buffer);
860
+ rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
861
+ } else if (isnan(value)) {
862
+ fbuffer_free(buffer);
863
+ rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
832
864
  }
833
- fbuffer_append_char(buffer, '"');
865
+ }
866
+ fbuffer_append(buffer, RSTRING_PAIR(tmp));
867
+ }
868
+
869
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
870
+ {
871
+ VALUE tmp;
872
+ VALUE klass = CLASS_OF(obj);
873
+ if (klass == rb_cHash) {
874
+ generate_json_object(buffer, Vstate, state, obj, depth);
875
+ } else if (klass == rb_cArray) {
876
+ generate_json_array(buffer, Vstate, state, obj, depth);
877
+ } else if (klass == rb_cString) {
878
+ generate_json_string(buffer, Vstate, state, obj, depth);
834
879
  } else if (obj == Qnil) {
835
- fbuffer_append(buffer, "null", 4);
880
+ generate_json_null(buffer, Vstate, state, obj, depth);
836
881
  } else if (obj == Qfalse) {
837
- fbuffer_append(buffer, "false", 5);
882
+ generate_json_false(buffer, Vstate, state, obj, depth);
838
883
  } else if (obj == Qtrue) {
839
- fbuffer_append(buffer, "true", 4);
884
+ generate_json_true(buffer, Vstate, state, obj, depth);
840
885
  } else if (klass == rb_cFixnum) {
841
- fbuffer_append_long(buffer, FIX2LONG(obj));
886
+ generate_json_fixnum(buffer, Vstate, state, obj, depth);
842
887
  } else if (klass == rb_cBignum) {
843
- tmp = rb_funcall(obj, i_to_s, 0);
844
- fbuffer_append(buffer, RSTRING_PAIR(tmp));
888
+ generate_json_bignum(buffer, Vstate, state, obj, depth);
845
889
  } else if (klass == rb_cFloat) {
846
- double value = RFLOAT_VALUE(obj);
847
- char allow_nan = state->allow_nan;
848
- tmp = rb_funcall(obj, i_to_s, 0);
849
- if (!allow_nan) {
850
- if (isinf(value)) {
851
- fbuffer_free(buffer);
852
- rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
853
- } else if (isnan(value)) {
854
- fbuffer_free(buffer);
855
- rb_raise(eGeneratorError, "%u: %s not allowed in JSON", __LINE__, StringValueCStr(tmp));
856
- }
857
- }
858
- fbuffer_append(buffer, RSTRING_PAIR(tmp));
890
+ generate_json_float(buffer, Vstate, state, obj, depth);
859
891
  } else if (rb_respond_to(obj, i_to_json)) {
860
892
  tmp = rb_funcall(obj, i_to_json, 2, Vstate, INT2FIX(depth + 1));
861
893
  Check_Type(tmp, T_STRING);
@@ -867,15 +899,8 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s
867
899
  }
868
900
  }
869
901
 
870
- /*
871
- * call-seq: partial_generate(obj)
872
- *
873
- * Generates a part of a JSON document from object +obj+ and returns the
874
- * result.
875
- */
876
- static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
902
+ static FBuffer *cState_prepare_buffer(VALUE self)
877
903
  {
878
- VALUE result;
879
904
  FBuffer *buffer = fbuffer_alloc();
880
905
  GET_STATE(self);
881
906
 
@@ -900,14 +925,25 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
900
925
  }
901
926
  fbuffer_append_char(state->array_delim, ',');
902
927
  if (state->array_nl) fbuffer_append(state->array_delim, state->array_nl, state->array_nl_len);
928
+ return buffer;
929
+ }
903
930
 
904
- generate_json(buffer, self, state, obj, NIL_P(depth) ? 0 : FIX2INT(depth));
905
- result = rb_str_new(FBUFFER_PAIR(buffer));
906
- fbuffer_free(buffer);
931
+ static VALUE fbuffer_to_s(FBuffer *fb)
932
+ {
933
+ VALUE result = rb_str_new(FBUFFER_PAIR(fb));
934
+ fbuffer_free(fb);
907
935
  FORCE_UTF8(result);
908
936
  return result;
909
937
  }
910
938
 
939
+ static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
940
+ {
941
+ FBuffer *buffer = cState_prepare_buffer(self);
942
+ GET_STATE(self);
943
+ generate_json(buffer, self, state, obj, NIL_P(depth) ? 0 : FIX2INT(depth));
944
+ return fbuffer_to_s(buffer);
945
+ }
946
+
911
947
  /*
912
948
  * call-seq: generate(obj)
913
949
  *
@@ -948,7 +984,6 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
948
984
  {
949
985
  VALUE opts;
950
986
  GET_STATE(self);
951
- MEMZERO(state, JSON_Generator_State, 1);
952
987
  state->max_nesting = 19;
953
988
  rb_scan_args(argc, argv, "01", &opts);
954
989
  if (!NIL_P(opts)) cState_configure(self, opts);
@@ -996,7 +1031,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
996
1031
  return rb_funcall(self, i_new, 1, opts);
997
1032
  } else {
998
1033
  if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
999
- CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, rb_intern("SAFE_STATE_PROTOTYPE"));
1034
+ CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
1000
1035
  }
1001
1036
  return CJSON_SAFE_STATE_PROTOTYPE;
1002
1037
  }
@@ -1266,7 +1301,6 @@ void Init_generator()
1266
1301
  rb_define_method(cState, "to_h", cState_to_h, 0);
1267
1302
  rb_define_method(cState, "[]", cState_aref, 1);
1268
1303
  rb_define_method(cState, "generate", cState_generate, 1);
1269
- rb_define_method(cState, "partial_generate", cState_partial_generate, 1);
1270
1304
 
1271
1305
  mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
1272
1306
  mObject = rb_define_module_under(mGeneratorMethods, "Object");
@@ -1275,8 +1309,10 @@ void Init_generator()
1275
1309
  rb_define_method(mHash, "to_json", mHash_to_json, -1);
1276
1310
  mArray = rb_define_module_under(mGeneratorMethods, "Array");
1277
1311
  rb_define_method(mArray, "to_json", mArray_to_json, -1);
1278
- mInteger = rb_define_module_under(mGeneratorMethods, "Integer");
1279
- rb_define_method(mInteger, "to_json", mInteger_to_json, -1);
1312
+ mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
1313
+ rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
1314
+ mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
1315
+ rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
1280
1316
  mFloat = rb_define_module_under(mGeneratorMethods, "Float");
1281
1317
  rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
1282
1318
  mString = rb_define_module_under(mGeneratorMethods, "String");
@@ -1314,10 +1350,12 @@ void Init_generator()
1314
1350
  i_send = rb_intern("__send__");
1315
1351
  i_respond_to_p = rb_intern("respond_to?");
1316
1352
  i_match = rb_intern("match");
1353
+ i_keys = rb_intern("keys");
1317
1354
  #ifdef HAVE_RUBY_ENCODING_H
1318
1355
  CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1319
1356
  i_encoding = rb_intern("encoding");
1320
1357
  i_encode = rb_intern("encode");
1321
1358
  #endif
1359
+ i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
1322
1360
  CJSON_SAFE_STATE_PROTOTYPE = Qnil;
1323
1361
  }
@@ -73,6 +73,7 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len);
73
73
  static void fbuffer_append_long(FBuffer *fb, long number);
74
74
  static void fbuffer_append_char(FBuffer *fb, char newchr);
75
75
  static FBuffer *fbuffer_dup(FBuffer *fb);
76
+ static VALUE fbuffer_to_s(FBuffer *fb);
76
77
 
77
78
  /* unicode defintions */
78
79
 
@@ -129,9 +130,22 @@ typedef struct JSON_Generator_StateStruct {
129
130
  JSON_Generator_State *state; \
130
131
  Data_Get_Struct(self, JSON_Generator_State, state)
131
132
 
133
+ #define GENERATE_JSON(type) \
134
+ FBuffer *buffer; \
135
+ VALUE Vstate, depth; \
136
+ JSON_Generator_State *state; \
137
+ \
138
+ rb_scan_args(argc, argv, "02", &Vstate, &depth); \
139
+ Vstate = cState_from_state_s(cState, Vstate); \
140
+ Data_Get_Struct(Vstate, JSON_Generator_State, state); \
141
+ buffer = cState_prepare_buffer(Vstate); \
142
+ generate_json_##type(buffer, Vstate, state, self, NIL_P(depth) ? 0 : FIX2INT(depth)); \
143
+ return fbuffer_to_s(buffer)
144
+
132
145
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
133
146
  static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self);
134
- static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self);
147
+ static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self);
148
+ static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self);
135
149
  static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self);
136
150
  static VALUE mString_included_s(VALUE self, VALUE modul);
137
151
  static VALUE mString_to_json(int argc, VALUE *argv, VALUE self);
@@ -148,6 +162,15 @@ static VALUE cState_s_allocate(VALUE klass);
148
162
  static VALUE cState_configure(VALUE self, VALUE opts);
149
163
  static VALUE cState_to_h(VALUE self);
150
164
  static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
165
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
166
+ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
167
+ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
168
+ static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
169
+ static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
170
+ static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
171
+ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
172
+ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
173
+ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
151
174
  static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth);
152
175
  static VALUE cState_generate(VALUE self, VALUE obj);
153
176
  static VALUE cState_initialize(int argc, VALUE *argv, VALUE self);
@@ -166,5 +189,6 @@ static VALUE cState_max_nesting(VALUE self);
166
189
  static VALUE cState_max_nesting_set(VALUE self, VALUE depth);
167
190
  static VALUE cState_allow_nan_p(VALUE self);
168
191
  static VALUE cState_ascii_only_p(VALUE self);
192
+ static FBuffer *cState_prepare_buffer(VALUE self);
169
193
 
170
194
  #endif
@@ -70,24 +70,25 @@ module JSON
70
70
  # * *array_class*: Defaults to Array
71
71
  def initialize(source, opts = {})
72
72
  if defined?(::Encoding)
73
- if source.encoding == Encoding::ASCII_8BIT
73
+ if source.encoding == ::Encoding::ASCII_8BIT
74
74
  b = source[0, 4].bytes.to_a
75
75
  source = case
76
76
  when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
77
- source.dup.force_encoding(Encoding::UTF_32BE).encode!(Encoding::UTF_8)
77
+ source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
78
78
  when b.size >= 4 && b[0] == 0 && b[2] == 0
79
- source.dup.force_encoding(Encoding::UTF_16BE).encode!(Encoding::UTF_8)
79
+ source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
80
80
  when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
81
- source.dup.force_encoding(Encoding::UTF_32LE).encode!(Encoding::UTF_8)
81
+ source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
82
+
82
83
  when b.size >= 4 && b[1] == 0 && b[3] == 0
83
- source.dup.force_encoding(Encoding::UTF_16LE).encode!(Encoding::UTF_8)
84
+ source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
84
85
  else
85
86
  source.dup
86
87
  end
87
88
  else
88
- source = source.encode(Encoding::UTF_8)
89
+ source = source.encode(::Encoding::UTF_8)
89
90
  end
90
- source.force_encoding(Encoding::ASCII_8BIT)
91
+ source.force_encoding(::Encoding::ASCII_8BIT)
91
92
  else
92
93
  b = source
93
94
  source = case
@@ -180,7 +181,7 @@ module JSON
180
181
  end
181
182
  end
182
183
  if string.respond_to?(:force_encoding)
183
- string.force_encoding(Encoding::UTF_8)
184
+ string.force_encoding(::Encoding::UTF_8)
184
185
  end
185
186
  string
186
187
  else
@@ -1,6 +1,6 @@
1
1
  module JSON
2
2
  # JSON version
3
- VERSION = '1.4.3'
3
+ VERSION = '1.4.4'
4
4
  VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -160,6 +160,20 @@ class TC_JSON < Test::Unit::TestCase
160
160
 
161
161
  class SubArray < Array; end
162
162
 
163
+ class SubArray2 < Array
164
+ def to_json(*a)
165
+ {
166
+ JSON.create_id => self.class.name,
167
+ 'ary' => to_a,
168
+ }.to_json(*a)
169
+ end
170
+
171
+ def self.json_create(o)
172
+ o.delete JSON.create_id
173
+ o['ary']
174
+ end
175
+ end
176
+
163
177
  def test_parse_array_custom_class
164
178
  res = parse('[]', :array_class => SubArray)
165
179
  assert_equal([], res)
@@ -174,6 +188,9 @@ class TC_JSON < Test::Unit::TestCase
174
188
  end
175
189
 
176
190
  class SubHash < Hash
191
+ end
192
+
193
+ class SubHash2 < Hash
177
194
  def to_json(*a)
178
195
  {
179
196
  JSON.create_id => self.class.name,
@@ -182,22 +199,38 @@ class TC_JSON < Test::Unit::TestCase
182
199
 
183
200
  def self.json_create(o)
184
201
  o.delete JSON.create_id
185
- new.merge(o)
202
+ self[o]
186
203
  end
187
204
  end
188
205
 
189
206
  def test_parse_object_custom_class
190
- res = parse('{}', :object_class => SubHash)
207
+ res = parse('{}', :object_class => SubHash2)
191
208
  assert_equal({}, res)
192
- assert_equal(SubHash, res.class)
209
+ assert_equal(SubHash2, res.class)
210
+ end
211
+
212
+ def test_generation_of_core_subclasses_with_new_to_json
213
+ obj = SubHash2["foo" => SubHash2["bar" => true]]
214
+ obj_json = JSON(obj)
215
+ obj_again = JSON(obj_json)
216
+ assert_kind_of SubHash2, obj_again
217
+ assert_kind_of SubHash2, obj_again['foo']
218
+ assert obj_again['foo']['bar']
219
+ assert_equal obj, obj_again
220
+ assert_equal ["foo"], JSON(JSON(SubArray2["foo"]))
221
+ end
222
+
223
+ def test_generation_of_core_subclasses_with_default_to_json
224
+ assert_equal '{"foo":"bar"}', JSON(SubHash["foo" => "bar"])
225
+ assert_equal '["foo"]', JSON(SubArray["foo"])
193
226
  end
194
227
 
195
228
  def test_generation_of_core_subclasses
196
- obj = SubHash.new.merge( "foo" => SubHash.new.merge("bar" => true))
229
+ obj = SubHash["foo" => SubHash["bar" => true]]
197
230
  obj_json = JSON(obj)
198
231
  obj_again = JSON(obj_json)
199
- assert_kind_of SubHash, obj_again
200
- assert_kind_of SubHash, obj_again['foo']
232
+ assert_kind_of Hash, obj_again
233
+ assert_kind_of Hash, obj_again['foo']
201
234
  assert obj_again['foo']['bar']
202
235
  assert_equal obj, obj_again
203
236
  end
@@ -151,12 +151,12 @@ class TC_JSONAddition < Test::Unit::TestCase
151
151
  def test_utc_datetime
152
152
  now = Time.now
153
153
  d = DateTime.parse(now.to_s) # usual case
154
- assert d, JSON.parse(d.to_json)
154
+ assert_equal d, JSON.parse(d.to_json)
155
155
  d = DateTime.parse(now.utc.to_s) # of = 0
156
- assert d, JSON.parse(d.to_json)
157
- d = DateTime.civil(2008, 6, 17, 11, 48, 32, 1) # of = 1 / 12 => 1/12
158
- assert d, JSON.parse(d.to_json)
159
- d = DateTime.civil(2008, 6, 17, 11, 48, 32, 12) # of = 12 / 12 => 12
160
- assert d, JSON.parse(d.to_json)
156
+ assert_equal d, JSON.parse(d.to_json)
157
+ d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
158
+ assert_equal d, JSON.parse(d.to_json)
159
+ d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
160
+ assert_equal d, JSON.parse(d.to_json)
161
161
  end
162
162
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 4
9
+ - 4
10
+ version: 1.4.4
5
11
  platform: ruby
6
12
  authors:
7
13
  - Florian Frank
@@ -9,7 +15,7 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-05-05 00:00:00 +02:00
18
+ date: 2010-08-06 00:00:00 +02:00
13
19
  default_executable: edit_json.rb
14
20
  dependencies: []
15
21
 
@@ -155,21 +161,27 @@ require_paths:
155
161
  - ext
156
162
  - lib
157
163
  required_ruby_version: !ruby/object:Gem::Requirement
164
+ none: false
158
165
  requirements:
159
166
  - - ">="
160
167
  - !ruby/object:Gem::Version
168
+ hash: 3
169
+ segments:
170
+ - 0
161
171
  version: "0"
162
- version:
163
172
  required_rubygems_version: !ruby/object:Gem::Requirement
173
+ none: false
164
174
  requirements:
165
175
  - - ">="
166
176
  - !ruby/object:Gem::Version
177
+ hash: 3
178
+ segments:
179
+ - 0
167
180
  version: "0"
168
- version:
169
181
  requirements: []
170
182
 
171
183
  rubyforge_project: json
172
- rubygems_version: 1.3.5
184
+ rubygems_version: 1.3.7
173
185
  signing_key:
174
186
  specification_version: 3
175
187
  summary: JSON Implementation for Ruby