oj 3.13.11 → 3.13.12

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,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