json_pure 1.4.4 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 2010-08-07 (1.4.5)
2
+ * Manage data structure nesting depth in state object during generation. This
3
+ should reduce problems with to_json method definіtions that only have one
4
+ argument.
5
+ * Some fixes in the state objects and additional tests.
1
6
  2010-08-06 (1.4.4)
2
7
  * Fixes build problem for rubinius under OS X, http://github.com/flori/json/issues/closed#issue/25
3
8
  * Fixes crashes described in http://github.com/flori/json/issues/closed#issue/21 and
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.4
1
+ 1.4.5
@@ -14,7 +14,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
14
14
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
15
15
  i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
16
16
  i_pack, i_unpack, i_create_id, i_extend, i_key_p, i_aref, i_send,
17
- i_respond_to_p, i_match, i_keys;
17
+ i_respond_to_p, i_match, i_keys, i_depth;
18
18
 
19
19
  /*
20
20
  * Copyright 2001-2004 Unicode, Inc.
@@ -417,13 +417,12 @@ static FBuffer *fbuffer_dup(FBuffer *fb)
417
417
  */
418
418
 
419
419
  /*
420
- * call-seq: to_json(state = nil, depth = 0)
420
+ * call-seq: to_json(state = nil)
421
421
  *
422
422
  * Returns a JSON string containing a JSON object, that is generated from
423
423
  * this Hash instance.
424
424
  * _state_ is a JSON::State object, that can also be used to configure the
425
425
  * produced JSON string output further.
426
- * _depth_ is used to find out nesting depth, to indent accordingly.
427
426
  */
428
427
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
429
428
  {
@@ -431,13 +430,12 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
431
430
  }
432
431
 
433
432
  /*
434
- * call-seq: to_json(state = nil, depth = 0)
433
+ * call-seq: to_json(state = nil)
435
434
  *
436
435
  * Returns a JSON string containing a JSON array, that is generated from
437
436
  * this Array instance.
438
437
  * _state_ is a JSON::State object, that can also be used to configure the
439
438
  * produced JSON string output further.
440
- * _depth_ is used to find out nesting depth, to indent accordingly.
441
439
  */
442
440
  static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
443
441
  GENERATE_JSON(array);
@@ -578,12 +576,12 @@ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
578
576
  */
579
577
  static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
580
578
  {
581
- VALUE state, depth;
579
+ VALUE state;
582
580
  VALUE string = rb_funcall(self, i_to_s, 0);
583
- rb_scan_args(argc, argv, "02", &state, &depth);
581
+ rb_scan_args(argc, argv, "01", &state);
584
582
  Check_Type(string, T_STRING);
585
583
  state = cState_from_state_s(cState, state);
586
- return cState_partial_generate(state, string, depth);
584
+ return cState_partial_generate(state, string);
587
585
  }
588
586
 
589
587
  static void State_free(JSON_Generator_State *state)
@@ -679,6 +677,17 @@ static VALUE cState_configure(VALUE self, VALUE opts)
679
677
  state->max_nesting = 0;
680
678
  }
681
679
  }
680
+ tmp = ID2SYM(i_depth);
681
+ state->depth = 0;
682
+ if (option_given_p(opts, tmp)) {
683
+ VALUE depth = rb_hash_aref(opts, tmp);
684
+ if (RTEST(depth)) {
685
+ Check_Type(depth, T_FIXNUM);
686
+ state->depth = FIX2LONG(depth);
687
+ } else {
688
+ state->depth = 0;
689
+ }
690
+ }
682
691
  tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
683
692
  state->allow_nan = RTEST(tmp);
684
693
  tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
@@ -704,6 +713,7 @@ static VALUE cState_to_h(VALUE self)
704
713
  rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
705
714
  rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
706
715
  rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
716
+ rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
707
717
  return result;
708
718
  }
709
719
 
@@ -722,7 +732,7 @@ static VALUE cState_aref(VALUE self, VALUE name)
722
732
  }
723
733
  }
724
734
 
