oj 3.11.8 → 3.12.3

Sign up to get free protection for your applications and to get access to all the features.
data/ext/oj/object.c CHANGED
@@ -30,11 +30,38 @@ inline static long read_long(const char *str, size_t len) {
30
30
 
31
31
  static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
32
32
  volatile VALUE rkey;
33
+ #if 0
34
+ VALUE *slot;
33
35
 
36
+ if (':' == k1) {
37
+ if (Qnil == (rkey = oj_sym_hash_get(kval->key + 1, kval->klen - 1, &slot))) {
38
+ rkey = rb_str_new(kval->key + 1, kval->klen - 1);
39
+ rkey = oj_encode(rkey);
40
+ rkey = rb_str_intern(rkey);
41
+ *slot = rkey;
42
+ rb_gc_register_address(slot);
43
+ }
44
+ } else if (Yes == pi->options.sym_key) {
45
+ if (Qnil == (rkey = oj_sym_hash_get(kval->key, kval->klen, &slot))) {
46
+ rkey = rb_str_new(kval->key, kval->klen);
47
+ rkey = oj_encode(rkey);
48
+ rkey = rb_str_intern(rkey);
49
+ *slot = rkey;
50
+ rb_gc_register_address(slot);
51
+ }
52
+ } else {
53
+ if (Qnil == (rkey = oj_str_hash_get(kval->key, kval->klen, &slot))) {
54
+ rkey = rb_str_new(kval->key, kval->klen);
55
+ rkey = oj_encode(rkey);
56
+ *slot = rkey;
57
+ rb_gc_register_address(slot);
58
+ }
59
+ }
60
+ #else
34
61
  if (':' == k1) {
35
62
  rkey = rb_str_new(kval->key + 1, kval->klen - 1);
36
63
  rkey = oj_encode(rkey);
37
- rkey = rb_funcall(rkey, oj_to_sym_id, 0);
64
+ rkey = rb_str_intern(rkey);
38
65
  } else {
39
66
  rkey = rb_str_new(kval->key, kval->klen);
40
67
  rkey = oj_encode(rkey);
@@ -42,6 +69,7 @@ static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
42
69
  rkey = rb_str_intern(rkey);
43
70
  }
44
71
  }
72
+ #endif
45
73
  return rkey;
46
74
  }
47
75
 
@@ -405,22 +433,22 @@ void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
405
433
  char *buf = ALLOC_N(char, klen + 2);
406
434
 
407
435
  if ('~' == *key) {
408
- strncpy(buf, key + 1, klen - 1);
436
+ memcpy(buf, key + 1, klen - 1);
409
437
  buf[klen - 1] = '\0';
410
438
  } else {
411
439
  *buf = '@';
412
- strncpy(buf + 1, key, klen);
440
+ memcpy(buf + 1, key, klen);
413
441
  buf[klen + 1] = '\0';
414
442
  }
415
443
  var_id = rb_intern(buf);
416
444
  xfree(buf);
