oj 3.7.12 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 596316b0a9a9e4fa7a82486f0589182f15a1c0c679d2d58f50357a291720cbfa
4
- data.tar.gz: 3d58bd1344943d671222f1a7412c77731ecce70ddd3469a03ad15263374c243e
3
+ metadata.gz: a19be14b516dee300d722fd94e2ffc33415e046bec08a2e6bc62a2585967d616
4
+ data.tar.gz: 5c2d36263070e4ae9313657cdc0e56beb414bdd9c9025f5d7b2d5d3088ecab9f
5
5
  SHA512:
6
- metadata.gz: 4273557f2d93c634e3a9ffc789a503f80ee5ca80a8031c1406a63a3e926648dd15294faa8820d6f6c63a625b9be4a34dd36bbde954ba8f68fe418f7182a84f55
7
- data.tar.gz: ad6468ca75db3d8ebc792fcabbf417490c2cfe2927ab4859ef1c059fe36b8bad1c311fa03608a878350dd8324d3ab75887728a6ec4af1ffb1ea8739027642c69
6
+ metadata.gz: aef03660a2a58f825e7776b230627229fc8a22b92bf748146b67b3c505bb62f4ca1ab6376450786ae67a9c1e15cae2095e0cbde92787fdcd8f72b5a28ff63ee8
7
+ data.tar.gz: c17b96a8433a4115aeb2d5367ca05d6739cfc9ab4c8471fd0f5c69b103e5b67f534dfd579c08133dc94315ebfa17ef1f077b9cc5a12ecb4d42431d4df8a57f67
data/README.md CHANGED
@@ -65,7 +65,7 @@ See [{file:CHANGELOG.md}](CHANGELOG.md)
65
65
 
66
66
  ## Links
67
67
 
68
- - *Documentation*: http://www.ohler.com/oj/doc, http://rubydoc.info/gems/oj
68
+ - *Documentation*: http://www.ohler.com/oj/doc, http://rubydoc.info/gems/oj
69
69
 
70
70
  - *GitHub* *repo*: https://github.com/ohler55/oj
71
71
 