725
- static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
735
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
726
736
  {
727
737
  char *object_nl = state->object_nl;
728
738
  long object_nl_len = state->object_nl_len;
@@ -733,9 +743,9 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
733
743
  long delim_len = FBUFFER_LEN(state->object_delim);
734
744
  char *delim2 = FBUFFER_PTR(state->object_delim2);
735
745
  long delim2_len = FBUFFER_LEN(state->object_delim2);
746
+ long depth = ++state->depth;
736
747
  int i, j;
737
748
  VALUE key, key_to_s, keys;
738
- depth++;
739
749
  if (max_nesting != 0 && depth > max_nesting) {
740
750
  fbuffer_free(buffer);
741
751
  rb_raise(eNestingError, "nesting of %ld is too deep", depth);
@@ -755,11 +765,11 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
755
765
  key = rb_ary_entry(keys, i);
756
766
  key_to_s = rb_funcall(key, i_to_s, 0);
757
767
  Check_Type(key_to_s, T_STRING);
758
- generate_json(buffer, Vstate, state, key_to_s, depth);
768
+ generate_json(buffer, Vstate, state, key_to_s);
759
769
  fbuffer_append(buffer, delim2, delim2_len);
760
- generate_json(buffer, Vstate, state, rb_hash_aref(obj, key), depth);
770
+ generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
761
771
  }
762
- depth--;
772
+ depth = --state->depth;
763
773
  if (object_nl) {
764
774
  fbuffer_append(buffer, object_nl, object_nl_len);
765
775
  if (indent) {
@@ -771,7 +781,7 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
771
781
  fbuffer_append_char(buffer, '}');
772
782
  }
773
783
 
774
- static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
784
+ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
775
785
  {
776
786
  char *array_nl = state->array_nl;
777
787
  long array_nl_len = state->array_nl_len;
@@ -780,8 +790,8 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
780
790
  long max_nesting = state->max_nesting;
781
791
  char *delim = FBUFFER_PTR(state->array_delim);
782
792
  long delim_len = FBUFFER_LEN(state->array_delim);
793
+ long depth = ++state->depth;
783
794
  int i, j;
784
- depth++;
785
795
  if (max_nesting != 0 && depth > max_nesting) {
786
796
  fbuffer_free(buffer);
787
797
  rb_raise(eNestingError, "nesting of %ld is too deep", depth);
@@ -795,9 +805,9 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
795
805
  fbuffer_append(buffer, indent, indent_len);
796
806
  }
797
807
  }
798
- generate_json(buffer, Vstate, state, rb_ary_entry(obj, i), depth);
808
+ generate_json(buffer, Vstate, state, rb_ary_entry(obj, i));
799
809
  }
800
- depth--;
810
+ state->depth = --depth;
801
811
  if (array_nl) {
802
812
  fbuffer_append(buffer, array_nl, array_nl_len);
803
813
  if (indent) {
@@ -809,7 +819,7 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
809
819
  fbuffer_append_char(buffer, ']');
810
820
  }
811
821
 
812
- static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
822
+ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
813
823
  {
814
824
  fbuffer_append_char(buffer, '"');
815
825
  #ifdef HAVE_RUBY_ENCODING_H
@@ -823,33 +833,33 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
823
833
  fbuffer_append_char(buffer, '"');
824
834
  }
825
835
 
826
- static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
836
+ static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
827
837
  {
828
838
  fbuffer_append(buffer, "null", 4);
829
839
  }
830
840
 
831
- static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
841
+ static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
832
842
  {
833
843
  fbuffer_append(buffer, "false", 5);
834
844
  }
835
845
 
836
- static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
846
+ static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
837
847
  {
838
848
  fbuffer_append(buffer, "true", 4);
839
849
  }
840
850
 
841
- static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
851
+ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
842
852
  {
843
853
  fbuffer_append_long(buffer, FIX2LONG(obj));
844
854
  }
845
855
 
846
- static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
856
+ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
847
857
  {
848
858
  VALUE tmp = rb_funcall(obj, i_to_s, 0);
849
859
  fbuffer_append(buffer, RSTRING_PAIR(tmp));
850
860
  }
851
861
 
852
- static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
862
+ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
853
863
  {
854
864
  double value = RFLOAT_VALUE(obj);
855
865
  char allow_nan = state->allow_nan;
@@ -866,36 +876,36 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
866
876
  fbuffer_append(buffer, RSTRING_PAIR(tmp));
867
877
  }
868
878
 
869
- static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth)
879
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
870
880
  {
871
881
  VALUE tmp;
872
882
  VALUE klass = CLASS_OF(obj);
873
883
  if (klass == rb_cHash) {
874
- generate_json_object(buffer, Vstate, state, obj, depth);
884
+ generate_json_object(buffer, Vstate, state, obj);
875
885
  } else if (klass == rb_cArray) {
876
- generate_json_array(buffer, Vstate, state, obj, depth);
886
+ generate_json_array(buffer, Vstate, state, obj);
877
887
  } else if (klass == rb_cString) {
878
- generate_json_string(buffer, Vstate, state, obj, depth);
888
+ generate_json_string(buffer, Vstate, state, obj);
879
889
  } else if (obj == Qnil) {
880
- generate_json_null(buffer, Vstate, state, obj, depth);
890
+ generate_json_null(buffer, Vstate, state, obj);
881
891
  } else if (obj == Qfalse) {
882
- generate_json_false(buffer, Vstate, state, obj, depth);
892
+ generate_json_false(buffer, Vstate, state, obj);
883
893
  } else if (obj == Qtrue) {
884
- generate_json_true(buffer, Vstate, state, obj, depth);
894
+ generate_json_true(buffer, Vstate, state, obj);
885
895
  } else if (klass == rb_cFixnum) {
886
- generate_json_fixnum(buffer, Vstate, state, obj, depth);
896
+ generate_json_fixnum(buffer, Vstate, state, obj);
887
897
  } else if (klass == rb_cBignum) {
888
- generate_json_bignum(buffer, Vstate, state, obj, depth);
898
+ generate_json_bignum(buffer, Vstate, state, obj);
889
899
  } else if (klass == rb_cFloat) {
890
- generate_json_float(buffer, Vstate, state, obj, depth);
900
+ generate_json_float(buffer, Vstate, state, obj);
891
901
  } else if (rb_respond_to(obj, i_to_json)) {
892
- tmp = rb_funcall(obj, i_to_json, 2, Vstate, INT2FIX(depth + 1));
902
+ tmp = rb_funcall(obj, i_to_json, 1, Vstate);
893
903
  Check_Type(tmp, T_STRING);
894
904
  fbuffer_append(buffer, RSTRING_PAIR(tmp));
895
905
  } else {
896
906
  tmp = rb_funcall(obj, i_to_s, 0);
897
907
  Check_Type(tmp, T_STRING);
898
- generate_json(buffer, Vstate, state, tmp, depth + 1);
908
+ generate_json(buffer, Vstate, state, tmp);
899
909
  }
900
910
  }
901
911
 
@@ -936,11 +946,11 @@ static VALUE fbuffer_to_s(FBuffer *fb)
936
946
  return result;
937
947
  }
