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/resolve.c CHANGED
@@ -1,129 +1,81 @@
1
- /* resolve.c
2
- * Copyright (c) 2012, 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) 2012 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 <stdlib.h>
32
4
  #include <stdio.h>
5
+ #include <stdlib.h>
33
6
  #include <string.h>
34
- #if USE_PTHREAD_MUTEX
7
+ #ifdef HAVE_PTHREAD_MUTEX_INIT
35
8
  #include <pthread.h>
36
9
  #endif
37
10
 
38
- #include "oj.h"
39
11
  #include "err.h"
12
+ #include "intern.h"
13
+ #include "oj.h"
40
14
  #include "parse.h"
41
- #include "hash.h"
42
15
 
43
- inline static VALUE
44
- resolve_classname(VALUE mod, const char *classname, int auto_define) {
45
- VALUE clas;
46
- ID ci = rb_intern(classname);
16
+ inline static VALUE resolve_classname(VALUE mod, const char *classname, int auto_define) {
17
+ VALUE clas;
18
+ ID ci = rb_intern(classname);
47
19
 
48
20
  if (rb_const_defined_at(mod, ci)) {
49
- clas = rb_const_get_at(mod, ci);
21
+ clas = rb_const_get_at(mod, ci);
50
22
  } else if (auto_define) {
51
- clas = rb_define_class_under(mod, classname, oj_bag_class);
23
+ clas = rb_define_class_under(mod, classname, oj_bag_class);
52
24
  } else {
53
- clas = Qundef;
25
+ clas = Qundef;
54
26
  }
55
27
  return clas;
56
28
  }
57
29
 
58
30
  static VALUE
59
- resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define) {
60
- char class_name[1024];
61
- VALUE clas;
62
- char *end = class_name + sizeof(class_name) - 1;
63
- char *s;
64
- const char *n = name;
31
+ resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
32
+ char class_name[1024];
33
+ VALUE clas;
34
+ char * end = class_name + sizeof(class_name) - 1;
35
+ char * s;
36
+ const char *n = name;
65
37
 
66
38
  clas = rb_cObject;
67
39
  for (s = class_name; 0 < len; n++, len--) {
68
- if (':' == *n) {
69
- *s = '\0';
70
- n++;
71
- len--;
72
- if (':' != *n) {
73
- return Qundef;
74
- }
75
- if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
76
- return Qundef;
77
- }
78
- s = class_name;
79
- } else if (end <= s) {
80
- return Qundef;
81
- } else {
82
- *s++ = *n;
83
- }
40
+ if (':' == *n) {
41
+ *s = '\0';
42
+ n++;
43
+ len--;
44
+ if (':' != *n) {
45
+ return Qundef;
46
+ }
47
+ if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
48
+ return Qundef;
49
+ }
50
+ s = class_name;
51
+ } else if (end <= s) {
52
+ return Qundef;
53
+ } else {
54
+ *s++ = *n;
55
+ }
84
56
  }
85
57
  *s = '\0';
86
58
  if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
87
- if (sizeof(class_name) - 1 < len) {
88
- len = sizeof(class_name) - 1;
89
- }
90
- memcpy(class_name, name, len);
91
- class_name[len] = '\0';
92
- oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "class %s is not defined", class_name);
59
+ oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class %s is not defined", name);
60
+ if (Qnil != error_class) {
61
+ pi->err_class = error_class;
62
+ }
93
63
  }
94
64
  return clas;
95
65
  }
96
66
 
97
67
  VALUE
98
- oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define) {
99
- VALUE clas;
100
- VALUE *slot;
101
-
68
+ oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
102
69
  if (No == pi->options.class_cache) {
103
- return resolve_classpath(pi, name, len, auto_define);
70
+ return resolve_classpath(pi, name, len, auto_define, error_class);
104
71
  }
105
- #if USE_PTHREAD_MUTEX
106
- pthread_mutex_lock(&oj_cache_mutex);
107
- #elif USE_RB_MUTEX
108
- rb_mutex_lock(oj_cache_mutex);
109
- #endif
110
- if (Qnil == (clas = oj_class_hash_get(name, len, &slot))) {
111
- if (Qundef != (clas = resolve_classpath(pi, name, len, auto_define))) {
112
- *slot = clas;
113
- }
114
- }
115
- #if USE_PTHREAD_MUTEX
116
- pthread_mutex_unlock(&oj_cache_mutex);
117
- #elif USE_RB_MUTEX
118
- rb_mutex_unlock(oj_cache_mutex);
119
- #endif
120
- return clas;
72
+ return oj_class_intern(name, len, true, pi, auto_define, error_class);
121
73
  }
122
74
 
123
75
  VALUE
124
- oj_name2struct(ParseInfo pi, VALUE nameVal) {
125
- size_t len = RSTRING_LEN(nameVal);
126
- const char *str = StringValuePtr(nameVal);
76
+ oj_name2struct(ParseInfo pi, VALUE nameVal, VALUE error_class) {
77
+ size_t len = RSTRING_LEN(nameVal);
78
+ const char *str = StringValuePtr(nameVal);
127
79
 
128
- return resolve_classpath(pi, str, len, 0);
80
+ return resolve_classpath(pi, str, len, 0, error_class);
129
81
  }
data/ext/oj/resolve.h CHANGED
@@ -1,39 +1,12 @@
1
- /* resolve.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
- */
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
- #ifndef __OJ_RESOLVE_H__
32
- #define __OJ_RESOLVE_H__
4
+ #ifndef OJ_RESOLVE_H
5
+ #define OJ_RESOLVE_H
33
6
 
