oj 3.11.5 → 3.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1421 -0
  3. data/README.md +19 -5
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +20 -6
  6. data/ext/oj/cache.c +329 -0
  7. data/ext/oj/cache.h +22 -0
  8. data/ext/oj/cache8.c +10 -9
  9. data/ext/oj/circarray.c +8 -6
  10. data/ext/oj/circarray.h +2 -2
  11. data/ext/oj/code.c +19 -33
  12. data/ext/oj/code.h +2 -2
  13. data/ext/oj/compat.c +27 -77
  14. data/ext/oj/custom.c +86 -179
  15. data/ext/oj/debug.c +126 -0
  16. data/ext/oj/dump.c +256 -249
  17. data/ext/oj/dump.h +26 -12
  18. data/ext/oj/dump_compat.c +565 -642
  19. data/ext/oj/dump_leaf.c +17 -63
  20. data/ext/oj/dump_object.c +65 -187
  21. data/ext/oj/dump_strict.c +27 -51
  22. data/ext/oj/encoder.c +43 -0
  23. data/ext/oj/err.c +2 -13
  24. data/ext/oj/err.h +24 -8
  25. data/ext/oj/extconf.rb +21 -6
  26. data/ext/oj/fast.c +149 -149
  27. data/ext/oj/intern.c +313 -0
  28. data/ext/oj/intern.h +22 -0
  29. data/ext/oj/mem.c +318 -0
  30. data/ext/oj/mem.h +53 -0
  31. data/ext/oj/mimic_json.c +121 -106
  32. data/ext/oj/object.c +85 -162
  33. data/ext/oj/odd.c +89 -67
  34. data/ext/oj/odd.h +15 -15
  35. data/ext/oj/oj.c +542 -411
  36. data/ext/oj/oj.h +99 -73
  37. data/ext/oj/parse.c +175 -187
  38. data/ext/oj/parse.h +26 -24
  39. data/ext/oj/parser.c +1600 -0
  40. data/ext/oj/parser.h +101 -0
  41. data/ext/oj/rails.c +112 -159
  42. data/ext/oj/rails.h +1 -1
  43. data/ext/oj/reader.c +11 -14
  44. data/ext/oj/reader.h +4 -2
  45. data/ext/oj/resolve.c +5 -24
  46. data/ext/oj/rxclass.c +7 -6
  47. data/ext/oj/rxclass.h +1 -1
  48. data/ext/oj/saj.c +22 -33
  49. data/ext/oj/saj2.c +584 -0
  50. data/ext/oj/saj2.h +23 -0
  51. data/ext/oj/scp.c +5 -28
  52. data/ext/oj/sparse.c +28 -72
  53. data/ext/oj/stream_writer.c +50 -40
  54. data/ext/oj/strict.c +56 -61
  55. data/ext/oj/string_writer.c +72 -39
  56. data/ext/oj/trace.h +31 -4
  57. data/ext/oj/usual.c +1218 -0
  58. data/ext/oj/usual.h +69 -0
  59. data/ext/oj/util.h +1 -1
  60. data/ext/oj/val_stack.c +14 -3
  61. data/ext/oj/val_stack.h +8 -7
  62. data/ext/oj/validate.c +46 -0
  63. data/ext/oj/wab.c +63 -88
  64. data/lib/oj/active_support_helper.rb +1 -3
  65. data/lib/oj/bag.rb +7 -1
  66. data/lib/oj/easy_hash.rb +4 -5
  67. data/lib/oj/error.rb +1 -2
  68. data/lib/oj/json.rb +162 -150
  69. data/lib/oj/mimic.rb +9 -7
  70. data/lib/oj/saj.rb +20 -6
  71. data/lib/oj/schandler.rb +5 -4
  72. data/lib/oj/state.rb +12 -8
  73. data/lib/oj/version.rb +1 -2
  74. data/lib/oj.rb +2 -0
  75. data/pages/Compatibility.md +1 -1
  76. data/pages/InstallOptions.md +20 -0
  77. data/pages/JsonGem.md +15 -0
  78. data/pages/Modes.md +8 -3
  79. data/pages/Options.md +43 -5
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +14 -2
  82. data/test/_test_active.rb +8 -9
  83. data/test/_test_active_mimic.rb +7 -8
  84. data/test/_test_mimic_rails.rb +17 -20
  85. data/test/activerecord/result_test.rb +5 -6
  86. data/test/activesupport6/encoding_test.rb +63 -28
  87. data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
  88. data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
  89. data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
  90. data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
  91. data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
  92. data/test/files.rb +15 -15
  93. data/test/foo.rb +16 -45
  94. data/test/helper.rb +11 -8
  95. data/test/isolated/shared.rb +3 -2
  96. data/test/json_gem/json_addition_test.rb +2 -2
  97. data/test/json_gem/json_common_interface_test.rb +8 -6
  98. data/test/json_gem/json_encoding_test.rb +0 -0
  99. data/test/json_gem/json_ext_parser_test.rb +1 -0
  100. data/test/json_gem/json_fixtures_test.rb +3 -2
  101. data/test/json_gem/json_generator_test.rb +56 -38
  102. data/test/json_gem/json_generic_object_test.rb +11 -11
  103. data/test/json_gem/json_parser_test.rb +54 -47
  104. data/test/json_gem/json_string_matching_test.rb +9 -9
  105. data/test/json_gem/test_helper.rb +7 -3
  106. data/test/mem.rb +34 -0
  107. data/test/perf.rb +22 -27
  108. data/test/perf_compat.rb +31 -33
  109. data/test/perf_dump.rb +50 -0
  110. data/test/perf_fast.rb +80 -82
  111. data/test/perf_file.rb +27 -29
  112. data/test/perf_object.rb +65 -69
  113. data/test/perf_once.rb +59 -0
  114. data/test/perf_parser.rb +183 -0
  115. data/test/perf_saj.rb +46 -54
  116. data/test/perf_scp.rb +58 -69
  117. data/test/perf_simple.rb +41 -39
  118. data/test/perf_strict.rb +74 -82
  119. data/test/perf_wab.rb +67 -69
  120. data/test/prec.rb +5 -5
  121. data/test/sample/change.rb +0 -1
  122. data/test/sample/dir.rb +0 -1
  123. data/test/sample/doc.rb +0 -1
  124. data/test/sample/file.rb +0 -1
  125. data/test/sample/group.rb +0 -1
  126. data/test/sample/hasprops.rb +0 -1
  127. data/test/sample/layer.rb +0 -1
  128. data/test/sample/rect.rb +0 -1
  129. data/test/sample/shape.rb +0 -1
  130. data/test/sample/text.rb +0 -1
  131. data/test/sample.rb +16 -16
  132. data/test/sample_json.rb +8 -8
  133. data/test/test_compat.rb +95 -43
  134. data/test/test_custom.rb +73 -51
  135. data/test/test_debian.rb +7 -10
  136. data/test/test_fast.rb +135 -79
  137. data/test/test_file.rb +41 -30
  138. data/test/test_gc.rb +16 -5
  139. data/test/test_generate.rb +5 -5
  140. data/test/test_hash.rb +5 -5
  141. data/test/test_integer_range.rb +9 -9
  142. data/test/test_null.rb +20 -20
  143. data/test/test_object.rb +99 -96
  144. data/test/test_parser.rb +11 -0
  145. data/test/test_parser_debug.rb +27 -0
  146. data/test/test_parser_saj.rb +337 -0
  147. data/test/test_parser_usual.rb +251 -0
  148. data/test/test_rails.rb +2 -2
  149. data/test/test_saj.rb +10 -8
  150. data/test/test_scp.rb +37 -39
  151. data/test/test_strict.rb +40 -32
  152. data/test/test_various.rb +165 -84
  153. data/test/test_wab.rb +48 -44
  154. data/test/test_writer.rb +47 -47
  155. data/test/tests.rb +13 -5
  156. data/test/tests_mimic.rb +12 -3
  157. data/test/tests_mimic_addition.rb +12 -3
  158. metadata +74 -128
  159. data/ext/oj/hash.c +0 -131
  160. data/ext/oj/hash.h +0 -19
  161. data/ext/oj/hash_test.c +0 -491
  162. data/test/activesupport4/decoding_test.rb +0 -108
  163. data/test/activesupport4/encoding_test.rb +0 -531
  164. data/test/activesupport4/test_helper.rb +0 -41
  165. data/test/activesupport5/test_helper.rb +0 -72
  166. data/test/bar.rb +0 -35
  167. data/test/baz.rb +0 -16
  168. data/test/zoo.rb +0 -13