938
948
 
939
- static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
949
+ static VALUE cState_partial_generate(VALUE self, VALUE obj)
940
950
  {
941
951
  FBuffer *buffer = cState_prepare_buffer(self);
942
952
  GET_STATE(self);
943
- generate_json(buffer, self, state, obj, NIL_P(depth) ? 0 : FIX2INT(depth));
953
+ generate_json(buffer, self, state, obj);
944
954
  return fbuffer_to_s(buffer);
945
955
  }
946
956
 
@@ -953,7 +963,7 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth)
953
963
  */
954
964
  static VALUE cState_generate(VALUE self, VALUE obj)
955
965
  {
956
- VALUE result = cState_partial_generate(self, obj, Qnil);
966
+ VALUE result = cState_partial_generate(self, obj);
957
967
  VALUE re, args[2];
958
968
  args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
959
969
  args[1] = CRegexp_MULTILINE;
@@ -1055,16 +1065,20 @@ static VALUE cState_indent(VALUE self)
1055
1065
  */
1056
1066
  static VALUE cState_indent_set(VALUE self, VALUE indent)
1057
1067
  {
1068
+ int len;
1058
1069
  GET_STATE(self);
1059
1070
  Check_Type(indent, T_STRING);
1060
- if (RSTRING_LEN(indent) == 0) {
1071
+ len = RSTRING_LEN(indent);
1072
+ if (len == 0) {
1061
1073
  if (state->indent) {
1062
1074
  ruby_xfree(state->indent);
1063
1075
  state->indent = NULL;
1076
+ state->indent_len = 0;
1064
1077
  }
1065
1078
  } else {
1066
1079
  if (state->indent) ruby_xfree(state->indent);
1067
1080
  state->indent = strdup(RSTRING_PTR(indent));
1081
+ state->indent_len = len;
1068
1082
  }
1069
1083
  return Qnil;
1070
1084
  }
@@ -1089,16 +1103,20 @@ static VALUE cState_space(VALUE self)
1089
1103
  */
1090
1104
  static VALUE cState_space_set(VALUE self, VALUE space)
1091
1105
  {
1106
+ int len;
1092
1107
  GET_STATE(self);
1093
1108
  Check_Type(space, T_STRING);
1094
- if (RSTRING_LEN(space) == 0) {
1109
+ len = RSTRING_LEN(space);
1110
+ if (len == 0) {
1095
1111
  if (state->space) {
1096
1112
  ruby_xfree(state->space);
1097
1113
  state->space = NULL;
1114
+ state->space_len = 0;
1098
1115
  }
1099
1116
  } else {
1100
1117
  if (state->space) ruby_xfree(state->space);
1101
1118
  state->space = strdup(RSTRING_PTR(space));
1119
+ state->space_len = len;
1102
1120
  }
1103
1121
  return Qnil;
1104
1122
  }
@@ -1121,16 +1139,20 @@ static VALUE cState_space_before(VALUE self)
1121
1139
  */
1122
1140
  static VALUE cState_space_before_set(VALUE self, VALUE space_before)
1123
1141
  {
1142
+ int len;
1124
1143
  GET_STATE(self);
1125
1144
  Check_Type(space_before, T_STRING);
1126
- if (RSTRING_LEN(space_before) == 0) {
1145
+ len = RSTRING_LEN(space_before);
1146
+ if (len == 0) {
1127
1147
  if (state->space_before) {
1128
1148
  ruby_xfree(state->space_before);
1129
1149
  state->space_before = NULL;
1150
+ state->space_before_len = 0;
1130
1151
  }
1131
1152
  } else {
1132
1153
  if (state->space_before) ruby_xfree(state->space_before);
1133
1154
  state->space_before = strdup(RSTRING_PTR(space_before));
1155
+ state->space_before_len = len;
1134
1156
  }
1135
1157
  return Qnil;
1136
1158
  }
@@ -1155,9 +1177,11 @@ static VALUE cState_object_nl(VALUE self)
1155
1177
  */
1156
1178
  static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1157
1179
  {
1180
+ int len;
1158
1181
  GET_STATE(self);
1159
1182
  Check_Type(object_nl, T_STRING);
1160
- if (RSTRING_LEN(object_nl) == 0) {
1183
+ len = RSTRING_LEN(object_nl);
1184
+ if (len == 0) {
1161
1185
  if (state->object_nl) {
1162
1186
  ruby_xfree(state->object_nl);
1163
1187
  state->object_nl = NULL;
@@ -1165,6 +1189,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1165
1189
  } else {
1166
1190
  if (state->object_nl) ruby_xfree(state->object_nl);
1167
1191
  state->object_nl = strdup(RSTRING_PTR(object_nl));
1192
+ state->object_nl_len = len;
1168
1193
  }
1169
1194
  return Qnil;
1170
1195
  }
@@ -1187,9 +1212,11 @@ static VALUE cState_array_nl(VALUE self)
1187
1212
  */
1188
1213
  static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1189
1214
  {
1215
+ int len;
1190
1216
  GET_STATE(self);
1191
1217
  Check_Type(array_nl, T_STRING);
1192
- if (RSTRING_LEN(array_nl) == 0) {
1218
+ len = RSTRING_LEN(array_nl);
1219
+ if (len == 0) {
1193
1220
  if (state->array_nl) {
1194
1221
  ruby_xfree(state->array_nl);
1195
1222
  state->array_nl = NULL;
@@ -1197,6 +1224,7 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1197
1224
  } else {
1198
1225
  if (state->array_nl) ruby_xfree(state->array_nl);
1199
1226
  state->array_nl = strdup(RSTRING_PTR(array_nl));
1227
+ state->array_nl_len = len;
1200
1228
  }
1201
1229
  return Qnil;
1202
1230
  }
@@ -1263,6 +1291,30 @@ static VALUE cState_ascii_only_p(VALUE self)
1263
1291
  return state->ascii_only ? Qtrue : Qfalse;
1264
1292
  }
1265
1293
 
1294
+ /*
1295
+ * call-seq: depth
1296
+ *
1297
+ * This integer returns the current depth of data structure nesting.
1298
+ */
1299
+ static VALUE cState_depth(VALUE self)
1300
+ {
1301
+ GET_STATE(self);
1302
+ return LONG2FIX(state->depth);
1303
+ }
1304
+
1305
+ /*
1306
+ * call-seq: depth=(depth)
1307
+ *
1308
+ * This sets the maximum level of data structure nesting in the generated JSON
1309
+ * to the integer depth, max_nesting = 0 if no maximum should be checked.
1310
+ */
1311
+ static VALUE cState_depth_set(VALUE self, VALUE depth)
1312
+ {
1313
+ GET_STATE(self);
1314
+ Check_Type(depth, T_FIXNUM);
1315
+ return state->depth = FIX2LONG(depth);
1316
+ }
1317
+
1266
1318
  /*
1267
1319
  *
1268
1320
  */
@@ -1297,6 +1349,8 @@ void Init_generator()
1297
1349
  rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
1298
1350
  rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
1299
1351
  rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
1352
+ rb_define_method(cState, "depth", cState_depth, 0);
1353
+ rb_define_method(cState, "depth=", cState_depth_set, 1);
1300
1354
  rb_define_method(cState, "configure", cState_configure, 1);
1301
1355
  rb_define_method(cState, "to_h", cState_to_h, 0);
1302
1356
  rb_define_method(cState, "[]", cState_aref, 1);
@@ -1341,6 +1395,7 @@ void Init_generator()
1341
1395
  i_max_nesting = rb_intern("max_nesting");
1342
1396
  i_allow_nan = rb_intern("allow_nan");
1343
1397
  i_ascii_only = rb_intern("ascii_only");
1398
+ i_depth = rb_intern("depth");
1344
1399
  i_pack = rb_intern("pack");
1345
1400
  i_unpack = rb_intern("unpack");
1346
1401
  i_create_id = rb_intern("create_id");
@@ -124,22 +124,23 @@ typedef struct JSON_Generator_StateStruct {
124
124
  long max_nesting;
125
125
  char allow_nan;
126
126
  char ascii_only;
127
+ long depth;
127
128
  } JSON_Generator_State;
128
129
 
129
130
  #define GET_STATE(self) \
130
131
  JSON_Generator_State *state; \
131
132
  Data_Get_Struct(self, JSON_Generator_State, state)
132
133
 
133
- #define GENERATE_JSON(type) \
134
+ #define GENERATE_JSON(type) \
134
135
  FBuffer *buffer; \
135
- VALUE Vstate, depth; \
136
+ VALUE Vstate; \
136
137
  JSON_Generator_State *state; \
137
138
  \
138
- rb_scan_args(argc, argv, "02", &Vstate, &depth); \
139
+ rb_scan_args(argc, argv, "01", &Vstate); \
139
140
  Vstate = cState_from_state_s(cState, Vstate); \
140
141
  Data_Get_Struct(Vstate, JSON_Generator_State, state); \
141
142
  buffer = cState_prepare_buffer(Vstate); \
142
- generate_json_##type(buffer, Vstate, state, self, NIL_P(depth) ? 0 : FIX2INT(depth)); \
143
+ generate_json_##type(buffer, Vstate, state, self); \
143
144
  return fbuffer_to_s(buffer)
144
145
 
145
146
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
@@ -161,17 +162,17 @@ static JSON_Generator_State *State_allocate();
161
162
  static VALUE cState_s_allocate(VALUE klass);
162
163
  static VALUE cState_configure(VALUE self, VALUE opts);
163
164
  static VALUE cState_to_h(VALUE self);
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);
174
- static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth);
165
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
166
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
167
+ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
168
+ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
169
+ static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
170
+ static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
171
+ static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
172
+ static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
173
+ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
174
+ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
175
+ static VALUE cState_partial_generate(VALUE self, VALUE obj);
175
176
  static VALUE cState_generate(VALUE self, VALUE obj);
176
177
  static VALUE cState_initialize(int argc, VALUE *argv, VALUE self);
177
178
  static VALUE cState_from_state_s(VALUE self, VALUE opts);
@@ -189,6 +190,8 @@ static VALUE cState_max_nesting(VALUE self);
189
190
  static VALUE cState_max_nesting_set(VALUE self, VALUE depth);
190
191
  static VALUE cState_allow_nan_p(VALUE self);
191
192
  static VALUE cState_ascii_only_p(VALUE self);
193
+ static VALUE cState_depth(VALUE self);
194
+ static VALUE cState_depth_set(VALUE self, VALUE depth);
192
195
  static FBuffer *cState_prepare_buffer(VALUE self);
193
196
 
194
197
  #endif
data/lib/json/common.rb CHANGED
@@ -11,9 +11,9 @@ module JSON
11
11
  # generate and parse for their documentation.
12
12
  def [](object, opts = {})
13
13
  if object.respond_to? :to_str
14
- JSON.parse(object.to_str, opts => {})
14
+ JSON.parse(object.to_str, opts)
15
15
  else
16
- JSON.generate(object, opts => {})
16
+ JSON.generate(object, opts)
17
17
  end
18
18
  end
19
19
 
@@ -63,20 +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
66
+ const_set :SAFE_STATE_PROTOTYPE, State.new
67
67
  const_set :FAST_STATE_PROTOTYPE, State.new(
68
68
  :indent => '',
69
69
  :space => '',
70
70
  :object_nl => "",
71
71
  :array_nl => "",
72
72
  :max_nesting => false
73
- ).freeze
73
+ )
74
74
  const_set :PRETTY_STATE_PROTOTYPE, State.new(
75
75
  :indent => ' ',
76
76
  :space => ' ',
77
77
  :object_nl => "\n",
78
78
  :array_nl => "\n"
79
- ).freeze
79
+ )
80
80
  end
81
81
 
82
82
  # Returns the JSON generator modul, that is used by JSON. This might be
@@ -196,6 +196,7 @@ module JSON
196
196
  # amount of sanity checks, and the pretty_generate method for some
197
197
  # defaults for a pretty output.
198
198
  def generate(obj, opts = nil)
199
+ state = SAFE_STATE_PROTOTYPE.dup
199
200
  if opts
200
201
  if opts.respond_to? :to_hash
201
202
  opts = opts.to_hash
@@ -204,10 +205,7 @@ module JSON
204
205
  else
205
206
  raise TypeError, "can't convert #{opts.class} into Hash"
206
207
  end
207
- state = SAFE_STATE_PROTOTYPE.dup
208
208
  state = state.configure(opts)
209
- else
210
- state = SAFE_STATE_PROTOTYPE
211
209
  end
212
210
  state.generate(obj)
213
211
  end
@@ -225,6 +223,7 @@ module JSON
225
223
  # *WARNING*: Be careful not to pass any Ruby data structures with circles as
226
224
  # _obj_ argument, because this will cause JSON to go into an infinite loop.
227
225
  def fast_generate(obj, opts = nil)
226
+ state = FAST_STATE_PROTOTYPE.dup
228
227
  if opts
229
228
  if opts.respond_to? :to_hash
230
229
  opts = opts.to_hash
@@ -233,10 +232,7 @@ module JSON
233
232
  else
234
233
  raise TypeError, "can't convert #{opts.class} into Hash"
235
234
  end
236
- state = FAST_STATE_PROTOTYPE.dup
237
235
  state.configure(opts)
238
- else
239
- state = FAST_STATE_PROTOTYPE
240
236
  end
241
237
  state.generate(obj)
242
238
  end
@@ -254,6 +250,7 @@ module JSON
254
250
  # The _opts_ argument can be used to configure the generator, see the
255
251
  # generate method for a more detailed explanation.
256
252
  def pretty_generate(obj, opts = nil)
253
+ state = PRETTY_STATE_PROTOTYPE.dup
257
254
  if opts
258
255
  if opts.respond_to? :to_hash
259
256
  opts = opts.to_hash
@@ -262,10 +259,7 @@ module JSON
262
259
  else
263
260
  raise TypeError, "can't convert #{opts.class} into Hash"
264
261
  end
265
- state = PRETTY_STATE_PROTOTYPE.dup
266
262
  state.configure(opts)
267
- else
268
- state = PRETTY_STATE_PROTOTYPE
269
263
  end
270
264
  state.generate(obj)
271
265
  end
@@ -377,11 +371,11 @@ module ::Kernel
377
371
  #
378
372
  # The _opts_ argument is passed through to generate/parse respectively, see
379
373
  # generate and parse for their documentation.
380
- def JSON(object, opts = {})
374
+ def JSON(object, *args)
381
375
  if object.respond_to? :to_str
382
- JSON.parse(object.to_str, opts)
376
+ JSON.parse(object.to_str, args.first)
383
377
  else
384
- JSON.generate(object, opts)
378
+ JSON.generate(object, args.first)
385
379
  end
386
380
  end
387
381
  end
@@ -163,6 +163,10 @@ module JSON
163
163
  # the generated JSON, max_nesting = 0 if no maximum is checked.
164
164
  attr_accessor :max_nesting
165
165
 
166
+ # This integer returns the current depth data structure nesting in the
167
+ # generated JSON.
168
+ attr_accessor :depth
169
+
166
170
  def check_max_nesting(depth) # :nodoc:
167
171
  return if @max_nesting.zero?
168
172
  current_nesting = depth + 1
@@ -196,6 +200,7 @@ module JSON
196
200
  @array_nl = opts[:array_nl] if opts.key?(:array_nl)
197
201
  @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
198
202
  @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
203
+ @depth = opts[:depth] || 0
199
204
  if !opts.key?(:max_nesting) # defaults to 19
200
205
  @max_nesting = 19
201
206
  elsif opts[:max_nesting]
@@ -210,7 +215,7 @@ module JSON
210
215
  # passed to the configure method.
211
216
  def to_h
212
217
  result = {}
213
- for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting]
218
+ for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting ascii_only depth]
214
219
  result[iv.intern] = instance_variable_get("@#{iv}")
215
220
  end
216
221
  result
@@ -69,41 +69,42 @@ module JSON
69
69
  # * *object_class*: Defaults to Hash
70
70
  # * *array_class*: Defaults to Array
71
71
  def initialize(source, opts = {})
72
- if defined?(::Encoding)
73
- if source.encoding == ::Encoding::ASCII_8BIT
74
- b = source[0, 4].bytes.to_a
75
- source = case
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)
78
- when b.size >= 4 && b[0] == 0 && b[2] == 0
79
- source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
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)
82
-
83
- when b.size >= 4 && b[1] == 0 && b[3] == 0
84
- source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
85
- else
86
- source.dup
87
- end
88
- else
89
- source = source.encode(::Encoding::UTF_8)
90
- end
91
- source.force_encoding(::Encoding::ASCII_8BIT)
92
- else
93
- b = source
72
+ opts ||= {}
73
+ if defined?(::Encoding)
74
+ if source.encoding == ::Encoding::ASCII_8BIT
75
+ b = source[0, 4].bytes.to_a
94
76
  source = case
