oj 2.18.3 → 3.13.14

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.
Files changed (182) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1324 -0
  3. data/README.md +51 -204
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +49 -72
  6. data/ext/oj/cache.c +326 -0
  7. data/ext/oj/cache.h +21 -0
  8. data/ext/oj/cache8.c +61 -64
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +37 -68
  11. data/ext/oj/circarray.h +16 -42
  12. data/ext/oj/code.c +221 -0
  13. data/ext/oj/code.h +40 -0
  14. data/ext/oj/compat.c +231 -107
  15. data/ext/oj/custom.c +1125 -0
  16. data/ext/oj/debug.c +132 -0
  17. data/ext/oj/dump.c +935 -2513
  18. data/ext/oj/dump.h +108 -0
  19. data/ext/oj/dump_compat.c +936 -0
  20. data/ext/oj/dump_leaf.c +164 -0
  21. data/ext/oj/dump_object.c +761 -0
  22. data/ext/oj/dump_strict.c +410 -0
  23. data/ext/oj/encode.h +7 -42
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +40 -54
  26. data/ext/oj/err.h +52 -46
  27. data/ext/oj/extconf.rb +21 -30
  28. data/ext/oj/fast.c +1097 -1080
  29. data/ext/oj/intern.c +301 -0
  30. data/ext/oj/intern.h +26 -0
  31. data/ext/oj/mimic_json.c +893 -0
  32. data/ext/oj/object.c +549 -620
  33. data/ext/oj/odd.c +155 -167
  34. data/ext/oj/odd.h +37 -63
  35. data/ext/oj/oj.c +1661 -2063
  36. data/ext/oj/oj.h +341 -270
  37. data/ext/oj/parse.c +974 -737
  38. data/ext/oj/parse.h +105 -97
  39. data/ext/oj/parser.c +1526 -0
  40. data/ext/oj/parser.h +90 -0
  41. data/ext/oj/rails.c +1504 -0
  42. data/ext/oj/rails.h +18 -0
  43. data/ext/oj/reader.c +141 -163
  44. data/ext/oj/reader.h +75 -113
  45. data/ext/oj/resolve.c +45 -93
  46. data/ext/oj/resolve.h +7 -34
  47. data/ext/oj/rxclass.c +143 -0
  48. data/ext/oj/rxclass.h +26 -0
  49. data/ext/oj/saj.c +447 -511
  50. data/ext/oj/saj2.c +348 -0
  51. data/ext/oj/scp.c +91 -138
  52. data/ext/oj/sparse.c +793 -644
  53. data/ext/oj/stream_writer.c +331 -0
  54. data/ext/oj/strict.c +145 -109
  55. data/ext/oj/string_writer.c +493 -0
  56. data/ext/oj/trace.c +72 -0
  57. data/ext/oj/trace.h +28 -0
  58. data/ext/oj/usual.c +1254 -0
  59. data/ext/oj/util.c +136 -0
  60. data/ext/oj/util.h +20 -0
  61. data/ext/oj/val_stack.c +62 -70
  62. data/ext/oj/val_stack.h +95 -129
  63. data/ext/oj/validate.c +51 -0
  64. data/ext/oj/wab.c +622 -0
  65. data/lib/oj/bag.rb +1 -0
  66. data/lib/oj/easy_hash.rb +17 -8
  67. data/lib/oj/error.rb +10 -11
  68. data/lib/oj/json.rb +176 -0
  69. data/lib/oj/mimic.rb +158 -19
  70. data/lib/oj/state.rb +132 -0
  71. data/lib/oj/version.rb +2 -2
  72. data/lib/oj.rb +1 -31
  73. data/pages/Advanced.md +22 -0
  74. data/pages/Compatibility.md +25 -0
  75. data/pages/Custom.md +23 -0
  76. data/pages/Encoding.md +65 -0
  77. data/pages/JsonGem.md +94 -0
  78. data/pages/Modes.md +161 -0
  79. data/pages/Options.md +327 -0
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +167 -0
  82. data/pages/Security.md +20 -0
  83. data/pages/WAB.md +13 -0
  84. data/test/activerecord/result_test.rb +32 -0
  85. data/test/activesupport4/decoding_test.rb +108 -0
  86. data/test/activesupport4/encoding_test.rb +531 -0
  87. data/test/activesupport4/test_helper.rb +41 -0
  88. data/test/activesupport5/abstract_unit.rb +45 -0
  89. data/test/activesupport5/decoding_test.rb +133 -0
  90. data/test/activesupport5/encoding_test.rb +500 -0
  91. data/test/activesupport5/encoding_test_cases.rb +98 -0
  92. data/test/activesupport5/test_helper.rb +72 -0
  93. data/test/activesupport5/time_zone_test_helpers.rb +39 -0
  94. data/test/activesupport6/abstract_unit.rb +44 -0
  95. data/test/activesupport6/decoding_test.rb +133 -0
  96. data/test/activesupport6/encoding_test.rb +507 -0
  97. data/test/activesupport6/encoding_test_cases.rb +98 -0
  98. data/test/activesupport6/test_common.rb +17 -0
  99. data/test/activesupport6/test_helper.rb +163 -0
  100. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  101. data/test/activesupport7/abstract_unit.rb +49 -0
  102. data/test/activesupport7/decoding_test.rb +125 -0
  103. data/test/activesupport7/encoding_test.rb +486 -0
  104. data/test/activesupport7/encoding_test_cases.rb +104 -0
  105. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  106. data/test/bar.rb +9 -0
  107. data/test/baz.rb +16 -0
  108. data/test/bug.rb +11 -46
  109. data/test/foo.rb +69 -16
  110. data/test/helper.rb +10 -1
  111. data/test/isolated/shared.rb +12 -8
  112. data/test/isolated/test_mimic_rails_after.rb +3 -3
  113. data/test/isolated/test_mimic_rails_before.rb +3 -3
  114. data/test/json_gem/json_addition_test.rb +216 -0
  115. data/test/json_gem/json_common_interface_test.rb +153 -0
  116. data/test/json_gem/json_encoding_test.rb +107 -0
  117. data/test/json_gem/json_ext_parser_test.rb +20 -0
  118. data/test/json_gem/json_fixtures_test.rb +35 -0
  119. data/test/json_gem/json_generator_test.rb +397 -0
  120. data/test/json_gem/json_generic_object_test.rb +90 -0
  121. data/test/json_gem/json_parser_test.rb +470 -0
  122. data/test/json_gem/json_string_matching_test.rb +42 -0
  123. data/test/json_gem/test_helper.rb +26 -0
  124. data/test/mem.rb +33 -0
  125. data/test/perf.rb +1 -1
  126. data/test/perf_compat.rb +30 -28
  127. data/test/perf_dump.rb +50 -0
  128. data/test/perf_object.rb +1 -1
  129. data/test/perf_once.rb +58 -0
  130. data/test/perf_parser.rb +189 -0
  131. data/test/perf_scp.rb +11 -10
  132. data/test/perf_strict.rb +30 -19
  133. data/test/perf_wab.rb +131 -0
  134. data/test/prec.rb +23 -0
  135. data/test/sample.rb +0 -1
  136. data/test/sample_json.rb +1 -1
  137. data/test/test_compat.rb +219 -102
  138. data/test/test_custom.rb +533 -0
  139. data/test/test_fast.rb +107 -35
  140. data/test/test_file.rb +19 -25
  141. data/test/test_generate.rb +21 -0
  142. data/test/test_hash.rb +11 -1
  143. data/test/test_integer_range.rb +72 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +357 -70
  146. data/test/test_parser.rb +27 -0
  147. data/test/test_parser_saj.rb +245 -0
  148. data/test/test_parser_usual.rb +217 -0
  149. data/test/test_rails.rb +35 -0
  150. data/test/test_saj.rb +1 -1
  151. data/test/test_scp.rb +39 -2
  152. data/test/test_strict.rb +186 -7
  153. data/test/test_various.rb +160 -774
  154. data/test/test_wab.rb +307 -0
  155. data/test/test_writer.rb +90 -2
  156. data/test/tests.rb +24 -0
  157. data/test/tests_mimic.rb +14 -0
  158. data/test/tests_mimic_addition.rb +7 -0
  159. data/test/zoo.rb +13 -0
  160. metadata +194 -56
  161. data/ext/oj/hash.c +0 -163
  162. data/ext/oj/hash.h +0 -46
  163. data/ext/oj/hash_test.c +0 -512
  164. data/test/activesupport_datetime_test.rb +0 -23
  165. data/test/bug2.rb +0 -10
  166. data/test/bug3.rb +0 -46
  167. data/test/bug_fast.rb +0 -32
  168. data/test/bug_load.rb +0 -24
  169. data/test/crash.rb +0 -111
  170. data/test/curl/curl_oj.rb +0 -46
  171. data/test/curl/get_oj.rb +0 -24
  172. data/test/curl/just_curl.rb +0 -31
  173. data/test/curl/just_oj.rb +0 -51
  174. data/test/example.rb +0 -11
  175. data/test/io.rb +0 -48
  176. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  177. data/test/mod.rb +0 -16
  178. data/test/rails.rb +0 -50
  179. data/test/russian.rb +0 -18
  180. data/test/struct.rb +0 -29
  181. data/test/test_serializer.rb +0 -59
  182. data/test/write_timebars.rb +0 -31
