oj 3.7.12 → 3.8.0

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