95
77
  when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
96
- JSON.iconv('utf-8', 'utf-32be', b)
78
+ source.dup.force_encoding(::Encoding::UTF_32BE).encode!(::Encoding::UTF_8)
97
79
  when b.size >= 4 && b[0] == 0 && b[2] == 0
98
- JSON.iconv('utf-8', 'utf-16be', b)
80
+ source.dup.force_encoding(::Encoding::UTF_16BE).encode!(::Encoding::UTF_8)
99
81
  when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
100
- JSON.iconv('utf-8', 'utf-32le', b)
82
+ source.dup.force_encoding(::Encoding::UTF_32LE).encode!(::Encoding::UTF_8)
83
+
101
84
  when b.size >= 4 && b[1] == 0 && b[3] == 0
102
- JSON.iconv('utf-8', 'utf-16le', b)
85
+ source.dup.force_encoding(::Encoding::UTF_16LE).encode!(::Encoding::UTF_8)
103
86
  else
104
- b
87
+ source.dup
105
88
  end
89
+ else
90
+ source = source.encode(::Encoding::UTF_8)
106
91
  end
92
+ source.force_encoding(::Encoding::ASCII_8BIT)
93
+ else
94
+ b = source
95
+ source = case
96
+ when b.size >= 4 && b[0] == 0 && b[1] == 0 && b[2] == 0
97
+ JSON.iconv('utf-8', 'utf-32be', b)
98
+ when b.size >= 4 && b[0] == 0 && b[2] == 0
99
+ JSON.iconv('utf-8', 'utf-16be', b)
100
+ when b.size >= 4 && b[1] == 0 && b[2] == 0 && b[3] == 0
101
+ JSON.iconv('utf-8', 'utf-32le', b)
102
+ when b.size >= 4 && b[1] == 0 && b[3] == 0
103
+ JSON.iconv('utf-8', 'utf-16le', b)
104
+ else
105
+ b
106
+ end
107
+ end
107
108
  super source
