oj 3.13.11 → 3.13.14

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,34 @@ 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
- }
630
- fclose(f);
614
+
615
+ oj_out_free(&out);
616
+
631
617
  if (!ok) {
632
618
  int err = ferror(f);
619
+ fclose(f);
633
620
 
634
621
  rb_raise(rb_eIOError, "Write failed. [%d:%s]", err, strerror(err));
635
622
  }
623
+ fclose(f);
636
624
  }
637
625
 
626
+ #if !IS_WINDOWS
638
627
  static void write_ready(int fd) {
639
628
  struct pollfd pp;
640
629
  int i;
@@ -649,9 +638,9 @@ static void write_ready(int fd) {
649
638
  rb_raise(rb_eIOError, "write failed. %d %s.", errno, strerror(errno));
650
639
  }
651
640
  }
641
+ #endif
652
642
 
653
643
  void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
654
- char buf[4096];
655
644
  struct _out out;
656
645
  ssize_t size;
657
646
  VALUE clas = rb_obj_class(stream);
@@ -660,9 +649,8 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
660
649
  VALUE s;
661
650
  #endif
662
651
 
663
- out.buf = buf;
664
- out.end = buf + sizeof(buf) - BUFFER_EXTRA;
665
- out.allocated = false;
652
+ oj_out_init(&out);
653
+
666
654
  out.omit_nil = copts->dump_opts.omit_nil;
667
655
  oj_dump_obj_to_json(obj, copts, &out);
668
656
  size = out.cur - out.buf;
@@ -692,20 +680,17 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
692
680
  } else if (rb_respond_to(stream, oj_write_id)) {
693
681
  rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
694
682
  } else {
695
- if (out.allocated) {
696
- xfree(out.buf);
697
- }
683
+ oj_out_free(&out);
698
684
  rb_raise(rb_eArgError, "to_stream() expected an IO Object.");
699
685
  }
700
- if (out.allocated) {
701
- xfree(out.buf);
702
- }
686
+ oj_out_free(&out);
703
687
  }
704
688
 
