ox-bundlecachetest 2.14.23

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +751 -0
  3. data/LICENSE +21 -0
  4. data/README.md +351 -0
  5. data/ext/ox/attr.h +78 -0
  6. data/ext/ox/base64.c +105 -0
  7. data/ext/ox/base64.h +18 -0
  8. data/ext/ox/buf.h +162 -0
  9. data/ext/ox/builder.c +948 -0
  10. data/ext/ox/cache.c +351 -0
  11. data/ext/ox/cache.h +21 -0
  12. data/ext/ox/cache8.c +106 -0
  13. data/ext/ox/cache8.h +23 -0
  14. data/ext/ox/dump.c +1260 -0
  15. data/ext/ox/err.c +46 -0
  16. data/ext/ox/err.h +36 -0
  17. data/ext/ox/extconf.rb +47 -0
  18. data/ext/ox/gen_load.c +342 -0
  19. data/ext/ox/hash_load.c +309 -0
  20. data/ext/ox/helper.h +84 -0
  21. data/ext/ox/intern.c +157 -0
  22. data/ext/ox/intern.h +25 -0
  23. data/ext/ox/obj_load.c +809 -0
  24. data/ext/ox/ox.c +1649 -0
  25. data/ext/ox/ox.h +245 -0
  26. data/ext/ox/parse.c +1197 -0
  27. data/ext/ox/sax.c +1570 -0
  28. data/ext/ox/sax.h +69 -0
  29. data/ext/ox/sax_as.c +270 -0
  30. data/ext/ox/sax_buf.c +209 -0
  31. data/ext/ox/sax_buf.h +204 -0
  32. data/ext/ox/sax_hint.c +207 -0
  33. data/ext/ox/sax_hint.h +40 -0
  34. data/ext/ox/sax_stack.h +113 -0
  35. data/ext/ox/slotcache.c +158 -0
  36. data/ext/ox/slotcache.h +19 -0
  37. data/ext/ox/special.c +390 -0
  38. data/ext/ox/special.h +14 -0
  39. data/ext/ox/type.h +39 -0
  40. data/lib/ox/bag.rb +103 -0
  41. data/lib/ox/cdata.rb +10 -0
  42. data/lib/ox/comment.rb +11 -0
  43. data/lib/ox/doctype.rb +11 -0
  44. data/lib/ox/document.rb +28 -0
  45. data/lib/ox/element.rb +464 -0
  46. data/lib/ox/error.rb +25 -0
  47. data/lib/ox/hasattrs.rb +54 -0
  48. data/lib/ox/instruct.rb +34 -0
  49. data/lib/ox/node.rb +23 -0
  50. data/lib/ox/raw.rb +12 -0
  51. data/lib/ox/sax.rb +97 -0
  52. data/lib/ox/version.rb +4 -0
  53. data/lib/ox/xmlrpc_adapter.rb +33 -0
  54. data/lib/ox.rb +79 -0
  55. metadata +128 -0