108
109
  if !opts.key?(:max_nesting) # defaults to 19
109
110
  @max_nesting = 19
data/lib/json/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module JSON
2
2
  # JSON version
3
- VERSION = '1.4.4'
3
+ VERSION = '1.4.5'
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:
@@ -102,6 +102,51 @@ EOT
102
102
  assert s[:check_circular?]
103
103
  end
104
104
 
105
+ def test_pretty_state
106
+ state = PRETTY_STATE_PROTOTYPE.dup
107
+ assert_equal({
108
+ :allow_nan => false,
109
+ :array_nl => "\n",
110
+ :ascii_only => false,
111
+ :depth => 0,
112
+ :indent => " ",
113
+ :max_nesting => 19,
114
+ :object_nl => "\n",
115
+ :space => " ",
116
+ :space_before => "",
117
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
118
+ end
119
+
120
+ def test_safe_state
121
+ state = SAFE_STATE_PROTOTYPE.dup
122
+ assert_equal({
123
+ :allow_nan => false,
124
+ :array_nl => "",
125
+ :ascii_only => false,
126
+ :depth => 0,
127
+ :indent => "",
128
+ :max_nesting => 19,
129
+ :object_nl => "",
130
+ :space => "",
131
+ :space_before => "",
132
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
133
+ end
134
+
135
+ def test_fast_state
136
+ state = FAST_STATE_PROTOTYPE.dup
137
+ assert_equal({
138
+ :allow_nan => false,
139
+ :array_nl => "",
140
+ :ascii_only => false,
141
+ :depth => 0,
142
+ :indent => "",
143
+ :max_nesting => 0,
144
+ :object_nl => "",
145
+ :space => "",
146
+ :space_before => "",
147
+ }.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
148
+ end
149
+
105
150
  def test_allow_nan
106
151
  assert_raises(GeneratorError) { generate([JSON::NaN]) }
107
152
  assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_pure
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 4
10
- version: 1.4.4
9
+ - 5
10
+ version: 1.4.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Florian Frank
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-06 00:00:00 +02:00
18
+ date: 2010-08-07 00:00:00 +02:00
19
19
  default_executable: edit_json.rb
20
20
  dependencies: []
21
21