705
689
  void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) {
706
- rb_encoding *enc = rb_enc_get(obj);
690
+ int idx = RB_ENCODING_GET(obj);
707
691
 
708
- if (oj_utf8_encoding != enc) {
692
+ if (oj_utf8_encoding_index != idx) {
693
+ rb_encoding *enc = rb_enc_from_index(idx);
709
694
  obj = rb_str_conv_enc(obj, enc, oj_utf8_encoding);
710
695
  }
711
696
  oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
@@ -719,7 +704,7 @@ void oj_dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
719
704
 
720
705
  static void debug_raise(const char *orig, size_t cnt, int line) {
721
706
  char buf[1024];
722
- char * b = buf;
707
+ char *b = buf;
723
708
  const char *s = orig;
724
709
  const char *s_end = s + cnt;
725
710
 
@@ -758,7 +743,7 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
758
743
 
759
744
  void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
760
745
  size_t size;
761
- char * cmap;
746
+ char *cmap;
762
747
  const char *orig = str;
763
748
  bool has_hi = false;
764
749
 
@@ -803,10 +788,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
803
788
  *out->cur++ = '"';
804
789
 
805
790
  if (escape1) {
806
- *out->cur++ = '\\';
807
- *out->cur++ = 'u';
808
- *out->cur++ = '0';
809
- *out->cur++ = '0';
791
+ APPEND_CHARS(out->cur, "\\u00", 4);
810
792
  dump_hex((uint8_t)*str, out);
811
793
  cnt--;
812
794
  size--;
@@ -817,8 +799,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
817
799
  if (is_sym) {
818
800
  *out->cur++ = ':';
819
801
  }
820
- memcpy(out->cur, str, cnt);
821
- out->cur += cnt;
802
+ APPEND_CHARS(out->cur, str, cnt);
822
803
  *out->cur++ = '"';
823
804
  } else {
824
805
  const char *end = str + cnt;
@@ -868,10 +849,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
868
849
  break;
869
850
  case '6': // control characters
870
851
  if (*(uint8_t *)str < 0x80) {
871
- *out->cur++ = '\\';
872
- *out->cur++ = 'u';
873
- *out->cur++ = '0';
874
- *out->cur++ = '0';
852
+ APPEND_CHARS(out->cur, "\\u00", 4);
875
853
  dump_hex((uint8_t)*str, out);
876
854
  } else {
877
855
  if (0xe2 == (uint8_t)*str &&
@@ -950,15 +928,27 @@ void oj_dump_obj_to_s(VALUE obj, Out out) {
950
928
 
951
929
  void oj_dump_raw(const char *str, size_t cnt, Out out) {
952
930
  assure_size(out, cnt + 10);
953
- memcpy(out->cur, str, cnt);
954
- out->cur += cnt;
931
+ APPEND_CHARS(out->cur, str, cnt);
955
932
  *out->cur = '\0';
956
933
  }
957
934
 
935
+ void oj_out_init(Out out) {
936
+ out->buf = out->stack_buffer;
937
+ out->cur = out->buf;
938
+ out->end = out->buf + sizeof(out->stack_buffer) - BUFFER_EXTRA;
939
+ out->allocated = false;
940
+ }
941
+
942
+ void oj_out_free(Out out) {
943
+ if (out->allocated) {
944
+ xfree(out->buf); // TBD
945
+ }
946
+ }
947
+
958
948
  void oj_grow_out(Out out, size_t len) {
959
949
  size_t size = out->end - out->buf;
960
950
  long pos = out->cur - out->buf;
961
- char * buf = out->buf;
951
+ char *buf = out->buf;
962
952
 
963
953
  size *= 2;
964
954
  if (size <= len * 2 + pos) {
@@ -981,37 +971,28 @@ void oj_grow_out(Out out, size_t len) {
981
971
 
982
972
  void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
983
973
  assure_size(out, 4);
984
- *out->cur++ = 'n';
985
- *out->cur++ = 'u';
986
- *out->cur++ = 'l';
987
- *out->cur++ = 'l';
974
+ APPEND_CHARS(out->cur, "null", 4);
988
975
  *out->cur = '\0';
989
976
  }
990
977
 
991
978
  void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
992
979
  assure_size(out, 4);
993
- *out->cur++ = 't';
994
- *out->cur++ = 'r';
995
- *out->cur++ = 'u';
996
- *out->cur++ = 'e';
980
+ APPEND_CHARS(out->cur, "true", 4);
997
981
  *out->cur = '\0';
998
982
  }
999
983
 
1000
984
  void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
1001
985
  assure_size(out, 5);
1002
- *out->cur++ = 'f';
1003
- *out->cur++ = 'a';
1004
- *out->cur++ = 'l';
1005
- *out->cur++ = 's';
1006
- *out->cur++ = 'e';
986
+ APPEND_CHARS(out->cur, "false", 5);
1007
987
  *out->cur = '\0';
1008
988
  }
1009
989
 
1010
990
  void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1011
991
  char buf[32];
1012
992
  char * b = buf + sizeof(buf) - 1;
1013
- long long num = rb_num2ll(obj);
993
+ long long num = NUM2LL(obj);
1014
994
  int neg = 0;
995
+ size_t cnt = 0;
1015
996
  bool dump_as_string = false;
1016
997
 
1017
998
  if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
@@ -1042,10 +1023,9 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1042
1023
  if (dump_as_string) {
1043
1024
  *--b = '"';
1044
1025
  }
1045
- assure_size(out, (sizeof(buf) - (b - buf)));
1046
- for (; '\0' != *b; b++) {
1047
- *out->cur++ = *b;
1048
- }
1026
+ cnt = sizeof(buf) - (b - buf) - 1;
1027
+ assure_size(out, cnt);
1028
+ APPEND_CHARS(out->cur, b, cnt);
1049
1029
  *out->cur = '\0';
1050
1030
  }
1051
1031
 
@@ -1061,8 +1041,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1061
1041
  } else {
1062
1042
  assure_size(out, cnt);
1063
1043
  }
1064
- memcpy(out->cur, RSTRING_PTR(rs), cnt);
1065
- out->cur += cnt;
1044
+ APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
1066
1045
  if (dump_as_string) {
1067
1046
  *out->cur++ = '"';
1068
1047
  }
@@ -1072,7 +1051,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1072
1051
  // Removed dependencies on math due to problems with CentOS 5.4.
1073
1052
  void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1074
1053
  char buf[64];
1075
- char * b;
1054
+ char *b;
1076
1055
  double d = rb_num2dbl(obj);
1077
1056
  int cnt = 0;
1078
1057
 
@@ -1195,9 +1174,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1195
1174
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
1196
1175
  }
1197
1176
  assure_size(out, cnt);
1198
- for (b = buf; '\0' != *b; b++) {
1199
- *out->cur++ = *b;
1200
- }
1177
+ APPEND_CHARS(out->cur, buf, cnt);
1201
1178
  *out->cur = '\0';
1202
1179
  }
1203
1180
 
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