@@ -93,4 +93,12 @@ Follow [@peterohler on Twitter](http://twitter.com/peterohler) for announcements
93
93
 
94
94
  - *OjC, a C JSON parser*: https://www.ohler.com/ojc also at https://github.com/ohler55/ojc
95
95
 
96
- - *Piper Push Cache, push JSON to browsers*: http://www.piperpushcache.com
96
+ - *Agoo, a high performance Ruby web server supporting GraphQL on GitHub*: https://github.com/ohler55/agoo
97
+
98
+ - *Agoo-C, a high performance C web server supporting GraphQL on GitHub*: https://github.com/ohler55/agoo-c
99
+
100
+ #### Contributing
101
+
102
+ + Provide a Pull Request off the `develop` branch.
103
+ + Report a bug
104
+ + Suggest an idea
@@ -115,7 +115,7 @@ date_dump(VALUE obj, int depth, Out out) {
115
115
  } else {
116
116
  volatile VALUE v;
117
117
  volatile VALUE ov;
118
-
118
+
119
119
  switch (out->opts->time_format) {
120
120
  case RubyTime:
121
121
  case XmlTime:
@@ -150,7 +150,7 @@ date_dump(VALUE obj, int depth, Out out) {
150
150
  static VALUE
151
151
  date_load(VALUE clas, VALUE args) {
152
152
  volatile VALUE v;
153
-
153
+
154
154
  if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
155
155
  return rb_funcall(oj_date_class, rb_intern("parse"), 1, v);
156
156
  }
@@ -160,7 +160,7 @@ date_load(VALUE clas, VALUE args) {
160
160
  static VALUE
161
161
  datetime_load(VALUE clas, VALUE args) {
162
162
  volatile VALUE v;
163
-
163
+
164
164
  if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
165
165
  return rb_funcall(oj_datetime_class, rb_intern("parse"), 1, v);
166
166
  }
@@ -209,7 +209,7 @@ range_dump(VALUE obj, int depth, Out out) {
209
209
  static VALUE
210
210
  range_load(VALUE clas, VALUE args) {
211
211
  VALUE nargs[3];
212
-
212
+
213
213
  nargs[0] = rb_hash_aref(args, rb_id2str(oj_begin_id));
214
214
  nargs[1] = rb_hash_aref(args, rb_id2str(oj_end_id));
215
215
  nargs[2] = rb_hash_aref(args, rb_id2str(oj_exclude_end_id));
@@ -250,7 +250,7 @@ rational_load(VALUE clas, VALUE args) {
250
250
  static VALUE
251
251
  regexp_load(VALUE clas, VALUE args) {
252
252
  volatile VALUE v;
253
-
253
+
254
254
  if (Qnil != (v = rb_hash_aref(args, rb_str_new2("s")))) {
255
255
  return rb_funcall(rb_cRegexp, oj_new_id, 1, v);
256
256
  }
@@ -423,7 +423,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
423
423
  v = rb_funcall(obj, *odd->attrs, 0);
424
424
  if (Qundef == v || T_STRING != rb_type(v)) {
425
425
  rb_raise(rb_eEncodingError, "Invalid type for raw JSON.\n");
426
- } else {
426
+ } else {
427
427
  const char *s = rb_string_value_ptr((VALUE*)&v);
428
428
  int len = (int)RSTRING_LEN(v);
429
429
  const char *name = rb_id2name(*odd->attrs);
@@ -459,7 +459,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
459
459
  char *n;
460
460
  char *end;
461
461
  ID i;
462
-
462
+
463
463
  if (sizeof(nbuf) <= nlen) {
464
464
  if (NULL == (n2 = strdup(name))) {
465
465
  rb_raise(rb_eNoMemError, "for attribute name.");
@@ -497,7 +497,10 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
497
497
  // Return class if still needs dumping.
498
498
  static VALUE
499
499
  dump_common(VALUE obj, int depth, Out out) {
500
- if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
500
+
501
+ if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
502
+ oj_dump_raw_json(obj, depth, out);
503
+ } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
501
504
  volatile VALUE rs;
502
505
  const char *s;
503
506
  int len;
@@ -608,7 +611,7 @@ dump_attr_cb(ID key, VALUE value, Out out) {
608
611
  oj_dump_custom_val(value, depth, out, true);
609
612
  out->depth = depth;
610
613
  *out->cur++ = ',';
611
-
614
+
612
615
  return ST_CONTINUE;
613
616
  }
614
617
 
@@ -780,7 +783,7 @@ static void
780
783
  dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
781
784
  long id = oj_check_circular(obj, out);
782
785
  VALUE clas;
783
-
786
+
784
787
  if (0 > id) {
785
788
  oj_dump_nil(Qnil, depth, out, false);
786
789
  } else if (Qnil != (clas = dump_common(obj, depth, out))) {
@@ -793,7 +796,7 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
793
796
  size_t size = d2 * out->indent + d3 * out->indent + 3;
794
797
  const char *name;
795
798
  int cnt;
796
- size_t len;
799
+ size_t len;
797
800
 
798
801
  assure_size(out, size);
799
802
  if (clas == rb_cRange) {
@@ -1113,7 +1116,7 @@ static void
1113
1116
  array_append_num(ParseInfo pi, NumInfo ni) {
1114
1117
  Val parent = stack_peek(&pi->stack);
1115
1118
  volatile VALUE rval = oj_num_as_value(ni);
1116
-
1119
+
1117
1120
  rb_ary_push(parent->val, rval);
1118
1121
  if (Yes == pi->options.trace) {
1119
1122
  oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
@@ -15,6 +15,7 @@
15
15
  #include "cache8.h"
16
16
  #include "dump.h"
17
17
  #include "odd.h"
18
+ #include "trace.h"
18
19
  #include "util.h"
19
20
 
20
21
  // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
@@ -166,7 +167,7 @@ hixss_friendly_size(const uint8_t *str, size_t len) {
166
167
  size_t size = 0;
167
168
  size_t i = len;
168
169
  bool check = false;
169
-
170
+
170
171
  for (; 0 < i; str++, i--) {
171
172
  size += hixss_friendly_chars[*str];
172
173
  if (0 != (0x80 & *str)) {
@@ -201,7 +202,7 @@ rails_friendly_size(const uint8_t *str, size_t len) {
201
202
  const char*
202
203
  oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp) {
203
204
  const char *str = NULL;
204
-
205
+
205
206
  if (AutoNan == opt) {
206
207
  switch (mode) {
207
208
  case CompatMode: opt = WordNan; break;
@@ -323,7 +324,7 @@ dump_unicode(const char *str, const char *end, Out out, const char *orig) {
323
324
  *out->cur++ = 'u';
324
325
  for (i = 3; 0 <= i; i--) {
325
326
  *out->cur++ = hex_chars[(uint8_t)(code >> (i * 4)) & 0x0F];
326
- }
327
+ }
327
328
  return str - 1;
328
329
  }
329
330
 
@@ -331,7 +332,7 @@ static const char*
331
332
  check_unicode(const char *str, const char *end, const char *orig) {
332
333
  uint8_t b = *(uint8_t*)str;
333
334
  int cnt = 0;
334
-
335
+
335
336
  if (0xC0 == (0xE0 & b)) {
336
337
  cnt = 1;
337
338
  } else if (0xE0 == (0xF0 & b)) {
@@ -411,7 +412,7 @@ oj_dump_time(VALUE obj, Out out, int withZone) {
411
412
  sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
412
413
  nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
413
414
  #endif
414
-
415
+
415
416
  *b-- = '\0';
416
417
  if (withZone) {
417
418
  long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
@@ -740,6 +741,30 @@ debug_raise(const char *orig, size_t cnt, int line) {
740
741
  rb_raise(oj_json_generator_error_class, "Partial character in string. %s @ %d", buf, line);
741
742
  }
742
743
 
744
+ void
745
+ oj_dump_raw_json(VALUE obj, int depth, Out out) {
746
+ if (oj_string_writer_class == rb_obj_class(obj)) {
747
+ StrWriter sw = (StrWriter)DATA_PTR(obj);
748
+ size_t len = sw->out.cur - sw->out.buf;
749
+
750
+ if (0 < len) {
751
+ len--;
752
+ }
753
+ oj_dump_raw(sw->out.buf, len, out);
754
+ } else {
755
+ volatile VALUE jv;
756
+
757
+ if (Yes == out->opts->trace) {
758
+ oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
759
+ }
760
+ jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
761
+ if (Yes == out->opts->trace) {
762
+ oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
763
+ }
764
+ oj_dump_raw(rb_string_value_ptr((VALUE*)&jv), (size_t)RSTRING_LEN(jv), out);
765
+ }
766
+ }
767
+
743
768
  void
744
769
  oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
745
770
  size_t size;
@@ -801,7 +826,7 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
801
826
  } else {
802
827
  const char *end = str + cnt;
803
828
  const char *check_start = str;
804
-
829
+
805
830
  if (is_sym) {
806
831
  *out->cur++ = ':';
807
832
  }
@@ -867,13 +892,13 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
867
892
  break; // ignore, should never happen if the table is correct
868
893
  }
869
894
  }
870
- *out->cur++ = '"';
895
+ *out->cur++ = '"';
871
896
  }
872
897
  if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 0 < str - orig && 0 != (0x80 & *(str - 1))) {
873
898
  uint8_t c = (uint8_t)*(str - 1);
874
899
  int i;
875
900
  int scnt = (int)(str - orig);
876
-
901
+
877
902
  // Last utf-8 characters must be 0x10xxxxxx. The start must be
878
903
  // 0x110xxxxx for 2 characters, 0x1110xxxx for 3, and 0x11110xxx for
879
904
  // 4.
@@ -939,7 +964,7 @@ oj_grow_out(Out out, size_t len) {
939
964
  size_t size = out->end - out->buf;
940
965
  long pos = out->cur - out->buf;
941
966
  char *buf = out->buf;
942
-
967
+
943
968
  size *= 2;
944
969
  if (size <= len * 2 + pos) {
945
970
  size += len;
@@ -996,24 +1021,21 @@ oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
996
1021
  char *b = buf + sizeof(buf) - 1;
997
1022
  long long num = rb_num2ll(obj);
998
1023
  int neg = 0;
999
- bool dump_as_string = false;
1024
+ bool dump_as_string = false;
1000
1025
 
1001
- if (out->opts->integer_range_max != 0 && out->opts->integer_range_min != 0 &&
1002
- (out->opts->integer_range_max < num || out->opts->integer_range_min > num)) {
1026
+ if (out->opts->integer_range_max != 0 && out->opts->integer_range_min != 0 &&
1027
+ (out->opts->integer_range_max < num || out->opts->integer_range_min > num)) {
1003
1028
  dump_as_string = true;
1004
- }
1005
-
1029
+ }
1006
1030
  if (0 > num) {
1007
1031
  neg = 1;
1008
1032
  num = -num;
1009
1033
  }
1010
-
1011
1034
  *b-- = '\0';
1012
1035
 
1013
- if (dump_as_string) {
1036
+ if (dump_as_string) {
1014
1037
  *b-- = '"';
1015
- }
1016
-
1038
+ }
1017
1039
  if (0 < num) {
1018
1040
  for (; 0 < num; num /= 10, b--) {
1019
1041
  *b = (num % 10) + '0';
@@ -1026,11 +1048,9 @@ oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1026
1048
  } else {
1027
1049
  *b = '0';
1028
1050
  }
1029
-
1030
- if (dump_as_string) {
1051
+ if (dump_as_string) {
1031
1052
  *--b = '"';
1032
- }
1033
-
1053
+ }
1034
1054
  assure_size(out, (sizeof(buf) - (b - buf)));
1035
1055
  for (; '\0' != *b; b++) {
1036
1056
  *out->cur++ = *b;
@@ -1045,7 +1065,7 @@ oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1045
1065
  bool dump_as_string = false;
1046
1066
 
1047
1067
  if (out->opts->integer_range_max != 0 || out->opts->integer_range_min != 0) { // Bignum cannot be inside of Fixnum range
1048
- dump_as_string = true;
1068
+ dump_as_string = true;
1049
1069
  assure_size(out, cnt + 2);
1050
1070
  *out->cur++ = '"';
1051
1071
  } else {
@@ -1083,7 +1103,7 @@ oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1083
1103
  cnt = sizeof(inf_val) - 1;
1084
1104
  } else {
1085
1105
  NanDump nd = out->opts->dump_opts.nan_dump;
1086
-
1106
+
1087
1107
  if (AutoNan == nd) {
1088
1108
  switch (out->opts->mode) {
1089
1109
  case CompatMode: nd = WordNan; break;
@@ -1118,7 +1138,7 @@ oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1118
1138
  cnt = sizeof(ninf_val) - 1;
1119
1139
  } else {
1120
1140
  NanDump nd = out->opts->dump_opts.nan_dump;
1121
-
1141
+
1122
1142
  if (AutoNan == nd) {
1123
1143
  switch (out->opts->mode) {
1124
1144
  case CompatMode: nd = WordNan; break;
@@ -1152,7 +1172,7 @@ oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1152
1172
  cnt = sizeof(ninf_val) - 1;
1153
1173
  } else {
1154
1174
  NanDump nd = out->opts->dump_opts.nan_dump;
1155
-
1175
+
1156
1176
  if (AutoNan == nd) {
1157
1177
  switch (out->opts->mode) {
1158
1178
  case ObjectMode: nd = HugeNan; break;
@@ -45,6 +45,8 @@ extern void oj_dump_rails_val(VALUE obj, int depth, Out out);
45
45
  extern void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok);
46
46
  extern void oj_dump_wab_val(VALUE obj, int depth, Out out);
47
47
 
48
+ extern void oj_dump_raw_json(VALUE obj, int depth, Out out);
49
+
48
50
  extern VALUE oj_add_to_json(int argc, VALUE *argv, VALUE self);
49
51
  extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
50
52
 
@@ -64,12 +64,10 @@ dump_values_array(VALUE *values, int depth, Out out) {
64
64
  } else {
65
65
  if (out->opts->dump_opts.use) {
66
66
  size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 2;
67
- } else {
68
- size = d2 * out->indent + 3;
69
- }
70
- if (out->opts->dump_opts.use) {
71
67
  size += out->opts->dump_opts.array_size;
72
68
  size += out->opts->dump_opts.indent_size;
69
+ } else {
70
+ size = d2 * out->indent + 3;
73
71
  }
74
72
  for (; Qundef != *values; values++) {
75
73
  assure_size(out, size);
@@ -80,6 +78,7 @@ dump_values_array(VALUE *values, int depth, Out out) {
80
78
  }
81
79
  if (0 < out->opts->dump_opts.indent_size) {
82
80
  int i;
81
+
83
82
  for (i = d2; 0 < i; i--) {
84
83
  strcpy(out->cur, out->opts->dump_opts.indent_str);
85
84
  out->cur += out->opts->dump_opts.indent_size;
@@ -155,7 +154,7 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
155
154
  if (as_ok && !oj_use_hash_alt && rb_obj_class(a) != rb_cArray && rb_respond_to(a, oj_to_json_id)) {
156
155
  dump_to_json(a, out);
157
156
  return;
158
- }
157
+ }
159
158
  cnt = (int)RARRAY_LEN(a);
160
159
  *out->cur++ = '[';
161
160
  assure_size(out, 2);
@@ -190,9 +189,9 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
190
189
  *out->cur++ = ',';
191
190
  }
192
191
  }
193
- size = depth * out->indent + 1;
194
- assure_size(out, size);
195
192
  if (out->opts->dump_opts.use) {
193
+ size = out->opts->dump_opts.array_size + out->opts->dump_opts.indent_size * depth + 1;
194
+ assure_size(out, size);
196
195
  if (0 < out->opts->dump_opts.array_size) {
197
196
  strcpy(out->cur, out->opts->dump_opts.array_nl);
198
197
  out->cur += out->opts->dump_opts.array_size;
@@ -206,6 +205,8 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
206
205
  }
207
206
  }
208
207
  } else {
208
+ size = depth * out->indent + 1;
209
+ assure_size(out, size);
209
210
  fill_indent(out, depth);
210
211
  }
211
212
  *out->cur++ = ']';
@@ -715,7 +716,7 @@ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
715
716
  if (as_ok && !oj_use_hash_alt && rb_obj_class(obj) != rb_cHash && rb_respond_to(obj, oj_to_json_id)) {
716
717
  dump_to_json(obj, out);
717
718
  return;
718
- }
719
+ }
719
720
  cnt = (int)RHASH_SIZE(obj);
720
721
  assure_size(out, 2);
721
722
  if (0 == cnt) {
@@ -762,9 +763,12 @@ dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
762
763
  exception_alt(obj, depth, out);
763
764
  return;
764
765
  }
766
+ if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
767
+ oj_dump_raw_json(obj, depth, out);
768
+ return;
769
+ }
765
770
  if (as_ok && rb_respond_to(obj, oj_to_json_id)) {
766
771
  dump_to_json(obj, out);
767
-
768
772
  return;
769
773
  }
770
774
  // Nothing else matched so encode as a JSON object with Ruby obj members
@@ -287,7 +287,7 @@ mimic_walk(VALUE key, VALUE obj, VALUE proc) {
287
287
  * call-seq: restore(source, proc=nil)
288
288
  *
289
289
  * Loads a Ruby Object from a JSON source that can be either a String or an
290
- * IO. If Proc is given or a block is providedit is called with each nested
290
+ * IO. If Proc is given or a block is provided it is called with each nested
291
291
  * element of the loaded Object.
292
292
  *
293
293
  * - *source* [_String_|IO] JSON source
@@ -300,7 +300,7 @@ mimic_walk(VALUE key, VALUE obj, VALUE proc) {
300
300
  * call-seq: load(source, proc=nil)
301
301
  *
302
302
  * Loads a Ruby Object from a JSON source that can be either a String or an
303
- * IO. If Proc is given or a block is providedit is called with each nested
303
+ * IO. If Proc is given or a block is provided it is called with each nested
304
304
  * element of the loaded Object.
305
305
  *
306
306
  * - *source* [_String_|IO] JSON source
@@ -357,6 +357,9 @@ mimic_generate_core(int argc, VALUE *argv, Options copts) {
357
357
  struct _out out;
358
358
  VALUE rstr;
359
359
 
360
+ // TBD
361
+ memset(buf, 0, sizeof(buf));
362
+
360
363
  out.buf = buf;
361
364
  out.end = buf + sizeof(buf) - 10;
362
365
  out.allocated = false;
@@ -677,6 +680,7 @@ static struct _options mimic_object_to_json_options = {
677
680
  No, // to_hash
678
681
  No, // to_json
679
682
  No, // as_json
683
+ No, // raw_json
680
684
  No, // nilnil
681
685
  No, // empty_string
682
686
  Yes, // allow_gc
@@ -685,6 +689,7 @@ static struct _options mimic_object_to_json_options = {
685
689
  No, // create_ok
686
690
  No, // allow_nan
687
691
  No, // trace
692
+ No, // safe
688
693
  0, // integer_range_min
689
694
  0, // integer_range_max
690
695
  oj_json_class,// create_id