@@ -0,0 +1,309 @@
1
+ /* hash_load.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include <errno.h>
7
+ #include <stdarg.h>
8
+ #include <stdbool.h>
9
+ #include <stdio.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+
13
+ #include "ox.h"
14
+ #include "ruby.h"
15
+
16
+ #define MARK_INC 256
17
+
18
+ // The approach taken for the hash and has_no_attrs parsing is to push just
19
+ // the key on to the stack and then decide what to do on the way up/out.
20
+
21
+ static VALUE create_top(PInfo pi) {
22
+ volatile VALUE top = rb_hash_new();
23
+
24
+ helper_stack_push(&pi->helpers, 0, top, HashCode);
25
+ pi->obj = top;
26
+
27
+ return top;
28
+ }
29
+
30
+ static void mark_value(PInfo pi, VALUE val) {
31
+ if (NULL == pi->marked) {
32
+ pi->marked = ALLOC_N(VALUE, MARK_INC);
33
+ pi->mark_size = MARK_INC;
34
+ } else if (pi->mark_size <= pi->mark_cnt) {
35
+ pi->mark_size += MARK_INC;
36
+ REALLOC_N(pi->marked, VALUE, pi->mark_size);
37
+ }
38
+ pi->marked[pi->mark_cnt] = val;
39
+ pi->mark_cnt++;
40
+ }
41
+
42
+ static bool marked(PInfo pi, VALUE val) {
43
+ if (NULL != pi->marked) {
44
+ VALUE *vp = pi->marked + pi->mark_cnt - 1;
45
+
46
+ for (; pi->marked <= vp; vp--) {
47
+ if (val == *vp) {
48
+ return true;
49
+ }
50
+ }
51
+ }
52
+ return false;
53
+ }
54
+
55
+ static void unmark(PInfo pi, VALUE val) {
56
+ if (NULL != pi->marked) {
57
+ VALUE *vp = pi->marked + pi->mark_cnt - 1;
58
+ int i;
59
+
60
+ for (i = 0; pi->marked <= vp; vp--, i++) {
61
+ if (val == *vp) {
62
+ for (; 0 < i; i--, vp++) {
63
+ *vp = *(vp + 1);
64
+ }
65
+ pi->mark_cnt--;
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ static void add_str(PInfo pi, VALUE s) {
73
+ Helper parent = helper_stack_peek(&pi->helpers);
74
+ volatile VALUE a;
75
+
76
+ if (0 != pi->options->rb_enc) {
77
+ rb_enc_associate(s, pi->options->rb_enc);
78
+ }
79
+ switch (parent->type) {
80
+ case NoCode:
81
+ parent->obj = s;
82
+ parent->type = StringCode;
83
+ break;
84
+ case ArrayCode: rb_ary_push(parent->obj, s); break;
85
+ default:
86
+ a = rb_ary_new();
87
+ rb_ary_push(a, parent->obj);
88
+ rb_ary_push(a, s);
89
+ parent->obj = a;
90
+ parent->type = ArrayCode;
91
+ break;
92
+ }
93
+ }
94
+
95
+ static void add_text(PInfo pi, char *text, int closed) {
96
+ VALUE s = rb_str_new2(text);
97
+ if (0 != pi->options->rb_enc) {
98
+ rb_enc_associate(s, pi->options->rb_enc);
99
+ }
100
+ add_str(pi, s);
101
+ }
102
+
103
+ static void add_cdata(PInfo pi, const char *text, size_t len) {
104
+ VALUE s = rb_str_new2(text);
105
+ if (0 != pi->options->rb_enc) {
106
+ rb_enc_associate(s, pi->options->rb_enc);
107
+ }
108
+ add_str(pi, s);
109
+ }
110
+
111
+ static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
112
+ VALUE s = rb_str_new2(ename);
113
+ if (0 != pi->options->rb_enc) {
114
+ rb_enc_associate(s, pi->options->rb_enc);
115
+ }
116
+ if (helper_stack_empty(&pi->helpers)) {
117
+ create_top(pi);
118
+ }
119
+ if (NULL != attrs && NULL != attrs->name) {
120
+ volatile VALUE h = rb_hash_new();
121
+ volatile VALUE key;
122
+ volatile VALUE val;
123
+ volatile VALUE a;
124
+
125
+ for (; 0 != attrs->name; attrs++) {
126
+ key = rb_str_new2(attrs->name);
127
+ if (0 != pi->options->rb_enc) {
128
+ rb_enc_associate(key, pi->options->rb_enc);
129
+ }
130
+ if (Qnil != pi->options->attr_key_mod) {
131
+ key = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, key);
132
+ } else if (Yes == pi->options->sym_keys) {
133
+ key = rb_id2sym(rb_intern_str(key));
134
+ }
135
+ val = rb_str_new2(attrs->value);
136
+ if (0 != pi->options->rb_enc) {
137
+ rb_enc_associate(val, pi->options->rb_enc);
138
+ }
139
+ rb_hash_aset(h, key, val);
140
+ }
141
+ a = rb_ary_new();
142
+ rb_ary_push(a, h);
143
+ mark_value(pi, a);
144
+ helper_stack_push(&pi->helpers, rb_intern_str(s), a, ArrayCode);
145
+ } else {
146
+ helper_stack_push(&pi->helpers, rb_intern_str(s), Qnil, NoCode);
147
+ }
148
+ }
149
+
150
+ static void add_element_no_attrs(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
151
+ VALUE s = rb_str_new2(ename);
152
+ if (0 != pi->options->rb_enc) {
153
+ rb_enc_associate(s, pi->options->rb_enc);
154
+ }
155
+ if (helper_stack_empty(&pi->helpers)) {
156
+ create_top(pi);
157
+ }
158
+ helper_stack_push(&pi->helpers, rb_intern_str(s), Qnil, NoCode);
159
+ }
160
+
161
+ static int umark_hash_cb(VALUE key, VALUE value, VALUE x) {
162
+ unmark((PInfo)x, value);
163
+
164
+ return ST_CONTINUE;
165
+ }
166
+
167
+ static void end_element_core(PInfo pi, const char *ename, bool check_marked) {
168
+ Helper e = helper_stack_pop(&pi->helpers);
169
+ Helper parent = helper_stack_peek(&pi->helpers);
170
+ volatile VALUE pobj = parent->obj;
171
+ volatile VALUE found = Qundef;
172
+ volatile VALUE key;
173
+ volatile VALUE a;
174
+
175
+ if (NoCode == e->type) {
176
+ e->obj = Qnil;
177
+ }
178
+ if (Qnil != pi->options->element_key_mod) {
179
+ key = rb_funcall(pi->options->element_key_mod, ox_call_id, 1, rb_id2str(e->var));
180
+ } else if (Yes == pi->options->sym_keys) {
181
+ key = rb_id2sym(e->var);
182
+ } else {
183
+ key = rb_id2str(e->var);
184
+ }
185
+ // Make sure the parent is a Hash. If not set then make a Hash. If an
186
+ // Array or non-Hash then append to array or create and append.
187
+ switch (parent->type) {
188
+ case NoCode:
189
+ pobj = rb_hash_new();
190
+ parent->obj = pobj;
191
+ parent->type = HashCode;
192
+ break;
193
+ case ArrayCode:
194
+ pobj = rb_hash_new();
195
+ rb_ary_push(parent->obj, pobj);
196
+ break;
197
+ case HashCode: found = rb_hash_lookup2(parent->obj, key, Qundef); break;
198
+ default:
199
+ a = rb_ary_new();
200
+ rb_ary_push(a, parent->obj);
201
+ pobj = rb_hash_new();
202
+ rb_ary_push(a, pobj);
203
+ parent->obj = a;
204
+ parent->type = ArrayCode;
205
+ break;
206
+ }
207
+ if (Qundef == found) {
208
+ rb_hash_aset(pobj, key, e->obj);
209
+ } else if (RUBY_T_ARRAY == rb_type(found)) {
210
+ if (check_marked && marked(pi, found)) {
211
+ unmark(pi, found);
212
+ a = rb_ary_new();
213
+ rb_ary_push(a, found);
214
+ rb_ary_push(a, e->obj);
215
+ rb_hash_aset(pobj, key, a);
216
+ } else {
217
+ rb_ary_push(found, e->obj);
218
+ }
219
+ } else { // something there other than an array
220
+ if (check_marked && marked(pi, e->obj)) {
221
+ unmark(pi, e->obj);
222
+ }
223
+ a = rb_ary_new();
224
+ rb_ary_push(a, found);
225
+ rb_ary_push(a, e->obj);
226
+ rb_hash_aset(pobj, key, a);
227
+ }
228
+ if (check_marked && NULL != pi->marked && RUBY_T_HASH == rb_type(e->obj)) {
229
+ rb_hash_foreach(e->obj, umark_hash_cb, (VALUE)pi);
230
+ }
231
+ }
232
+
233
+ static void end_element(PInfo pi, const char *ename) {
234
+ end_element_core(pi, ename, true);
235
+ }
236
+
237
+ static void end_element_no_attrs(PInfo pi, const char *ename) {
238
+ end_element_core(pi, ename, false);
239
+ }
240
+
241
+ static void finish(PInfo pi) {
242
+ xfree(pi->marked);
243
+ }
244
+
245
+ static void set_encoding_from_instruct(PInfo pi, Attr attrs) {
246
+ for (; 0 != attrs->name; attrs++) {
247
+ if (0 == strcmp("encoding", attrs->name)) {
248
+ pi->options->rb_enc = rb_enc_find(attrs->value);
249
+ }
250
+ }
251
+ }
252
+
253
+ static void instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
254
+ if (0 == strcmp("xml", target)) {
255
+ set_encoding_from_instruct(pi, attrs);
256
+ }
257
+ }
258
+
259
+ struct _parseCallbacks _ox_hash_callbacks = {
260
+ instruct,
261
+ NULL,
262
+ NULL,
263
+ NULL,
264
+ add_text,
265
+ add_element,
266
+ end_element,
267
+ finish,
268
+ };
269
+
270
+ ParseCallbacks ox_hash_callbacks = &_ox_hash_callbacks;
271
+
272
+ struct _parseCallbacks _ox_hash_cdata_callbacks = {
273
+ instruct,
274
+ NULL,
275
+ NULL,
276
+ add_cdata,
277
+ add_text,
278
+ add_element,
279
+ end_element,
280
+ finish,
281
+ };
282
+
283
+ ParseCallbacks ox_hash_cdata_callbacks = &_ox_hash_cdata_callbacks;
284
+
285
+ struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
286
+ instruct,
287
+ NULL,
288
+ NULL,
289
+ NULL,
290
+ add_text,
291
+ add_element_no_attrs,
292
+ end_element_no_attrs,
293
+ NULL,
294
+ };
295
+
296
+ ParseCallbacks ox_hash_no_attrs_callbacks = &_ox_hash_no_attrs_callbacks;
297
+
298
+ struct _parseCallbacks _ox_hash_no_attrs_cdata_callbacks = {
299
+ instruct,
300
+ NULL,
301
+ NULL,
302
+ add_cdata,
303
+ add_text,
304
+ add_element_no_attrs,
305
+ end_element_no_attrs,
306
+ NULL,
307
+ };
308
+
309
+ ParseCallbacks ox_hash_no_attrs_cdata_callbacks = &_ox_hash_no_attrs_cdata_callbacks;
data/ext/ox/helper.h ADDED
@@ -0,0 +1,84 @@
1
+ /* helper.h
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #ifndef OX_HELPER_H
7
+ #define OX_HELPER_H
8
+
9
+ #include "type.h"
10
+
11
+ #define HELPER_STACK_INC 16
12
+
13
+ typedef struct _helper {
14
+ ID var; /* Object var ID */
15
+ VALUE obj; /* object created or Qundef if not appropriate */
16
+ Type type; /* type of object in obj */
17
+ } *Helper;
18
+
19
+ typedef struct _helperStack {
20
+ struct _helper base[HELPER_STACK_INC];
21
+ Helper head; /* current stack */
22
+ Helper end; /* stack end */
23
+ Helper tail; /* pointer to one past last element name on stack */
24
+ } *HelperStack;
25
+
26
+ inline static void helper_stack_init(HelperStack stack) {
27
+ stack->head = stack->base;
28
+ stack->end = stack->base + sizeof(stack->base) / sizeof(struct _helper);
29
+ stack->tail = stack->head;
30
+ }
31
+
32
+ inline static int helper_stack_empty(HelperStack stack) {
33
+ return (stack->head == stack->tail);
34
+ }
35
+
36
+ inline static int helper_stack_depth(HelperStack stack) {
37
+ return (int)(stack->tail - stack->head);
38
+ }
39
+
40
+ inline static void helper_stack_cleanup(HelperStack stack) {
41
+ if (stack->base != stack->head) {
42
+ xfree(stack->head);
43
+ stack->head = stack->base;
44
+ }
45
+ }
46
+
47
+ inline static Helper helper_stack_push(HelperStack stack, ID var, VALUE obj, Type type) {
48
+ if (stack->end <= stack->tail) {
49
+ size_t len = stack->end - stack->head;
50
+ size_t toff = stack->tail - stack->head;
51
+
52
+ if (stack->base == stack->head) {
53
+ stack->head = ALLOC_N(struct _helper, len + HELPER_STACK_INC);
54
+ memcpy(stack->head, stack->base, sizeof(struct _helper) * len);
55
+ } else {
56
+ REALLOC_N(stack->head, struct _helper, len + HELPER_STACK_INC);
57
+ }
58
+ stack->tail = stack->head + toff;
59
+ stack->end = stack->head + len + HELPER_STACK_INC;
60
+ }
61
+ stack->tail->var = var;
62
+ stack->tail->obj = obj;
63
+ stack->tail->type = type;
64
+ stack->tail++;
65
+
66
+ return stack->tail - 1;
67
+ }
68
+
69
+ inline static Helper helper_stack_peek(HelperStack stack) {
70
+ if (stack->head < stack->tail) {
71
+ return stack->tail - 1;
72
+ }
73
+ return 0;
74
+ }
75
+
76
+ inline static Helper helper_stack_pop(HelperStack stack) {
77
+ if (stack->head < stack->tail) {
78
+ stack->tail--;
79
+ return stack->tail;
80
+ }
81
+ return 0;
82
+ }
83
+
84
+ #endif /* OX_HELPER_H */
data/ext/ox/intern.c ADDED
@@ -0,0 +1,157 @@
1
+ // Copyright (c) 2011, 2021 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+
4
+ #include "intern.h"
5
+
6
+ #include <stdint.h>
7
+
8
+ #include "cache.h"
9
+ #include "ox.h"
10
+ #include "ruby/version.h"
11
+
12
+ // These are statics but in an attempt to stop the cross linking or maybe
13
+ // something in Ruby they all have been given an ox prefix.
14
+ static struct _cache *ox_str_cache = NULL;
15
+ static VALUE ox_str_cache_obj;
16
+
17
+ static struct _cache *ox_sym_cache = NULL;
18
+ static VALUE ox_sym_cache_obj;
19
+
20
+ static struct _cache *ox_attr_cache = NULL;
21
+ static VALUE ox_attr_cache_obj;
22
+
23
+ static struct _cache *ox_id_cache = NULL;
24
+ static VALUE ox_id_cache_obj;
25
+
26
+ static VALUE form_str(const char *str, size_t len) {
27
+ return rb_str_freeze(rb_utf8_str_new(str, len));
28
+ }
29
+
30
+ static VALUE form_sym(const char *str, size_t len) {
31
+ return rb_to_symbol(rb_str_freeze(rb_utf8_str_new(str, len)));
32
+ }
33
+
34
+ static VALUE form_attr(const char *str, size_t len) {
35
+ char buf[256];
36
+
37
+ if (sizeof(buf) - 2 <= len) {
38
+ char *b = ALLOC_N(char, len + 2);
39
+ ID id;
40
+
41
+ if ('~' == *str) {
42
+ memcpy(b, str + 1, len - 1);
43
+ b[len - 1] = '\0';
44
+ len -= 2;
45
+ } else {
46
+ *b = '@';
47
+ memcpy(b + 1, str, len);
48
+ b[len + 1] = '\0';
49
+ }
50
+ id = rb_intern3(buf, len + 1, rb_utf8_encoding());
51
+ xfree(b);
52
+ return id;
53
+ }
54
+ if ('~' == *str) {
55
+ memcpy(buf, str + 1, len - 1);
56
+ buf[len - 1] = '\0';
57
+ len -= 2;
58
+ } else {
59
+ *buf = '@';
60
+ memcpy(buf + 1, str, len);
61
+ buf[len + 1] = '\0';
62
+ }
63
+ return (VALUE)rb_intern3(buf, len + 1, rb_utf8_encoding());
64
+ }
65
+
66
+ static VALUE form_id(const char *str, size_t len) {
67
+ return (VALUE)rb_intern3(str, len, rb_utf8_encoding());
68
+ }
69
+
70
+ void ox_hash_init(void) {
71
+ VALUE cache_class = rb_define_class_under(Ox, "Cache", rb_cObject);
72
+ #if RUBY_API_VERSION_CODE >= 30200
73
+ rb_undef_alloc_func(cache_class);
74
+ #endif
75
+
76
+ ox_str_cache = ox_cache_create(0, form_str, true, false);
77
+ ox_str_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_str_cache);
78
+ rb_gc_register_address(&ox_str_cache_obj);
79
+
80
+ ox_sym_cache = ox_cache_create(0, form_sym, true, false);
81
+ ox_sym_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_sym_cache);
82
+ rb_gc_register_address(&ox_sym_cache_obj);
83
+
84
+ ox_attr_cache = ox_cache_create(0, form_attr, false, false);
85
+ ox_attr_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_attr_cache);
86
+ rb_gc_register_address(&ox_attr_cache_obj);
87
+
88
+ ox_id_cache = ox_cache_create(0, form_id, false, false);
89
+ ox_id_cache_obj = TypedData_Wrap_Struct(cache_class, &ox_cache_type, ox_id_cache);
90
+ rb_gc_register_address(&ox_id_cache_obj);
91
+ }
92
+
93
+ VALUE
94
+ ox_str_intern(const char *key, size_t len, const char **keyp) {
95
+ // For huge cache sizes over half a million the rb_enc_interned_str
96
+ // performs slightly better but at more "normal" size of a several
97
+ // thousands the cache intern performs about 20% better.
98
+ #if HAVE_RB_ENC_INTERNED_STR && 0
99
+ return rb_enc_interned_str(key, len, rb_utf8_encoding());
100
+ #else
101
+ return ox_cache_intern(ox_str_cache, key, len, keyp);
102
+ #endif
103
+ }
104
+
105
+ VALUE
106
+ ox_sym_intern(const char *key, size_t len, const char **keyp) {
107
+ return ox_cache_intern(ox_sym_cache, key, len, keyp);
108
+ }
109
+
110
+ ID ox_attr_intern(const char *key, size_t len) {
111
+ return ox_cache_intern(ox_attr_cache, key, len, NULL);
112
+ }
113
+
114
+ ID ox_id_intern(const char *key, size_t len) {
115
+ return ox_cache_intern(ox_id_cache, key, len, NULL);
116
+ }
117
+
118
+ char *ox_strndup(const char *s, size_t len) {
119
+ char *d = ALLOC_N(char, len + 1);
120
+
121
+ memcpy(d, s, len);
122
+ d[len] = '\0';
123
+
124
+ return d;
125
+ }
126
+
127
+ VALUE
128
+ ox_utf8_name(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
129
+ return ox_str_intern(str, len, strp);
130
+ }
131
+
132
+ VALUE
133
+ ox_utf8_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
134
+ return ox_sym_intern(str, len, strp);
135
+ }
136
+
137
+ VALUE
138
+ ox_enc_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
139
+ VALUE sym = rb_str_new2(str);
140
+
141
+ rb_enc_associate(sym, encoding);
142
+ if (NULL != strp) {
143
+ *strp = StringValuePtr(sym);
144
+ }
145
+ return rb_to_symbol(sym);
146
+ }
147
+
148
+ VALUE
149
+ ox_enc_name(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
150
+ VALUE sym = rb_str_new2(str);
151
+
152
+ rb_enc_associate(sym, encoding);
153
+ if (NULL != strp) {
154
+ *strp = StringValuePtr(sym);
155
+ }
156
+ return sym;
157
+ }
data/ext/ox/intern.h ADDED
@@ -0,0 +1,25 @@
1
+ // Copyright (c) 2011, 2021 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
+ #ifndef OX_INTERN_H
4
+ #define OX_INTERN_H
5
+
6
+ #include <ruby.h>
7
+ #include <ruby/encoding.h>
8
+
9
+ struct _parseInfo;
10
+
11
+ extern void ox_hash_init();
12
+
13
+ extern VALUE ox_str_intern(const char *key, size_t len, const char **keyp);
14
+ extern VALUE ox_sym_intern(const char *key, size_t len, const char **keyp);
15
+ extern ID ox_attr_intern(const char *key, size_t len);
16
+ extern ID ox_id_intern(const char *key, size_t len);
17
+
18
+ extern char *ox_strndup(const char *s, size_t len);
19
+
20
+ extern VALUE ox_utf8_name(const char *str, size_t len, rb_encoding *encoding, const char **strp);
21
+ extern VALUE ox_utf8_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp);
22
+ extern VALUE ox_enc_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp);
23
+ extern VALUE ox_enc_name(const char *str, size_t len, rb_encoding *encoding, const char **strp);
24
+
25
+ #endif /* OX_INTERN_H */