data/ext/oj/util.c ADDED
@@ -0,0 +1,136 @@
1
+ // Copyright (c) 2019 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #include "util.h"
5
+
6
+ #include <stdbool.h>
7
+ #include <stdint.h>
8
+ #include <stdio.h>
9
+ #include <string.h>
10
+ #include <time.h>
11
+
12
+ #define SECS_PER_DAY 86400LL
13
+ #define SECS_PER_YEAR 31536000LL
14
+ #define SECS_PER_LEAP 31622400LL
15
+ #define SECS_PER_QUAD_YEAR (SECS_PER_YEAR * 3 + SECS_PER_LEAP)
16
+ #define SECS_PER_CENT (SECS_PER_QUAD_YEAR * 24 + SECS_PER_YEAR * 4)
17
+ #define SECS_PER_LEAP_CENT (SECS_PER_CENT + SECS_PER_DAY)
18
+ #define SECS_PER_QUAD_CENT (SECS_PER_CENT * 4 + SECS_PER_DAY)
19
+
20
+ static int64_t eom_secs[] = {
21
+ 2678400, // January (31)
22
+ 5097600, // February (28) 2419200 2505600
23
+ 7776000, // March (31)
24
+ 10368000, // April (30 2592000
25
+ 13046400, // May (31)
26
+ 15638400, // June (30)
27
+ 18316800, // July (31)
28
+ 20995200, // August (31)
29
+ 23587200, // September (30)
30
+ 26265600, // October (31)
31
+ 28857600, // November (30)
32
+ 31536000, // December (31)
33
+ };
34
+
35
+ static int64_t eom_leap_secs[] = {
36
+ 2678400, // January (31)
37
+ 5184000, // February (28) 2419200 2505600
38
+ 7862400, // March (31)
39
+ 10454400, // April (30 2592000
40
+ 13132800, // May (31)
41
+ 15724800, // June (30)
42
+ 18403200, // July (31)
43
+ 21081600, // August (31)
44
+ 23673600, // September (30)
45
+ 26352000, // October (31)
46
+ 28944000, // November (30)
47
+ 31622400, // December (31)
48
+ };
49
+
50
+ void sec_as_time(int64_t secs, TimeInfo ti) {
51
+ int64_t qc = 0;
52
+ int64_t c = 0;
53
+ int64_t qy = 0;
54
+ int64_t y = 0;
55
+ bool leap = false;
56
+ int64_t *ms;
57
+ int m;
58
+ int shift = 0;
59
+
60
+ secs += 62167219200LL; // normalize to first day of the year 0
61
+ if (secs < 0) {
62
+ shift = -secs / SECS_PER_QUAD_CENT;
63
+ shift++;
64
+ secs += shift * SECS_PER_QUAD_CENT;
65
+ }
66
+ qc = secs / SECS_PER_QUAD_CENT;
67
+ secs = secs - qc * SECS_PER_QUAD_CENT;
68
+ if (secs < SECS_PER_LEAP) {
69
+ leap = true;
70
+ } else if (secs < SECS_PER_QUAD_YEAR) {
71
+ if (SECS_PER_LEAP <= secs) {
72
+ secs -= SECS_PER_LEAP;
73
+ y = secs / SECS_PER_YEAR;
74
+ secs = secs - y * SECS_PER_YEAR;
75
+ y++;
76
+ leap = false;
77
+ }
78
+ } else if (secs < SECS_PER_LEAP_CENT) { // first century in 400 years is a leap century (one
79
+ // extra day)
80
+ qy = secs / SECS_PER_QUAD_YEAR;
81
+ secs = secs - qy * SECS_PER_QUAD_YEAR;
82
+ if (secs < SECS_PER_LEAP) {
83
+ leap = true;
84
+ } else {
85
+ secs -= SECS_PER_LEAP;
86
+ y = secs / SECS_PER_YEAR;
87
+ secs = secs - y * SECS_PER_YEAR;
88
+ y++;
89
+ }
90
+ } else {
91
+ secs -= SECS_PER_LEAP_CENT;
92
+ c = secs / SECS_PER_CENT;
93
+ secs = secs - c * SECS_PER_CENT;
94
+ c++;
95
+ if (secs < SECS_PER_YEAR * 4) {
96
+ y = secs / SECS_PER_YEAR;
97
+ secs = secs - y * SECS_PER_YEAR;
98
+ } else {
99
+ secs -= SECS_PER_YEAR * 4;
100
+ qy = secs / SECS_PER_QUAD_YEAR;
101
+ secs = secs - qy * SECS_PER_QUAD_YEAR;
102
+ qy++;
103
+ if (secs < SECS_PER_LEAP) {
104
+ leap = true;
105
+ } else {
106
+ secs -= SECS_PER_LEAP;
107
+ y = secs / SECS_PER_YEAR;
108
+ secs = secs - y * SECS_PER_YEAR;
109
+ y++;
110
+ }
111
+ }
112
+ }
113
+ ti->year = (int)((qc - (int64_t)shift) * 400 + c * 100 + qy * 4 + y);
114
+ if (leap) {
115
+ ms = eom_leap_secs;
116
+ } else {
117
+ ms = eom_secs;
118
+ }
119
+ for (m = 1; m <= 12; m++, ms++) {
120
+ if (secs < *ms) {
121
+ if (1 < m) {
122
+ secs -= *(ms - 1);
123
+ }
124
+ ti->mon = m;
125
+ break;
126
+ }
127
+ }
128
+ ti->day = (int)(secs / 86400LL);
129
+ secs = secs - (int64_t)ti->day * 86400LL;
130
+ ti->day++;
131
+ ti->hour = (int)(secs / 3600LL);
132
+ secs = secs - (int64_t)ti->hour * 3600LL;
133
+ ti->min = (int)(secs / 60LL);
134
+ secs = secs - (int64_t)ti->min * 60LL;
135
+ ti->sec = (int)secs;
136
+ }
data/ext/oj/util.h ADDED
@@ -0,0 +1,20 @@
1
+ // Copyright (c) 2019 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #ifndef OJ_UTIL_H
5
+ #define OJ_UTIL_H
6
+
7
+ #include <stdint.h>
8
+
9
+ typedef struct _timeInfo {
10
+ int sec;
11
+ int min;
12
+ int hour;
13
+ int day;
14
+ int mon;
15
+ int year;
16
+ } * TimeInfo;
17
+
18
+ extern void sec_as_time(int64_t secs, TimeInfo ti);
19
+
20
+ #endif /* OJ_UTIL_H */
data/ext/oj/val_stack.c CHANGED
@@ -1,98 +1,90 @@
1
- /* val_stack.c
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * - Redistributions of source code must retain the above copyright notice, this
9
- * list of conditions and the following disclaimer.
10
- *
11
- * - Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * - Neither the name of Peter Ohler nor the names of its contributors may be
16
- * used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
30
3
 
31
- #include "oj.h"
32
4
  #include "val_stack.h"
33
5
 
34
- static void
35
- mark(void *ptr) {
36
- ValStack stack = (ValStack)ptr;
37
- Val v;
6
+ #include <string.h>
7
+
8
+ #include "odd.h"
9
+ #include "oj.h"
10
+
11
+ static void mark(void *ptr) {
12
+ ValStack stack = (ValStack)ptr;
13
+ Val v;
38
14
 
39
15
  if (0 == ptr) {
40
- return;
16
+ return;
41
17
  }
42
- #if USE_PTHREAD_MUTEX
18
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
43
19
  pthread_mutex_lock(&stack->mutex);
44
- #elif USE_RB_MUTEX
20
+ #else
45
21
  rb_mutex_lock(stack->mutex);
46
22
  rb_gc_mark(stack->mutex);
47
23
  #endif
48
24
  for (v = stack->head; v < stack->tail; v++) {
49
- if (Qnil != v->val && Qundef != v->val) {
50
- rb_gc_mark(v->val);
51
- }
52
- if (Qnil != v->key_val && Qundef != v->key_val) {
53
- rb_gc_mark(v->key_val);
54
- }
25
+ if (Qnil != v->val && Qundef != v->val) {
26
+ rb_gc_mark(v->val);
27
+ }
28
+ if (Qnil != v->key_val && Qundef != v->key_val) {
29
+ rb_gc_mark(v->key_val);
30
+ }
31
+ if (NULL != v->odd_args) {
32
+ VALUE *a;
33
+ int i;
34
+
35
+ for (i = v->odd_args->odd->attr_cnt, a = v->odd_args->args; 0 < i; i--, a++) {
36
+ if (Qnil != *a) {
37
+ rb_gc_mark(*a);
38
+ }
39
+ }
40
+ }
55
41
  }
56
- #if USE_PTHREAD_MUTEX
42
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
57
43
  pthread_mutex_unlock(&stack->mutex);
58
- #elif USE_RB_MUTEX
44
+ #else
59
45
  rb_mutex_unlock(stack->mutex);
60
46
  #endif
61
47
  }
62
48
 
63
49
  VALUE
64
50
  oj_stack_init(ValStack stack) {
65
- #if USE_PTHREAD_MUTEX
66
- pthread_mutex_init(&stack->mutex, 0);
67
- #elif USE_RB_MUTEX
51
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
52
+ int err;
53
+
54
+ if (0 != (err = pthread_mutex_init(&stack->mutex, 0))) {
55
+ rb_raise(rb_eException, "failed to initialize a mutex. %s", strerror(err));
56
+ }
57
+ #else
68
58
  stack->mutex = rb_mutex_new();
69
59
  #endif
70
- stack->head = stack->base;
71
- stack->end = stack->base + sizeof(stack->base) / sizeof(struct _Val);
72
- stack->tail = stack->head;
73
- stack->head->val = Qundef;
74
- stack->head->key = 0;
75
- stack->head->key_val = Qundef;
76
- stack->head->classname = 0;
77
- stack->head->klen = 0;
78
- stack->head->clen = 0;
79
- stack->head->next = NEXT_NONE;
60
+ stack->head = stack->base;
61
+ stack->end = stack->base + sizeof(stack->base) / sizeof(struct _val);
62
+ stack->tail = stack->head;
63
+ stack->head->val = Qundef;
64
+ stack->head->key = NULL;
65
+ stack->head->key_val = Qundef;
66
+ stack->head->classname = NULL;
67
+ stack->head->odd_args = NULL;
68
+ stack->head->clas = Qundef;
69
+ stack->head->klen = 0;
70
+ stack->head->clen = 0;
71
+ stack->head->next = NEXT_NONE;
72
+
80
73
  return Data_Wrap_Struct(oj_cstack_class, mark, 0, stack);
81
74
  }
82
75
 
83
- const char*
84
- oj_stack_next_string(ValNext n) {
76
+ const char *oj_stack_next_string(ValNext n) {
85
77
  switch (n) {
86
- case NEXT_ARRAY_NEW: return "array element or close";
87
- case NEXT_ARRAY_ELEMENT: return "array element";
88
- case NEXT_ARRAY_COMMA: return "comma";
89
- case NEXT_HASH_NEW: return "hash pair or close";
90
- case NEXT_HASH_KEY: return "hash key";
91
- case NEXT_HASH_COLON: return "colon";
92
- case NEXT_HASH_VALUE: return "hash value";
93
- case NEXT_HASH_COMMA: return "comma";
94
- case NEXT_NONE: break;
95
- default: break;
78
+ case NEXT_ARRAY_NEW: return "array element or close";
79
+ case NEXT_ARRAY_ELEMENT: return "array element";
80
+ case NEXT_ARRAY_COMMA: return "comma";
81
+ case NEXT_HASH_NEW: return "hash pair or close";
82
+ case NEXT_HASH_KEY: return "hash key";
83
+ case NEXT_HASH_COLON: return "colon";
84
+ case NEXT_HASH_VALUE: return "hash value";
85
+ case NEXT_HASH_COMMA: return "comma";
86
+ case NEXT_NONE: break;
87
+ default: break;
96
88
  }
97
89
  return "nothing";
98
90
  }
data/ext/oj/val_stack.h CHANGED
@@ -1,184 +1,150 @@
1
- /* val_stack.h
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * - Redistributions of source code must retain the above copyright notice, this
9
- * list of conditions and the following disclaimer.
10
- *
11
- * - Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * - Neither the name of Peter Ohler nor the names of its contributors may be
16
- * used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
30
-
31
- #ifndef __OJ_VAL_STACK_H__
32
- #define __OJ_VAL_STACK_H__
1
+ // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #ifndef OJ_VAL_STACK_H
5
+ #define OJ_VAL_STACK_H
33
6
 
34
- #include "ruby.h"
35
- #include "odd.h"
36
7
  #include <stdint.h>
37
- #if USE_PTHREAD_MUTEX
8
+
9
+ #include "odd.h"
10
+ #include "ruby.h"
11
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
38
12
  #include <pthread.h>
39
13
  #endif
40
14
 
41
- #define STACK_INC 64
15
+ #define STACK_INC 64
42
16
 
43
17
  typedef enum {
44
- NEXT_NONE = 0,
45
- NEXT_ARRAY_NEW = 'a',
46
- NEXT_ARRAY_ELEMENT = 'e',
47
- NEXT_ARRAY_COMMA = ',',
48
- NEXT_HASH_NEW = 'h',
49
- NEXT_HASH_KEY = 'k',
50
- NEXT_HASH_COLON = ':',
51
- NEXT_HASH_VALUE = 'v',
52
- NEXT_HASH_COMMA = 'n',
18
+ NEXT_NONE = 0,
19
+ NEXT_ARRAY_NEW = 'a',
20
+ NEXT_ARRAY_ELEMENT = 'e',
21
+ NEXT_ARRAY_COMMA = ',',
22
+ NEXT_HASH_NEW = 'h',
23
+ NEXT_HASH_KEY = 'k',
24
+ NEXT_HASH_COLON = ':',
25
+ NEXT_HASH_VALUE = 'v',
26
+ NEXT_HASH_COMMA = 'n',
53
27
  } ValNext;
54
28
 
55
- typedef struct _Val {
56
- volatile VALUE val;
57
- const char *key;
58
- char karray[32];
59
- volatile VALUE key_val;
60
- union {
61
- const char *classname;
62
- OddArgs odd_args;
63
- };
64
- uint16_t klen;
65
- uint16_t clen;
66
- char next; // ValNext
67
- char k1; // first original character in the key
68
- char kalloc;
69
- } *Val;
70
-
71
- typedef struct _ValStack {
72
- struct _Val base[STACK_INC];
73
- Val head; // current stack
74
- Val end; // stack end
75
- Val tail; // pointer to one past last element name on stack
76
- #if USE_PTHREAD_MUTEX
77
- pthread_mutex_t mutex;
78
- #elif USE_RB_MUTEX
79
- VALUE mutex;
29
+ typedef struct _val {
30
+ volatile VALUE val;
31
+ const char * key;
32
+ char karray[32];
33
+ volatile VALUE key_val;
34
+ const char * classname;
35
+ VALUE clas;
36
+ OddArgs odd_args;
37
+ uint16_t klen;
38
+ uint16_t clen;
39
+ char next; // ValNext
40
+ char k1; // first original character in the key
41
+ char kalloc;
42
+ } * Val;
43
+
44
+ typedef struct _valStack {
45
+ struct _val base[STACK_INC];
46
+ Val head; // current stack
47
+ Val end; // stack end
48
+ Val tail; // pointer to one past last element name on stack
49
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
50
+ pthread_mutex_t mutex;
51
+ #else
52
+ VALUE mutex;
80
53
  #endif
81
54
 
82
- } *ValStack;
55
+ } * ValStack;
83
56
 
84
- extern VALUE oj_stack_init(ValStack stack);
57
+ extern VALUE oj_stack_init(ValStack stack);
85
58
 
86
- inline static int
87
- stack_empty(ValStack stack) {
59
+ inline static int stack_empty(ValStack stack) {
88
60
  return (stack->head == stack->tail);
89
61
  }
90
62
 
91
- inline static void
92
- stack_cleanup(ValStack stack) {
63
+ inline static void stack_cleanup(ValStack stack) {
93
64
  if (stack->base != stack->head) {
94
65
  xfree(stack->head);
95
- stack->head = NULL;
66
+ stack->head = NULL;
96
67
  }
97
68
  }
98
69
 
99
- inline static void
100
- stack_push(ValStack stack, VALUE val, ValNext next) {
70
+ inline static void stack_push(ValStack stack, VALUE val, ValNext next) {
101
71
  if (stack->end <= stack->tail) {
102
- size_t len = stack->end - stack->head;
103
- size_t toff = stack->tail - stack->head;
104
- Val head = stack->head;
105
-
106
- // A realloc can trigger a GC so make sure it happens outside the lock
107
- // but lock before changing pointers.
108
- if (stack->base == stack->head) {
109
- head = ALLOC_N(struct _Val, len + STACK_INC);
110
- memcpy(head, stack->base, sizeof(struct _Val) * len);
111
- } else {
112
- REALLOC_N(head, struct _Val, len + STACK_INC);
113
- }
114
- #if USE_PTHREAD_MUTEX
115
- pthread_mutex_lock(&stack->mutex);
116
- #elif USE_RB_MUTEX
117
- rb_mutex_lock(stack->mutex);
72
+ size_t len = stack->end - stack->head;
73
+ size_t toff = stack->tail - stack->head;
74
+ Val head = stack->head;
75
+
76
+ // A realloc can trigger a GC so make sure it happens outside the lock
77
+ // but lock before changing pointers.
78
+ if (stack->base == stack->head) {
79
+ head = ALLOC_N(struct _val, len + STACK_INC);
80
+ memcpy(head, stack->base, sizeof(struct _val) * len);
81
+ } else {
82
+ REALLOC_N(head, struct _val, len + STACK_INC);
83
+ }
84
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
85
+ pthread_mutex_lock(&stack->mutex);
86
+ #else
87
+ rb_mutex_lock(stack->mutex);
118
88
  #endif
119
- stack->head = head;
120
- stack->tail = stack->head + toff;
121
- stack->end = stack->head + len + STACK_INC;
122
- #if USE_PTHREAD_MUTEX
123
- pthread_mutex_unlock(&stack->mutex);
124
- #elif USE_RB_MUTEX
125
- rb_mutex_unlock(stack->mutex);
89
+ stack->head = head;
90
+ stack->tail = stack->head + toff;
91
+ stack->end = stack->head + len + STACK_INC;
92
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
93
+ pthread_mutex_unlock(&stack->mutex);
94
+ #else
95
+ rb_mutex_unlock(stack->mutex);
126
96
  #endif
127
97
  }
128
- stack->tail->val = val;
129
- stack->tail->next = next;
130
- stack->tail->classname = 0;
131
- stack->tail->key = 0;
132
- stack->tail->key_val = Qundef;
133
- stack->tail->clen = 0;
134
- stack->tail->klen = 0;
135
- stack->tail->kalloc = 0;
98
+ stack->tail->val = val;
99
+ stack->tail->next = next;
100
+ stack->tail->classname = NULL;
101
+ stack->tail->clas = Qundef;
102
+ stack->tail->odd_args = NULL;
103
+ stack->tail->key = 0;
104
+ stack->tail->key_val = Qundef;
105
+ stack->tail->clen = 0;
106
+ stack->tail->klen = 0;
107
+ stack->tail->kalloc = 0;
136
108
  stack->tail++;
137
109
  }
138
110
 
139
- inline static size_t
140
- stack_size(ValStack stack) {
111
+ inline static size_t stack_size(ValStack stack) {
141
112
  return stack->tail - stack->head;
142
113
  }
143
114
 
144
- inline static Val
145
- stack_peek(ValStack stack) {
115
+ inline static Val stack_peek(ValStack stack) {
146
116
  if (stack->head < stack->tail) {
147
- return stack->tail - 1;
117
+ return stack->tail - 1;
148
118
  }
149
119
  return 0;
150
120
  }
151
121
 
152
- inline static Val
153
- stack_peek_up(ValStack stack) {
122
+ inline static Val stack_peek_up(ValStack stack) {
154
123
  if (stack->head < stack->tail - 1) {
155
- return stack->tail - 2;
124
+ return stack->tail - 2;
156
125
  }
157
126
  return 0;
158
127
  }
159
128
 
160
- inline static Val
161
- stack_prev(ValStack stack) {
129
+ inline static Val stack_prev(ValStack stack) {
162
130
  return stack->tail;
163
131
  }
164
132
 
165
- inline static VALUE
166
- stack_head_val(ValStack stack) {
133
+ inline static VALUE stack_head_val(ValStack stack) {
167
134
  if (Qundef != stack->head->val) {
168
- return stack->head->val;
135
+ return stack->head->val;
169
136
  }
170
137
  return Qnil;
171
138
  }
172
139
 
173
- inline static Val
174
- stack_pop(ValStack stack) {
140
+ inline static Val stack_pop(ValStack stack) {
175
141
  if (stack->head < stack->tail) {
176
- stack->tail--;
177
- return stack->tail;
142
+ stack->tail--;
143
+ return stack->tail;
178
144
  }
179
145
  return 0;
180
146
  }
181
147
 
182
- extern const char* oj_stack_next_string(ValNext n);
148
+ extern const char *oj_stack_next_string(ValNext n);
183
149
 
184
- #endif /* __OJ_VAL_STACK_H__ */
150
+ #endif /* OJ_VAL_STACK_H */
data/ext/oj/validate.c ADDED
@@ -0,0 +1,51 @@
1
+ // Copyright (c) 2021, Peter Ohler, All rights reserved.
2
+
3
+ #include "parser.h"
4
+
5
+ static void
6
+ noop(ojParser p) {
7
+ }
8
+
9
+ static VALUE
10
+ option(ojParser p, const char *key, VALUE value) {
11
+ rb_raise(rb_eArgError, "%s is not an option for the validate delegate", key);
12
+ return Qnil;
13
+ }
14
+
15
+ static VALUE
16
+ result(ojParser p) {
17
+ return Qnil;
18
+ }
19
+
20
+ static void
21
+ dfree(ojParser p) {
22
+ }
23
+
24
+ static void
25
+ mark(ojParser p) {
26
+ }
27
+
28
+ void oj_set_parser_validator(ojParser p) {
29
+ p->ctx = NULL;
30
+ Funcs end = p->funcs + 3;
31
+ Funcs f;
32
+
33
+ for (f = p->funcs; f < end; f++) {
34
+ f->add_null = noop;
35
+ f->add_true = noop;
36
+ f->add_false = noop;
37
+ f->add_int = noop;
38
+ f->add_float = noop;
39
+ f->add_big = noop;
40
+ f->add_str = noop;
41
+ f->open_array = noop;
42
+ f->close_array = noop;
43
+ f->open_object = noop;
44
+ f->close_object = noop;
45
+ }
46
+ p->option = option;
47
+ p->result = result;
48
+ p->free = dfree;
49
+ p->mark = mark;
50
+ p->start = noop;
51
+ }