data/ext/oj/oj.h CHANGED
@@ -39,6 +39,16 @@ enum st_retval { ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK };
39
39
  #define NINF_VAL "-3.0e14159265358979323846"
40
40
  #define NAN_VAL "3.3e14159265358979323846"
41
41
 
42
+ #if __STDC_VERSION__ >= 199901L
43
+ // To avoid using ruby_snprintf with C99.
44
+ #undef snprintf
45
+ #include <stdio.h>
46
+ #endif
47
+
48
+ // To avoid using ruby_nonempty_memcpy().
49
+ #undef memcpy
50
+ #include <string.h>
51
+
42
52
  typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo;
43
53
 
44
54
  typedef enum {
@@ -56,6 +66,7 @@ typedef enum { UnixTime = 'u', UnixZTime = 'z', XmlTime = 'x', RubyTime = 'r' }
56
66
  typedef enum {
57
67
  NLEsc = 'n',
58
68
  JSONEsc = 'j',
69
+ SlashEsc = 's',
59
70
  XSSEsc = 'x',
60
71
  ASCIIEsc = 'a',
61
72
  JXEsc = 'g', // json gem
@@ -92,13 +103,6 @@ typedef enum {
92
103
  FILE_IO = 'f',
93
104
  } StreamWriterType;
94
105
 
95
- typedef enum {
96
- CALLER_DUMP = 'd',
97
- CALLER_TO_JSON = 't',
98
- CALLER_GENERATE = 'g',
99
- // Add the fast versions if necessary. Maybe unparse as well if needed.
100
- } DumpCaller;
101
-
102
106
  typedef struct _dumpOpts {
103
107
  bool use;
104
108
  char indent_str[16];
@@ -113,39 +117,42 @@ typedef struct _dumpOpts {
113
117
  uint8_t array_size;
114
118
  char nan_dump; // NanDump
115
119
  bool omit_nil;
120
+ bool omit_null_byte;
116
121
  int max_depth;
117
- } * DumpOpts;
122
+ } *DumpOpts;
118
123
 
119
124
  typedef struct _options {
120
- int indent; // indention for dump, default 2
121
- char circular; // YesNo
122
- char auto_define; // YesNo
123
- char sym_key; // YesNo
124
- char escape_mode; // Escape_Mode
125
- char mode; // Mode
126
- char class_cache; // YesNo
127
- char time_format; // TimeFormat
128
- char bigdec_as_num; // YesNo
129
- char bigdec_load; // BigLoad
130
- char compat_bigdec; // boolean (0 or 1)
131
- char to_hash; // YesNo
132
- char to_json; // YesNo
133
- char as_json; // YesNo
134
- char raw_json; // YesNo
135
- char nilnil; // YesNo
136
- char empty_string; // YesNo
137
- char allow_gc; // allow GC during parse
138
- char quirks_mode; // allow single JSON values instead of documents
139
- char allow_invalid; // YesNo - allow invalid unicode
140
- char create_ok; // YesNo allow create_id
141
- char allow_nan; // YEsyNo for parsing only
142
- char trace; // YesNo
143
- char safe; // YesNo
144
- char sec_prec_set; // boolean (0 or 1)
145
- char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
125
+ int indent; // indention for dump, default 2
126
+ char circular; // YesNo
127
+ char auto_define; // YesNo
128
+ char sym_key; // YesNo
129
+ char escape_mode; // Escape_Mode
130
+ char mode; // Mode
131
+ char class_cache; // YesNo
132
+ char time_format; // TimeFormat
133
+ char bigdec_as_num; // YesNo
134
+ char bigdec_load; // BigLoad
135
+ char compat_bigdec; // boolean (0 or 1)
136
+ char to_hash; // YesNo
137
+ char to_json; // YesNo
138
+ char as_json; // YesNo
139
+ char raw_json; // YesNo
140
+ char nilnil; // YesNo
141
+ char empty_string; // YesNo
142
+ char allow_gc; // allow GC during parse
143
+ char quirks_mode; // allow single JSON values instead of documents
144
+ char allow_invalid; // YesNo - allow invalid unicode
145
+ char create_ok; // YesNo allow create_id
146
+ char allow_nan; // YEsyNo for parsing only
147
+ char trace; // YesNo
148
+ char safe; // YesNo
149
+ char sec_prec_set; // boolean (0 or 1)
150
+ char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
151
+ char cache_keys; // YesNo
152
+ char cache_str; // string short than or equal to this are cache
146
153
  int64_t int_range_min; // dump numbers below as string
147
154
  int64_t int_range_max; // dump numbers above as string
148
- const char * create_id; // 0 or string
155
+ const char *create_id; // 0 or string
149
156
  size_t create_id_len; // length of create_id
150
157
  int sec_prec; // second precision when dumping time
151
158
  char float_prec; // float precision, linked to float_fmt
@@ -154,8 +161,8 @@ typedef struct _options {
154
161
  VALUE array_class; // class to use in place of Array on load
155
162
  struct _dumpOpts dump_opts;
156
163
  struct _rxClass str_rx;
157
- VALUE * ignore; // Qnil terminated array of classes or NULL
158
- } * Options;
164
+ VALUE *ignore; // Qnil terminated array of classes or NULL
165
+ } *Options;
159
166
 
160
167
  struct _out;
161
168
  typedef void (*DumpFunc)(VALUE obj, int depth, struct _out *out, bool as_ok);
@@ -165,41 +172,42 @@ typedef struct _rOpt {
165
172
  VALUE clas;
166
173
  bool on;
167
174
  DumpFunc dump;
168
- } * ROpt;
175
+ } *ROpt;
169
176
 
170
177
  typedef struct _rOptTable {
171
178
  int len;
172
179
  int alen;
173
180
  ROpt table;
174
- } * ROptTable;
181
+ } *ROptTable;
175
182
 