34
7
  #include "ruby.h"
35
8
 
36
- extern VALUE oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define);
37
- extern VALUE oj_name2struct(ParseInfo pi, VALUE nameVal);
9
+ extern VALUE oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class);
10
+ extern VALUE oj_name2struct(ParseInfo pi, VALUE nameVal, VALUE error_class);
38
11
 
39
- #endif /* __OJ_RESOLVE_H__ */
12
+ #endif /* OJ_RESOLVE_H */
data/ext/oj/rxclass.c ADDED
@@ -0,0 +1,143 @@
1
+ // Copyright (c) 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #include <errno.h>
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <sys/types.h>
9
+ #if !IS_WINDOWS
10
+ #include <regex.h>
11
+ #endif
12
+
13
+ #include "rxclass.h"
14
+
15
+ typedef struct _rxC {
16
+ struct _rxC *next;
17
+ VALUE rrx;
18
+ #if !IS_WINDOWS
19
+ regex_t rx;
20
+ #endif
21
+ VALUE clas;
22
+ char src[256];
23
+ } * RxC;
24
+
25
+ void oj_rxclass_init(RxClass rc) {
26
+ *rc->err = '\0';
27
+ rc->head = NULL;
28
+ rc->tail = NULL;
29
+ }
30
+
31
+ void oj_rxclass_cleanup(RxClass rc) {
32
+ RxC rxc;
33
+
34
+ while (NULL != (rxc = rc->head)) {
35
+ rc->head = rc->head->next;
36
+ #if !IS_WINDOWS
37
+ if (Qnil == rxc->rrx) {
38
+ regfree(&rxc->rx);
39
+ }
40
+ xfree(rxc);
41
+ #endif
42
+ }
43
+ }
44
+
45
+ void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
46
+ RxC rxc = ALLOC_N(struct _rxC, 1);
47
+
48
+ memset(rxc, 0, sizeof(struct _rxC));
49
+ rxc->rrx = rx;
50
+ rxc->clas = clas;
51
+ if (NULL == rc->tail) {
52
+ rc->head = rxc;
53
+ } else {
54
+ rc->tail->next = rxc;
55
+ }
56
+ rc->tail = rxc;
57
+ }
58
+
59
+ // Attempt to compile the expression. If it fails populate the error code..
60
+ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
61
+ RxC rxc;
62
+ #if !IS_WINDOWS
63
+ int err;
64
+ int flags = 0;
65
+ #endif
66
+ if (sizeof(rxc->src) <= strlen(expr)) {
67
+ snprintf(rc->err,
68
+ sizeof(rc->err),
69
+ "expressions must be less than %lu characters",
70
+ (unsigned long)sizeof(rxc->src));
71
+ return EINVAL;
72
+ }
73
+ rxc = ALLOC_N(struct _rxC, 1);
74
+ rxc->next = 0;
75
+ rxc->clas = clas;
76
+
77
+ #if IS_WINDOWS
78
+ rxc->rrx = rb_funcall(rb_cRegexp, rb_intern("new"), 1, rb_str_new2(expr));
79
+ #else
80
+ rxc->rrx = Qnil;
81
+ if (0 != (err = regcomp(&rxc->rx, expr, flags))) {
82
+ regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
83
+ free(rxc);
84
+ return err;
85
+ }
86
+ #endif
87
+ if (NULL == rc->tail) {
88
+ rc->head = rxc;
89
+ } else {
90
+ rc->tail->next = rxc;
91
+ }
92
+ rc->tail = rxc;
93
+
94
+ return 0;
95
+ }
96
+
97
+ VALUE
98
+ oj_rxclass_match(RxClass rc, const char *str, int len) {
99
+ RxC rxc;
100
+ char buf[4096];
101
+
102
+ for (rxc = rc->head; NULL != rxc; rxc = rxc->next) {
103
+ if (Qnil != rxc->rrx) {
104
+ // Must use a valiabel for this to work.
105
+ volatile VALUE rstr = rb_str_new(str, len);
106
+
107
+ // if (Qtrue == rb_funcall(rxc->rrx, rb_intern("match?"), 1, rstr)) {
108
+ if (Qnil != rb_funcall(rxc->rrx, rb_intern("match"), 1, rstr)) {
109
+ return rxc->clas;
110
+ }
111
+ } else if (len < (int)sizeof(buf)) {
112
+ #if !IS_WINDOWS
113
+ // string is not \0 terminated so copy and attempt a match
114
+ memcpy(buf, str, len);
115
+ buf[len] = '\0';
116
+ if (0 == regexec(&rxc->rx, buf, 0, NULL, 0)) { // match
117
+ return rxc->clas;
118
+ }
119
+ #endif
120
+ } else {
121
+ // TBD allocate a larger buffer and attempt
122
+ }
123
+ }
124
+ return Qnil;
125
+ }
126
+
127
+ void oj_rxclass_copy(RxClass src, RxClass dest) {
128
+ dest->head = NULL;
129
+ dest->tail = NULL;
130
+ if (NULL != src->head) {
131
+ RxC rxc;
132
+
133
+ for (rxc = src->head; NULL != rxc; rxc = rxc->next) {
134
+ if (Qnil != rxc->rrx) {
135
+ oj_rxclass_rappend(dest, rxc->rrx, rxc->clas);
136
+ } else {
137
+ #if !IS_WINDOWS
138
+ oj_rxclass_append(dest, rxc->src, rxc->clas);
139
+ #endif
140
+ }
141
+ }
142
+ }
143
+ }
data/ext/oj/rxclass.h ADDED
@@ -0,0 +1,26 @@
1
+ // Copyright (c) 2017 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_RXCLASS_H
5
+ #define OJ_RXCLASS_H
6
+
7
+ #include <stdbool.h>
8
+
9
+ #include "ruby.h"
10
+
11
+ struct _rxC;
12
+
13
+ typedef struct _rxClass {
14
+ struct _rxC *head;
15
+ struct _rxC *tail;
16
+ char err[128];
17
+ } * RxClass;
18
+
19
+ extern void oj_rxclass_init(RxClass rc);
20
+ extern void oj_rxclass_cleanup(RxClass rc);
21
+ extern int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas);
22
+ extern VALUE oj_rxclass_match(RxClass rc, const char *str, int len);
23
+ extern void oj_rxclass_copy(RxClass src, RxClass dest);
24
+ extern void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas);
25
+
26
+ #endif /* OJ_RXCLASS_H */