json_pure 1.4.3 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
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
data/lib/json/version.rb CHANGED
@@ -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:
data/tests/test_json.rb CHANGED
@@ -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_pure
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
 
@@ -152,21 +158,27 @@ rdoc_options:
152
158
  require_paths:
153
159
  - lib
154
160
  required_ruby_version: !ruby/object:Gem::Requirement
161
+ none: false
155
162
  requirements:
156
163
  - - ">="
157
164
  - !ruby/object:Gem::Version
165
+ hash: 3
166
+ segments:
167
+ - 0
158
168
  version: "0"
159
- version:
160
169
  required_rubygems_version: !ruby/object:Gem::Requirement
170
+ none: false
161
171
  requirements:
162
172
  - - ">="
163
173
  - !ruby/object:Gem::Version
174
+ hash: 3
175
+ segments:
176
+ - 0
164
177
  version: "0"
165
- version:
166
178
  requirements: []
167
179
 
168
180
  rubyforge_project: json
169
- rubygems_version: 1.3.5
181
+ rubygems_version: 1.3.7
170
182
  signing_key:
171
183
  specification_version: 3
172
184
  summary: JSON Implementation for Ruby