oj 3.13.11 → 3.13.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/oj/dump.c CHANGED
@@ -234,7 +234,7 @@ inline static void dump_hex(uint8_t c, Out out) {
234
234
  static void raise_invalid_unicode(const char *str, int len, int pos) {
235
235
  char c;
236
236
  char code[32];
237
- char * cp = code;
237
+ char *cp = code;
238
238
  int i;
239
239
  uint8_t d;
240
240
 
@@ -291,14 +291,12 @@ static const char *dump_unicode(const char *str, const char *end, Out out, const
291
291
  code -= 0x00010000;
292
292
  c1 = ((code >> 10) & 0x000003FF) + 0x0000D800;
293
293
  code = (code & 0x000003FF) + 0x0000DC00;
294
- *out->cur++ = '\\';
295
- *out->cur++ = 'u';
294
+ APPEND_CHARS(out->cur, "\\u", 2);
296
295
  for (i = 3; 0 <= i; i--) {
297
296
  *out->cur++ = hex_chars[(uint8_t)(c1 >> (i * 4)) & 0x0F];
298
297
  }
299
298
  }
300
- *out->cur++ = '\\';
301
- *out->cur++ = 'u';
299
+ APPEND_CHARS(out->cur, "\\u", 2);
302
300
  for (i = 3; 0 <= i; i--) {
303
301
  *out->cur++ = hex_chars[(uint8_t)(code >> (i * 4)) & 0x0F];
304
302
  }
@@ -347,9 +345,7 @@ long oj_check_circular(VALUE obj, Out out) {
347
345
  } else {
348
346
  if (ObjectMode == out->opts->mode) {
349
347
  assure_size(out, 18);
350
- *out->cur++ = '"';
351
- *out->cur++ = '^';
352
- *out->cur++ = 'r';
348
+ APPEND_CHARS(out->cur, "\"^r", 3);
353
349
  dump_ulong(id, out);
354
350
  *out->cur++ = '"';
355
351
  }
@@ -361,9 +357,9 @@ long oj_check_circular(VALUE obj, Out out) {
361
357
 
362
358
  void oj_dump_time(VALUE obj, Out out, int withZone) {
363
359
  char buf[64];
364
- char * b = buf + sizeof(buf) - 1;
360
+ char *b = buf + sizeof(buf) - 1;
365
361
  long size;
366
- char * dot;
362
+ char *dot;
367
363
  int neg = 0;
368
364
  long one = 1000000000;
369
365
  long long sec;
@@ -379,12 +375,12 @@ void oj_dump_time(VALUE obj, Out out, int withZone) {
379
375
  sec = (long long)ts.tv_sec;
380
376
  nsec = ts.tv_nsec;
381
377
  } else {
382
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
383
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
378
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
379
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
384
380
  }
385
381
  #else
386
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
387
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
382
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
383
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
388
384
  #endif
389
385
 
390
386
  *b-- = '\0';
@@ -451,8 +447,7 @@ void oj_dump_time(VALUE obj, Out out, int withZone) {
451
447
  b++;
452
448
  size = sizeof(buf) - (b - buf) - 1;
453
449
  assure_size(out, size);
454
- memcpy(out->cur, b, size);
455
- out->cur += size;
450
+ APPEND_CHARS(out->cur, b, size);
456
451
  *out->cur = '\0';
457
452
  }
458
453
 
@@ -479,12 +474,12 @@ void oj_dump_xml_time(VALUE obj, Out out) {
479
474
  sec = ts.tv_sec;
480
475
  nsec = ts.tv_nsec;
481
476
  } else {
482
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
483
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
477
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
478
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
484
479
  }
485
480
  #else
486
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
487
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
481
+ sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
482
+ nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
488
483
  #endif
489
484
 
490
485
  assure_size(out, 36);
@@ -565,12 +560,8 @@ void oj_dump_obj_to_json(VALUE obj, Options copts, Out out) {
565
560
 
566
561
  void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv) {
567
562
  if (0 == out->buf) {
568
- out->buf = ALLOC_N(char, 4096);
569
- // 1 less than end plus extra for possible errors
570
- out->end = out->buf + 4095 - BUFFER_EXTRA;
571
- out->allocated = true;
563
+ oj_out_init(out);
572
564
  }
573
- out->cur = out->buf;
574
565
  out->circ_cnt = 0;
575
566
  out->opts = copts;
576
567
  out->hash_cnt = 0;
@@ -605,36 +596,35 @@ void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int arg
605
596
  }
606
597
 
607
598
  void oj_write_obj_to_file(VALUE obj, const char *path, Options copts) {
608
- char buf[4096];
609
599
  struct _out out;
610
600
  size_t size;
611
- FILE * f;
601
+ FILE *f;
612
602
  int ok;
613
603
 
614
- out.buf = buf;
615
- out.end = buf + sizeof(buf) - BUFFER_EXTRA;
616
- out.allocated = false;
604
+ oj_out_init(&out);
605
+
617
606
  out.omit_nil = copts->dump_opts.omit_nil;
618
607
  oj_dump_obj_to_json(obj, copts, &out);
619
608
  size = out.cur - out.buf;
620
609
  if (0 == (f = fopen(path, "w"))) {
621
- if (out.allocated) {
622
- xfree(out.buf);
623
- }
610
+ oj_out_free(&out);
624
611
  rb_raise(rb_eIOError, "%s", strerror(errno));
625
612
  }
626
613
  ok = (size == fwrite(out.buf, 1, size, f));
627
- if (out.allocated) {
628
- xfree(out.buf);
629
- }
614
+
615
+ oj_out_free(&out);
616
+
630
617
  fclose(f);
631
618
  if (!ok) {
632
619
  int err = ferror(f);
620
+ fclose(f);
633
621
 
634
622
  rb_raise(rb_eIOError, "Write failed. [%d:%s]", err, strerror(err));
635
623
  }
624
+ fclose(f);
636
625
  }
637
626
 
627
+ #if !IS_WINDOWS
638
628
  static void write_ready(int fd) {
639
629
  struct pollfd pp;
640
630
  int i;
@@ -649,9 +639,9 @@ static void write_ready(int fd) {
649
639
  rb_raise(rb_eIOError, "write failed. %d %s.", errno, strerror(errno));
650
640
  }
651
641
  }
642
+ #endif
652
643
 
653
644
  void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
654
- char buf[4096];
655
645
  struct _out out;
656
646
  ssize_t size;
657
647
  VALUE clas = rb_obj_class(stream);
@@ -660,9 +650,8 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
660
650
  VALUE s;
661
651
  #endif
662
652
 
663
- out.buf = buf;
664
- out.end = buf + sizeof(buf) - BUFFER_EXTRA;
665
- out.allocated = false;
653
+ oj_out_init(&out);
654
+
666
655
  out.omit_nil = copts->dump_opts.omit_nil;
667
656
  oj_dump_obj_to_json(obj, copts, &out);
668
657
  size = out.cur - out.buf;
@@ -692,20 +681,17 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
692
681
  } else if (rb_respond_to(stream, oj_write_id)) {
693
682
  rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
694
683
  } else {
695
- if (out.allocated) {
696
- xfree(out.buf);
697
- }
684
+ oj_out_free(&out);
698
685
  rb_raise(rb_eArgError, "to_stream() expected an IO Object.");
699
686
  }
700
- if (out.allocated) {
701
- xfree(out.buf);
702
- }
687
+ oj_out_free(&out);
703
688
  }
704
689
 
705
690
  void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) {
706
- rb_encoding *enc = rb_enc_get(obj);
691
+ int idx = RB_ENCODING_GET(obj);
707
692
 
708
- if (oj_utf8_encoding != enc) {
693
+ if (oj_utf8_encoding_index != idx) {
694
+ rb_encoding *enc = rb_enc_from_index(idx);
709
695
  obj = rb_str_conv_enc(obj, enc, oj_utf8_encoding);
710
696
  }
711
697
  oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
@@ -719,7 +705,7 @@ void oj_dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
719
705
 
720
706
  static void debug_raise(const char *orig, size_t cnt, int line) {
721
707
  char buf[1024];
722
- char * b = buf;
708
+ char *b = buf;
723
709
  const char *s = orig;
724
710
  const char *s_end = s + cnt;
725
711
 
@@ -758,7 +744,7 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
758
744
 
759
745
  void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
760
746
  size_t size;
761
- char * cmap;
747
+ char *cmap;
762
748
  const char *orig = str;
763
749
  bool has_hi = false;
764
750
 
@@ -803,10 +789,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
803
789
  *out->cur++ = '"';
804
790
 
805
791
  if (escape1) {
806
- *out->cur++ = '\\';
807
- *out->cur++ = 'u';
808
- *out->cur++ = '0';
809
- *out->cur++ = '0';
792
+ APPEND_CHARS(out->cur, "\\u00", 4);
810
793
  dump_hex((uint8_t)*str, out);
811
794
  cnt--;
812
795
  size--;
@@ -817,8 +800,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
817
800
  if (is_sym) {
818
801
  *out->cur++ = ':';
819
802
  }
820
- memcpy(out->cur, str, cnt);
821
- out->cur += cnt;
803
+ APPEND_CHARS(out->cur, str, cnt);
822
804
  *out->cur++ = '"';
823
805
  } else {
824
806
  const char *end = str + cnt;
@@ -868,10 +850,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
868
850
  break;
869
851
  case '6': // control characters
870
852
  if (*(uint8_t *)str < 0x80) {
871
- *out->cur++ = '\\';
872
- *out->cur++ = 'u';
873
- *out->cur++ = '0';
874
- *out->cur++ = '0';
853
+ APPEND_CHARS(out->cur, "\\u00", 4);
875
854
  dump_hex((uint8_t)*str, out);
876
855
  } else {
877
856
  if (0xe2 == (uint8_t)*str &&
@@ -950,16 +929,29 @@ void oj_dump_obj_to_s(VALUE obj, Out out) {
950
929
 
951
930
  void oj_dump_raw(const char *str, size_t cnt, Out out) {
952
931
  assure_size(out, cnt + 10);
953
- memcpy(out->cur, str, cnt);
954
- out->cur += cnt;
932
+ APPEND_CHARS(out->cur, str, cnt);
955
933
  *out->cur = '\0';
956
934
  }
957
935
 
936
+ void oj_out_init(Out out) {
937
+ out->buf = out->stack_buffer;
938
+ out->cur = out->buf;
939
+ out->end = out->buf + sizeof(out->stack_buffer) - BUFFER_EXTRA;
940
+ out->allocated = false;
941
+ }
942
+
943
+ void oj_out_free(Out out) {
944
+ if (out->allocated) {
945
+ xfree(out->buf); // TBD
946
+ }
947
+ }
948
+
958
949
  void oj_grow_out(Out out, size_t len) {
959
950
  size_t size = out->end - out->buf;
960
951
  long pos = out->cur - out->buf;
961
- char * buf = out->buf;
952
+ char *buf = out->buf;
962
953
 
954
+ printf("*** grow %ld\n", len);
963
955
  size *= 2;
964
956
  if (size <= len * 2 + pos) {
965
957
  size += len;
@@ -981,37 +973,28 @@ void oj_grow_out(Out out, size_t len) {
981
973
 
982
974
  void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
983
975
  assure_size(out, 4);
984
- *out->cur++ = 'n';
985
- *out->cur++ = 'u';
986
- *out->cur++ = 'l';
987
- *out->cur++ = 'l';
976
+ APPEND_CHARS(out->cur, "null", 4);
988
977
  *out->cur = '\0';
989
978
  }
990
979
 
991
980
  void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
992
981
  assure_size(out, 4);
993
- *out->cur++ = 't';
994
- *out->cur++ = 'r';
995
- *out->cur++ = 'u';
996
- *out->cur++ = 'e';
982
+ APPEND_CHARS(out->cur, "true", 4);
997
983
  *out->cur = '\0';
998
984
  }
999
985
 
1000
986
  void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
1001
987
  assure_size(out, 5);
1002
- *out->cur++ = 'f';
1003
- *out->cur++ = 'a';
1004
- *out->cur++ = 'l';
1005
- *out->cur++ = 's';
1006
- *out->cur++ = 'e';
988
+ APPEND_CHARS(out->cur, "false", 5);
1007
989
  *out->cur = '\0';
1008
990
  }
1009
991
 
1010
992
  void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1011
993
  char buf[32];
1012
994
  char * b = buf + sizeof(buf) - 1;
1013
- long long num = rb_num2ll(obj);
995
+ long long num = NUM2LL(obj);
1014
996
  int neg = 0;
997
+ size_t cnt = 0;
1015
998
  bool dump_as_string = false;
1016
999
 
1017
1000
  if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
@@ -1042,10 +1025,9 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1042
1025
  if (dump_as_string) {
1043
1026
  *--b = '"';
1044
1027
  }
1045
- assure_size(out, (sizeof(buf) - (b - buf)));
1046
- for (; '\0' != *b; b++) {
1047
- *out->cur++ = *b;
1048
- }
1028
+ cnt = sizeof(buf) - (b - buf) - 1;
1029
+ assure_size(out, cnt);
1030
+ APPEND_CHARS(out->cur, b, cnt);
1049
1031
  *out->cur = '\0';
1050
1032
  }
1051
1033
 
@@ -1061,8 +1043,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1061
1043
  } else {
1062
1044
  assure_size(out, cnt);
1063
1045
  }
1064
- memcpy(out->cur, RSTRING_PTR(rs), cnt);
1065
- out->cur += cnt;
1046
+ APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
1066
1047
  if (dump_as_string) {
1067
1048
  *out->cur++ = '"';
1068
1049
  }
@@ -1072,7 +1053,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1072
1053
  // Removed dependencies on math due to problems with CentOS 5.4.
1073
1054
  void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1074
1055
  char buf[64];
1075
- char * b;
1056
+ char *b;
1076
1057
  double d = rb_num2dbl(obj);
1077
1058
  int cnt = 0;
1078
1059
 
@@ -1195,9 +1176,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1195
1176
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
1196
1177
  }
1197
1178
  assure_size(out, cnt);
1198
- for (b = buf; '\0' != *b; b++) {
1199
- *out->cur++ = *b;
1200
- }
1179
+ APPEND_CHARS(out->cur, buf, cnt);
1201
1180
  *out->cur = '\0';
1202
1181
  }
1203
1182
 
data/ext/oj/dump.h CHANGED
@@ -32,6 +32,11 @@ extern void oj_dump_obj_to_s(VALUE obj, Out out);
32
32
 
33
33
  extern const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp);
34
34
 
35
+ // initialize an out buffer with the provided stack allocated memory
36
+ extern void oj_out_init(Out out);
37
+ // clean up the out buffer if it uses heap allocated memory
38
+ extern void oj_out_free(Out out);
39
+
35
40
  extern void oj_grow_out(Out out, size_t len);
36
41
  extern long oj_check_circular(VALUE obj, Out out);
37
42
 
@@ -62,9 +67,8 @@ inline static void fill_indent(Out out, int cnt) {
62
67
  if (0 < out->indent) {
63
68
  cnt *= out->indent;
64
69
  *out->cur++ = '\n';
65
- for (; 0 < cnt; cnt--) {
66
- *out->cur++ = ' ';
67
- }
70
+ memset(out->cur, ' ', cnt);
71
+ out->cur += cnt;
68
72
  }
69
73
  }
70
74
 
@@ -83,8 +87,9 @@ inline static bool dump_ignore(Options opts, VALUE obj) {
83
87
  }
84
88
 
85
89
  inline static void dump_ulong(unsigned long num, Out out) {
86
- char buf[32];
87
- char *b = buf + sizeof(buf) - 1;
90
+ char buf[32];
91
+ char *b = buf + sizeof(buf) - 1;
92
+ size_t cnt = 0;
88
93
 
89
94
  *b-- = '\0';
90
95
  if (0 < num) {
@@ -95,9 +100,8 @@ inline static void dump_ulong(unsigned long num, Out out) {
95
100
  } else {
96
101
  *b = '0';
97
102
  }
98
- for (; '\0' != *b; b++) {
99
- *out->cur++ = *b;
100
- }
103
+ cnt = sizeof(buf) - (b - buf) - 1;
104
+ APPEND_CHARS(out->cur, b, cnt);
101
105
  *out->cur = '\0';
102
106
  }
103
107