oj 3.13.11 → 3.13.13

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,15 +929,27 @@ 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
 
963
954
  size *= 2;
964
955
  if (size <= len * 2 + pos) {
@@ -981,37 +972,28 @@ void oj_grow_out(Out out, size_t len) {
981
972
 
982
973
  void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
983
974
  assure_size(out, 4);
984
- *out->cur++ = 'n';
985
- *out->cur++ = 'u';
986
- *out->cur++ = 'l';
987
- *out->cur++ = 'l';
975
+ APPEND_CHARS(out->cur, "null", 4);
988
976
  *out->cur = '\0';
989
977
  }
990
978
 
991
979
  void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
992
980
  assure_size(out, 4);
993
- *out->cur++ = 't';
994
- *out->cur++ = 'r';
995
- *out->cur++ = 'u';
996
- *out->cur++ = 'e';
981
+ APPEND_CHARS(out->cur, "true", 4);
997
982
  *out->cur = '\0';
998
983
  }
999
984
 
1000
985
  void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
1001
986
  assure_size(out, 5);
1002
- *out->cur++ = 'f';
1003
- *out->cur++ = 'a';
1004
- *out->cur++ = 'l';
1005
- *out->cur++ = 's';
1006
- *out->cur++ = 'e';
987
+ APPEND_CHARS(out->cur, "false", 5);
1007
988
  *out->cur = '\0';
1008
989
  }
1009
990
 
1010
991
  void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1011
992
  char buf[32];
1012
993
  char * b = buf + sizeof(buf) - 1;
1013
- long long num = rb_num2ll(obj);
994
+ long long num = NUM2LL(obj);
1014
995
  int neg = 0;
996
+ size_t cnt = 0;
1015
997
  bool dump_as_string = false;
1016
998
 
1017
999
  if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
@@ -1042,10 +1024,9 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1042
1024
  if (dump_as_string) {
1043
1025
  *--b = '"';
1044
1026
  }
1045
- assure_size(out, (sizeof(buf) - (b - buf)));
1046
- for (; '\0' != *b; b++) {
1047
- *out->cur++ = *b;
1048
- }
1027
+ cnt = sizeof(buf) - (b - buf) - 1;
1028
+ assure_size(out, cnt);
1029
+ APPEND_CHARS(out->cur, b, cnt);
1049
1030
  *out->cur = '\0';
1050
1031
  }
1051
1032
 
@@ -1061,8 +1042,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1061
1042
  } else {
1062
1043
  assure_size(out, cnt);
1063
1044
  }
1064
- memcpy(out->cur, RSTRING_PTR(rs), cnt);
1065
- out->cur += cnt;
1045
+ APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
1066
1046
  if (dump_as_string) {
1067
1047
  *out->cur++ = '"';
1068
1048
  }
@@ -1072,7 +1052,7 @@ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1072
1052
  // Removed dependencies on math due to problems with CentOS 5.4.
1073
1053
  void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1074
1054
  char buf[64];
1075
- char * b;
1055
+ char *b;
1076
1056
  double d = rb_num2dbl(obj);
1077
1057
  int cnt = 0;
1078
1058
 
@@ -1195,9 +1175,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1195
1175
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
1196
1176
  }
1197
1177
  assure_size(out, cnt);
1198
- for (b = buf; '\0' != *b; b++) {
1199
- *out->cur++ = *b;
1200
- }
1178
+ APPEND_CHARS(out->cur, buf, cnt);
1201
1179
  *out->cur = '\0';
1202
1180
  }
1203
1181
 
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