176
183
  typedef struct _out {
177
- char * buf;
178
- char * end;
179
- char * cur;
180
- Cache8 circ_cache;
181
- slot_t circ_cnt;
182
- int indent;
183
- int depth; // used by dump_hash
184
- Options opts;
185
- uint32_t hash_cnt;
186
- bool allocated;
187
- bool omit_nil;
188
- int argc;
189
- VALUE * argv;
190
- DumpCaller caller; // used for the mimic json only
191
- ROptTable ropts;
192
- } * Out;
184
+ char stack_buffer[4096];
185
+ char *buf;
186
+ char *end;
187
+ char *cur;
188
+ Cache8 circ_cache;
189
+ slot_t circ_cnt;
190
+ int indent;
191
+ int depth; // used by dump_hash
192
+ Options opts;
193
+ uint32_t hash_cnt;
194
+ bool allocated;
195
+ bool omit_nil;
196
+ bool omit_null_byte;
197
+ int argc;
198
+ VALUE *argv;
199
+ ROptTable ropts;
200
+ } *Out;
193
201
 
194
202
  typedef struct _strWriter {
195
203
  struct _out out;
196
204
  struct _options opts;
197
205
  int depth;
198
- char * types; // DumpType
199
- char * types_end;
206
+ char *types; // DumpType
207
+ char *types_end;
200
208
  int keyWritten;
201
209
 
202
- } * StrWriter;
210
+ } *StrWriter;
203
211
 
