oj 3.13.11 → 3.13.14

Sign up to get free protection for your applications and to get access to all the features.
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