417
445
  } else {
418
446
  if ('~' == *key) {
419
- strncpy(attr, key + 1, klen - 1);
447
+ memcpy(attr, key + 1, klen - 1);
420
448
  attr[klen - 1] = '\0';
421
449
  } else {
422
450
  *attr = '@';
423
- strncpy(attr + 1, key, klen);
451
+ memcpy(attr + 1, key, klen);
424
452
  attr[klen + 1] = '\0';
425
453
  }
426
454
  var_id = rb_intern(attr);
data/ext/oj/oj.c CHANGED
@@ -40,7 +40,6 @@ ID oj_error_id;
40
40
  ID oj_file_id;
41
41
  ID oj_fileno_id;
42
42
  ID oj_ftype_id;
43
- ID oj_has_key_id;
44
43
  ID oj_hash_end_id;
45
44
  ID oj_hash_key_id;
46
45
  ID oj_hash_set_id;
@@ -106,6 +105,8 @@ static VALUE auto_sym;
106
105
  static VALUE bigdecimal_as_decimal_sym;
107
106
  static VALUE bigdecimal_load_sym;
108
107
  static VALUE bigdecimal_sym;
108
+ static VALUE cache_keys_sym;
109
+ static VALUE cache_str_sym;
109
110
  static VALUE circular_sym;
110
111
  static VALUE class_cache_sym;
111
112
  static VALUE compat_bigdecimal_sym;
@@ -186,6 +187,8 @@ struct _options oj_default_options = {
186
187
  No, // safe
187
188
  false, // sec_prec_set
188
189
  No, // ignore_under
190
+ Yes, // cache_keys
191
+ 3, // cache_str
189
192
  0, // int_range_min
190
193
  0, // int_range_max
191
194
  oj_json_class, // create_id
@@ -279,9 +282,11 @@ struct _options oj_default_options = {
279
282
  *used
280
283
  * - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
281
284
  * - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
282
- * - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
283
- * - *:ignore_under* [Boolean] if true then attributes that start with _ are ignored when dumping in
285
+ * - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
286
+ * - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
284
287
  *object or custom mode.
288
+ * - *:cache_keys* [_Boolean_] if true then hash keys are cached
289
+ * - *:cache_str* [_Fixnum_] maximum string value length to cache
285
290
  * - *:integer_range* [_Range_] Dump integers outside range as strings.
286
291
  * - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
287
292
  * - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
@@ -389,11 +394,17 @@ static VALUE get_def_opts(VALUE self) {
389
394
  ? Qtrue
390
395
  : ((No == oj_default_options.safe) ? Qfalse : Qnil));
391
396
  rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
397
+ rb_hash_aset(opts, cache_str_sym, INT2FIX(oj_default_options.cache_str));
392
398
  rb_hash_aset(opts,
393
399
  ignore_under_sym,
394
400
  (Yes == oj_default_options.ignore_under)
395
401
  ? Qtrue
396
402
  : ((No == oj_default_options.ignore_under) ? Qfalse : Qnil));
403
+ rb_hash_aset(opts,
404
+ cache_keys_sym,
405
+ (Yes == oj_default_options.cache_keys)
406
+ ? Qtrue
407
+ : ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
397
408
  switch (oj_default_options.mode) {
398
409
  case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
399
410
  case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
@@ -557,6 +568,8 @@ static VALUE get_def_opts(VALUE self) {
557
568
  * - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
558
569
  * - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
559
570
  *dumping in object or custom mode.
571
+ * - *:cache_keys* [_Boolean_] if true then hash keys are cached
572
+ * - *:cache_str* [_Fixnum_] maximum string vsalue length to cache
560
573
  * - *:integer_range* [_Range_] Dump integers outside range as strings.
561
574
  * - *:trace* [_Boolean_] turn trace on or off.
562
575
  * - *:safe* [_Boolean_] turn safe mimic on or off.
@@ -568,6 +581,14 @@ static VALUE set_def_opts(VALUE self, VALUE opts) {
568
581
  return Qnil;
569
582
  }
570
583
 
584
+ bool oj_hash_has_key(VALUE hash, VALUE key)
585
+ {
586
+ if (Qundef == rb_hash_lookup2(hash, key, Qundef)) {
587
+ return false;
588
+ }
589
+ return true;
590
+ }
591
+
571
592
  void oj_parse_options(VALUE ropts, Options copts) {
572
593
  struct _yesNoOpt ynos[] = {{circular_sym, &copts->circular},
573
594
  {auto_define_sym, &copts->auto_define},
@@ -589,6 +610,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
589
610
  {oj_safe_sym, &copts->safe},
590
611
  {ignore_under_sym, &copts->ignore_under},
591
612
  {oj_create_additions_sym, &copts->create_ok},
613
+ {cache_keys_sym, &copts->cache_keys},
592
614
  {Qnil, 0}};
593
615
  YesNoOpt o;
594
616
  volatile VALUE v;
@@ -597,7 +619,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
597
619
  if (T_HASH != rb_type(ropts)) {
598
620
  return;
599
621
  }
600
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_indent_sym)) {
622
+ if (oj_hash_has_key(ropts, oj_indent_sym)) {
601
623
  v = rb_hash_lookup(ropts, oj_indent_sym);
602
624
  switch (rb_type(v)) {
603
625
  case T_NIL:
@@ -647,6 +669,28 @@ void oj_parse_options(VALUE ropts, Options copts) {
647
669
  copts->float_prec = n;
648
670
  }
649
671
  }
672
+ if (Qnil != (v = rb_hash_lookup(ropts, cache_str_sym))) {
673
+ int n;
674
+
675
+ #ifdef RUBY_INTEGER_UNIFICATION
676
+ if (rb_cInteger != rb_obj_class(v)) {
677
+ rb_raise(rb_eArgError, ":cache_str must be a Integer.");
678
+ }
679
+ #else
680
+ if (T_FIXNUM != rb_type(v)) {
681
+ rb_raise(rb_eArgError, ":cache_str must be a Fixnum.");
682
+ }
683
+ #endif
684
+ n = FIX2INT(v);
685
+ if (0 >= n) {
686
+ copts->cache_str = 0;
687
+ } else {
688
+ if (32 < n) {
689
+ n = 32;
690
+ }
691
+ copts->cache_str = (char)n;
692
+ }
693
+ }
650
694
  if (Qnil != (v = rb_hash_lookup(ropts, sec_prec_sym))) {
651
695
  int n;
652
696
 
@@ -736,7 +780,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
736
780
  if (Qnil != (v = rb_hash_lookup(ropts, compat_bigdecimal_sym))) {
737
781
  copts->compat_bigdec = (Qtrue == v);
738
782
  }
739
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
783
+ if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
740
784
  v = rb_hash_lookup(ropts, oj_decimal_class_sym);
741
785
  if (rb_cFloat == v) {
742
786
  copts->compat_bigdec = false;
@@ -746,7 +790,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
746
790
  rb_raise(rb_eArgError, ":decimal_class must be BigDecimal or Float.");
747
791
  }
748
792
  }
749
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, create_id_sym)) {
793
+ if (oj_hash_has_key(ropts, create_id_sym)) {
750
794
  v = rb_hash_lookup(ropts, create_id_sym);
751
795
  if (Qnil == v) {
752
796
  if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
@@ -768,7 +812,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
768
812
  }
769
813
  }
770
814
  for (o = ynos; 0 != o->attr; o++) {
771
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, o->sym)) {
815
+ if (oj_hash_has_key(ropts, o->sym)) {
772
816
  v = rb_hash_lookup(ropts, o->sym);
773
817
  if (Qnil == v) {
774
818
  *o->attr = NotSet;
@@ -783,7 +827,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
783
827
  }
784
828
  }
785
829
  }
786
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_space_sym)) {
830
+ if (oj_hash_has_key(ropts, oj_space_sym)) {
787
831
  if (Qnil == (v = rb_hash_lookup(ropts, oj_space_sym))) {
788
832
  copts->dump_opts.after_size = 0;
789
833
  *copts->dump_opts.after_sep = '\0';
@@ -798,7 +842,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
798
842
  copts->dump_opts.after_size = (uint8_t)len;
799
843
  }
800
844
  }
801
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_space_before_sym)) {
845
+ if (oj_hash_has_key(ropts, oj_space_before_sym)) {
802
846
  if (Qnil == (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
803
847
  copts->dump_opts.before_size = 0;
804
848
  *copts->dump_opts.before_sep = '\0';
@@ -813,7 +857,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
813
857
  copts->dump_opts.before_size = (uint8_t)len;
814
858
  }
815
859
  }
816
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_nl_sym)) {
860
+ if (oj_hash_has_key(ropts, oj_object_nl_sym)) {
817
861
  if (Qnil == (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
818
862
  copts->dump_opts.hash_size = 0;
819
863
  *copts->dump_opts.hash_nl = '\0';
@@ -828,7 +872,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
828
872
  copts->dump_opts.hash_size = (uint8_t)len;
829
873
  }
830
874
  }
831
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_nl_sym)) {
875
+ if (oj_hash_has_key(ropts, oj_array_nl_sym)) {
832
876
  if (Qnil == (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
833
877
  copts->dump_opts.array_size = 0;
834
878
  *copts->dump_opts.array_nl = '\0';
@@ -877,7 +921,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
877
921
  } else if (Qfalse == v) {
878
922
  copts->escape_mode = JSONEsc;
879
923
  }
880
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
924
+ if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
881
925
  if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
882
926
  copts->hash_class = Qnil;
883
927
  } else {
@@ -885,7 +929,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
885
929
  copts->hash_class = v;
886
930
  }
887
931
  }
888
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
932
+ if (oj_hash_has_key(ropts, oj_object_class_sym)) {
889
933
  if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
890
934
  copts->hash_class = Qnil;
891
935
  } else {
@@ -893,7 +937,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
893
937
  copts->hash_class = v;
894
938
  }
895
939
  }
896
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
940
+ if (oj_hash_has_key(ropts, oj_array_class_sym)) {
897
941
  if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
898
942
  copts->array_class = Qnil;
899
943
  } else {
@@ -902,7 +946,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
902
946
  }
903
947
  }
904
948
  oj_parse_opt_match_string(&copts->str_rx, ropts);
905
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, ignore_sym)) {
949
+ if (oj_hash_has_key(ropts, ignore_sym)) {
906
950
  xfree(copts->ignore);
907
951
  copts->ignore = NULL;
908
952
  if (Qnil != (v = rb_hash_lookup(ropts, ignore_sym))) {
@@ -1200,6 +1244,38 @@ static VALUE safe_load(VALUE self, VALUE doc) {
1200
1244
  * - *io* [_IO__|_String_] IO Object to read from
1201
1245
  */
1202
1246
 
1247
+ struct dump_arg {
1248
+ struct _out *out;
1249
+ struct _options *copts;
1250
+ int argc;
1251
+ VALUE *argv;
1252
+ };
1253
+
1254
+ static VALUE dump_body(VALUE a)
1255
+ {
1256
+ volatile struct dump_arg *arg = (void *)a;
1257
+ VALUE rstr;
1258
+
1259
+ oj_dump_obj_to_json_using_params(*arg->argv, arg->copts, arg->out, arg->argc - 1, arg->argv + 1);
1260
+ if (0 == arg->out->buf) {
1261
+ rb_raise(rb_eNoMemError, "Not enough memory.");
1262
+ }
1263
+ rstr = rb_str_new2(arg->out->buf);
1264
+ rstr = oj_encode(rstr);
1265
+
1266
+ return rstr;
1267
+ }
1268
+
1269
+ static VALUE dump_ensure(VALUE a)
1270
+ {
1271
+ volatile struct dump_arg *arg = (void *)a;
1272
+
1273
+ if (arg->out->allocated) {
1274
+ xfree(arg->out->buf);
1275
+ }
1276
+ return Qnil;
1277
+ }
1278
+
1203
1279
  /* Document-method: dump
1204
1280
  * call-seq: dump(obj, options={})
1205
1281
  *
@@ -1209,9 +1285,9 @@ static VALUE safe_load(VALUE self, VALUE doc) {
1209
1285
  */
1210
1286
  static VALUE dump(int argc, VALUE *argv, VALUE self) {
1211
1287
  char buf[4096];
1288
+ struct dump_arg arg;
1212
1289
  struct _out out;
1213
1290
  struct _options copts = oj_default_options;
1214
- VALUE rstr;
1215
1291
 
1216
1292
  if (1 > argc) {
1217
1293
  rb_raise(rb_eArgError, "wrong number of arguments (0 for 1).");
@@ -1225,21 +1301,18 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1225
1301
  if (CompatMode == copts.mode && copts.escape_mode != ASCIIEsc) {
1226
1302
  copts.escape_mode = JSONEsc;
1227
1303
  }
1228
- out.buf = buf;
1229
- out.end = buf + sizeof(buf) - 10;
1230
- out.allocated = false;
1231
- out.omit_nil = copts.dump_opts.omit_nil;
1232
- out.caller = CALLER_DUMP;
1233
- oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
1234
- if (0 == out.buf) {
1235
- rb_raise(rb_eNoMemError, "Not enough memory.");
1236
- }
1237
- rstr = rb_str_new2(out.buf);
1238
- rstr = oj_encode(rstr);
1239
- if (out.allocated) {
1240
- xfree(out.buf);
1241
- }
1242
- return rstr;
1304
+ arg.out = &out;
1305
+ arg.copts = &copts;
1306
+ arg.argc = argc;
1307
+ arg.argv = argv;
1308
+
1309
+ arg.out->buf = buf;
1310
+ arg.out->end = buf + sizeof(buf) - 10;
1311
+ arg.out->allocated = false;
1312
+ arg.out->omit_nil = copts.dump_opts.omit_nil;
1313
+ arg.out->caller = CALLER_DUMP;
1314
+
1315
+ return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
1243
1316
  }
1244
1317
 
1245
1318
  /* Document-method: to_json
@@ -1636,13 +1709,20 @@ extern VALUE oj_optimize_rails(VALUE self);
1636
1709
 
1637
1710
  /*
1638
1711
  extern void oj_hash_test();
1639
-
1640
1712
  static VALUE
1641
1713
  hash_test(VALUE self) {
1642
1714
  oj_hash_test();
1643
1715
  return Qnil;
1644
1716
  }
1645
1717
  */
1718
+ /*
1719
+ extern void oj_hash_sizes();
1720
+ static VALUE
1721
+ hash_test(VALUE self) {
1722
+ oj_hash_sizes();
1723
+ return Qnil;
1724
+ }
1725
+ */
1646
1726
 
1647
1727
  static VALUE protect_require(VALUE x) {
1648
1728
  rb_require("time");
@@ -1741,7 +1821,6 @@ void Init_oj() {
1741
1821
  oj_file_id = rb_intern("file?");
1742
1822
  oj_fileno_id = rb_intern("fileno");
1743
1823
  oj_ftype_id = rb_intern("ftype");
1744
- oj_has_key_id = rb_intern("has_key?");
1745
1824
  oj_hash_end_id = rb_intern("hash_end");
1746
1825
  oj_hash_key_id = rb_intern("hash_key");
1747
1826
  oj_hash_set_id = rb_intern("hash_set");
@@ -1816,6 +1895,10 @@ void Init_oj() {
1816
1895
  rb_gc_register_address(&bigdecimal_load_sym);
1817
1896
  bigdecimal_sym = ID2SYM(rb_intern("bigdecimal"));
1818
1897
  rb_gc_register_address(&bigdecimal_sym);
1898
+ cache_keys_sym = ID2SYM(rb_intern("cache_keys"));
1899
+ rb_gc_register_address(&cache_keys_sym);
1900
+ cache_str_sym = ID2SYM(rb_intern("cache_str"));
1901
+ rb_gc_register_address(&cache_str_sym);
1819
1902
  circular_sym = ID2SYM(rb_intern("circular"));
1820
1903
  rb_gc_register_address(&circular_sym);
1821
1904
  class_cache_sym = ID2SYM(rb_intern("class_cache"));
data/ext/oj/oj.h CHANGED
@@ -143,6 +143,8 @@ typedef struct _options {
143
143
  char safe; // YesNo
144
144
  char sec_prec_set; // boolean (0 or 1)
145
145
  char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
146
+ char cache_keys; // YexNo
147
+ char cache_str; // string short than or equal to this are cache
146
148
  int64_t int_range_min; // dump numbers below as string
147
149
  int64_t int_range_max; // dump numbers above as string
148
150
  const char * create_id; // 0 or string
@@ -243,6 +245,7 @@ extern VALUE oj_compat_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
243
245
  extern VALUE oj_object_parse_cstr(int argc, VALUE *argv, char *json, size_t len);
244
246
  extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len);
245
247
 
248
+ extern bool oj_hash_has_key(VALUE hash, VALUE key);
246
249
  extern void oj_parse_options(VALUE ropts, Options copts);
247
250
 
248
251
  extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
@@ -325,7 +328,6 @@ extern ID oj_exclude_end_id;
325
328
  extern ID oj_file_id;
326
329
  extern ID oj_fileno_id;
327
330
  extern ID oj_ftype_id;
328
- extern ID oj_has_key_id;
329
331
  extern ID oj_hash_end_id;
330
332
  extern ID oj_hash_key_id;
331
333
  extern ID oj_hash_set_id;
data/ext/oj/parse.h CHANGED
@@ -90,6 +90,9 @@ extern void oj_set_wab_callbacks(ParseInfo pi);
90
90
  extern void oj_sparse2(ParseInfo pi);
91
91
  extern VALUE oj_pi_sparse(int argc, VALUE *argv, ParseInfo pi, int fd);
92
92
 
93
+ extern VALUE oj_cstr_to_value(const char *str, size_t len, size_t cache_str);
94
+ extern VALUE oj_calc_hash_key(ParseInfo pi, Val parent);
95
+
93
96
  static inline void parse_info_init(ParseInfo pi) {
94
97
  memset(pi, 0, sizeof(struct _parseInfo));
95
98
  }
data/ext/oj/scp.c CHANGED
@@ -9,6 +9,7 @@
9
9
  #include <unistd.h>
10
10
 
11
11
  #include "encode.h"
12
+ #include "hash.h"
12
13
  #include "oj.h"
13
14
  #include "parse.h"
14
15
 
@@ -82,19 +83,6 @@ static void end_array(ParseInfo pi) {
82
83
  rb_funcall(pi->handler, oj_array_end_id, 0);
83
84
  }
84
85
 
85
- static VALUE calc_hash_key(ParseInfo pi, Val kval) {
86
- volatile VALUE rkey = kval->key_val;
87
-
88
- if (Qundef == rkey) {
89
- rkey = rb_str_new(kval->key, kval->klen);
90
- rkey = oj_encode(rkey);
91
- if (Yes == pi->options.sym_key) {
92
- rkey = rb_str_intern(rkey);
93
- }
94
- }
95
- return rkey;
96
- }
97
-
98
86
  static VALUE hash_key(ParseInfo pi, const char *key, size_t klen) {
99
87
  return rb_funcall(pi->handler, oj_hash_key_id, 1, rb_str_new(key, klen));
100
88
  }
@@ -107,7 +95,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
107
95
  oj_hash_set_id,
108
96
  3,
109
97
  stack_peek(&pi->stack)->val,
110
- calc_hash_key(pi, kval),
98
+ oj_calc_hash_key(pi, kval),
111
99
  rstr);
112
100
  }
113
101
 
@@ -116,7 +104,7 @@ static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
116
104
  oj_hash_set_id,
117
105
  3,
118
106
  stack_peek(&pi->stack)->val,
119
- calc_hash_key(pi, kval),
107
+ oj_calc_hash_key(pi, kval),
120
108
  oj_num_as_value(ni));
121
109
  }
122
110
 
@@ -125,7 +113,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
125
113
  oj_hash_set_id,
126
114
  3,
127
115
  stack_peek(&pi->stack)->val,
128
- calc_hash_key(pi, kval),
116
+ oj_calc_hash_key(pi, kval),
129
117
  value);
130
118
  }
131
119