204
212
  typedef struct _streamWriter {
205
213
  struct _strWriter sw;
@@ -207,7 +215,7 @@ typedef struct _streamWriter {
207
215
  VALUE stream;
208
216
  int fd;
209
217
  int flush_limit; // indicator of when to flush
210
- } * StreamWriter;
218
+ } *StreamWriter;
211
219
 
212
220
  enum { NO_VAL = 0x00, STR_VAL = 0x01, COL_VAL = 0x02, RUBY_VAL = 0x03 };
213
221
 
@@ -218,14 +226,14 @@ typedef struct _leaf {
218
226
  size_t index; // array index, 0 is not set
219
227
  };
220
228
  union {
221
- char * str; // pointer to location in json string or allocated
229
+ char *str; // pointer to location in json string or allocated
222
230
  struct _leaf *elements; // array and hash elements
223
231
  VALUE value;
224
232
  };
225
233
  uint8_t rtype;
226
234
  uint8_t parent_type;
227
235
  uint8_t value_type;
228
- } * Leaf;
236
+ } *Leaf;
229
237
 
230
238
  extern VALUE oj_saj_parse(int argc, VALUE *argv, VALUE self);
231
239
  extern VALUE oj_sc_parse(int argc, VALUE *argv, VALUE self);
@@ -243,15 +251,18 @@ extern VALUE oj_compat_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
243
251
  extern VALUE oj_object_parse_cstr(int argc, VALUE *argv, char *json, size_t len);
244
252
  extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len);
245
253
 
254
+ extern bool oj_hash_has_key(VALUE hash, VALUE key);
246
255
  extern void oj_parse_options(VALUE ropts, Options copts);
247
256
 
248
- extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
249
- extern void
250
- oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
251
- extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
252
- extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
253
- extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
254
- extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
257
+ extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
258
+ extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
259
+ extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
260
+ extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
261
+ extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
262
+ extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
263
+ extern char *oj_longlong_to_string(long long num, bool negative, char *buf);
264
+
265
+ extern StrWriter oj_str_writer_unwrap(VALUE writer);
255
266
 
256
267
  extern void oj_str_writer_push_key(StrWriter sw, const char *key);
257
268
  extern void oj_str_writer_push_object(StrWriter sw, const char *key);
@@ -262,8 +273,8 @@ extern void oj_str_writer_pop(StrWriter sw);
262
273
  extern void oj_str_writer_pop_all(StrWriter sw);
263
274
 
264
275
  extern void oj_init_doc(void);
265
- extern void oj_string_writer_init();
266
- extern void oj_stream_writer_init();
276
+ extern void oj_string_writer_init(void);
277
+ extern void oj_stream_writer_init(void);
267
278
  extern void oj_str_writer_init(StrWriter sw, int buf_size);
268
279
  extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
269
280
  extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
@@ -278,7 +289,8 @@ extern VALUE oj_rails_encode(int argc, VALUE *argv, VALUE self);
278
289
 
279
290
  extern VALUE Oj;
280
291
  extern struct _options oj_default_options;
281
- extern rb_encoding * oj_utf8_encoding;
292
+ extern rb_encoding *oj_utf8_encoding;
293
+ extern int oj_utf8_encoding_index;
282
294
 
283
295
  extern VALUE oj_bag_class;
284
296
  extern VALUE oj_bigdecimal_class;
@@ -306,8 +318,10 @@ extern VALUE oj_max_nesting_sym;
306
318
  extern VALUE oj_object_class_sym;
307
319
  extern VALUE oj_object_nl_sym;
308
320
  extern VALUE oj_quirks_mode_sym;
321
+ extern VALUE oj_skip_null_byte_sym;
309
322
  extern VALUE oj_space_before_sym;
310
323
  extern VALUE oj_space_sym;
324
+ extern VALUE oj_symbolize_names_sym;
311
325
  extern VALUE oj_trace_sym;
312
326
 
313
327
  extern VALUE oj_slash_string;
@@ -320,22 +334,22 @@ extern ID oj_as_json_id;
320
334
  extern ID oj_begin_id;
321
335
  extern ID oj_bigdecimal_id;
322
336
  extern ID oj_end_id;
337
+ extern ID oj_eofq_id;
323
338
  extern ID oj_error_id;
324
339
  extern ID oj_exclude_end_id;
325
340
  extern ID oj_file_id;
326
341
  extern ID oj_fileno_id;
327
342
  extern ID oj_ftype_id;
328
- extern ID oj_has_key_id;
329
343
  extern ID oj_hash_end_id;
330
344
  extern ID oj_hash_key_id;
331
345
  extern ID oj_hash_set_id;
332
346
  extern ID oj_hash_start_id;
333
347
  extern ID oj_iconv_id;
334
- extern ID oj_instance_variables_id;
335
348
  extern ID oj_json_create_id;
336
349
  extern ID oj_length_id;
337
350
  extern ID oj_new_id;
338
351
  extern ID oj_parse_id;
352
+ extern ID oj_plus_id;
339
353
  extern ID oj_pos_id;
340
354
  extern ID oj_read_id;
341
355
  extern ID oj_readpartial_id;
@@ -361,6 +375,18 @@ extern bool oj_use_hash_alt;
361
375
  extern bool oj_use_array_alt;
362
376
  extern bool string_writer_optimized;
363
377
 
378
+ static inline VALUE oj_safe_string_convert(VALUE obj) {
379
+ VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
380
+ StringValue(rstr);
381
+ return rstr;
382
+ }
383
+
384
+ #define APPEND_CHARS(buffer, chars, size) \
385
+ { \
386
+ memcpy(buffer, chars, size); \
387
+ buffer += size; \
388
+ }
389
+
364
390
  #ifdef HAVE_PTHREAD_MUTEX_INIT
365
391
  extern pthread_mutex_t oj_cache_mutex;
366
392
  #else