ox 2.14.3 → 2.14.7
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 +4 -4
- data/CHANGELOG.md +33 -1
- data/README.md +1 -1
- data/ext/ox/builder.c +8 -8
- data/ext/ox/cache.c +320 -131
- data/ext/ox/cache.h +15 -13
- data/ext/ox/dump.c +2 -2
- data/ext/ox/extconf.rb +5 -2
- data/ext/ox/gen_load.c +8 -76
- data/ext/ox/hash_load.c +0 -4
- data/ext/ox/intern.c +158 -0
- data/ext/ox/intern.h +25 -0
- data/ext/ox/obj_load.c +12 -85
- data/ext/ox/ox.c +1018 -931
- data/ext/ox/ox.h +188 -210
- data/ext/ox/oxcache.c +160 -0
- data/ext/ox/oxcache.h +19 -0
- data/ext/ox/parse.c +72 -31
- data/ext/ox/sax.c +1093 -1279
- data/ext/ox/sax.h +45 -31
- data/ext/ox/sax_as.c +3 -5
- data/ext/ox/sax_buf.c +7 -16
- data/lib/ox/version.rb +1 -1
- metadata +11 -5
- data/ext/ox/sax_has.h +0 -53
data/ext/ox/gen_load.c
CHANGED
@@ -10,10 +10,9 @@
|
|
10
10
|
#include <stdarg.h>
|
11
11
|
|
12
12
|
#include "ruby.h"
|
13
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
14
13
|
#include "ruby/encoding.h"
|
15
|
-
#endif
|
16
14
|
#include "ox.h"
|
15
|
+
#include "intern.h"
|
17
16
|
|
18
17
|
static void instruct(PInfo pi, const char *target, Attr attrs, const char *content);
|
19
18
|
static void create_doc(PInfo pi);
|
@@ -103,7 +102,6 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
|
|
103
102
|
sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name));
|
104
103
|
rb_hash_aset(ah, sym, rb_str_new2(attrs->value));
|
105
104
|
} else if (Yes == pi->options->sym_keys) {
|
106
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
107
105
|
if (0 != pi->options->rb_enc) {
|
108
106
|
VALUE rstr = rb_str_new2(attrs->name);
|
109
107
|
|
@@ -113,20 +111,17 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
|
|
113
111
|
sym = ID2SYM(rb_intern(attrs->name));
|
114
112
|
}
|
115
113
|
sym = ID2SYM(rb_intern(attrs->name));
|
116
|
-
#endif
|
117
114
|
rb_hash_aset(ah, sym, rb_str_new2(attrs->value));
|
118
115
|
} else {
|
119
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
120
116
|
volatile VALUE rstr = rb_str_new2(attrs->name);
|
121
117
|
|
122
118
|
if (0 != pi->options->rb_enc) {
|
123
119
|
rb_enc_associate(rstr, pi->options->rb_enc);
|
124
120
|
}
|
125
121
|
rb_hash_aset(ah, rstr, rb_str_new2(attrs->value));
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
#endif
|
122
|
+
}
|
123
|
+
if (0 == strcmp("encoding", attrs->name)) {
|
124
|
+
pi->options->rb_enc = rb_enc_find(attrs->value);
|
130
125
|
}
|
131
126
|
}
|
132
127
|
nodes = rb_ary_new();
|
@@ -195,11 +190,9 @@ add_doctype(PInfo pi, const char *docType) {
|
|
195
190
|
VALUE n = rb_obj_alloc(ox_doctype_clas);
|
196
191
|
VALUE s = rb_str_new2(docType);
|
197
192
|
|
198
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
199
193
|
if (0 != pi->options->rb_enc) {
|
200
194
|
rb_enc_associate(s, pi->options->rb_enc);
|
201
195
|
}
|
202
|
-
#endif
|
203
196
|
rb_ivar_set(n, ox_at_value_id, s);
|
204
197
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
205
198
|
create_doc(pi);
|
@@ -212,11 +205,9 @@ add_comment(PInfo pi, const char *comment) {
|
|
212
205
|
VALUE n = rb_obj_alloc(ox_comment_clas);
|
213
206
|
VALUE s = rb_str_new2(comment);
|
214
207
|
|
215
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
216
208
|
if (0 != pi->options->rb_enc) {
|
217
209
|
rb_enc_associate(s, pi->options->rb_enc);
|
218
210
|
}
|
219
|
-
#endif
|
220
211
|
rb_ivar_set(n, ox_at_value_id, s);
|
221
212
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
222
213
|
create_doc(pi);
|
@@ -229,11 +220,9 @@ add_cdata(PInfo pi, const char *cdata, size_t len) {
|
|
229
220
|
VALUE n = rb_obj_alloc(ox_cdata_clas);
|
230
221
|
VALUE s = rb_str_new2(cdata);
|
231
222
|
|
232
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
233
223
|
if (0 != pi->options->rb_enc) {
|
234
224
|
rb_enc_associate(s, pi->options->rb_enc);
|
235
225
|
}
|
236
|
-
#endif
|
237
226
|
rb_ivar_set(n, ox_at_value_id, s);
|
238
227
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
239
228
|
create_doc(pi);
|
@@ -245,11 +234,9 @@ static void
|
|
245
234
|
add_text(PInfo pi, char *text, int closed) {
|
246
235
|
VALUE s = rb_str_new2(text);
|
247
236
|
|
248
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
249
237
|
if (0 != pi->options->rb_enc) {
|
250
238
|
rb_enc_associate(s, pi->options->rb_enc);
|
251
239
|
}
|
252
|
-
#endif
|
253
240
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
254
241
|
create_doc(pi);
|
255
242
|
}
|
@@ -264,11 +251,9 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
264
251
|
if (Qnil != pi->options->element_key_mod) {
|
265
252
|
s = rb_funcall(pi->options->element_key_mod, ox_call_id, 1, s);
|
266
253
|
}
|
267
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
268
254
|
if (0 != pi->options->rb_enc) {
|
269
255
|
rb_enc_associate(s, pi->options->rb_enc);
|
270
256
|
}
|
271
|
-
#endif
|
272
257
|
e = rb_obj_alloc(ox_element_clas);
|
273
258
|
rb_ivar_set(e, ox_at_value_id, s);
|
274
259
|
if (0 != attrs->name) {
|
@@ -280,40 +265,14 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
280
265
|
if (Qnil != pi->options->attr_key_mod) {
|
281
266
|
sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name));
|
282
267
|
} else if (Yes == pi->options->sym_keys) {
|
283
|
-
|
284
|
-
|
285
|
-
if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot, 0))) {
|
286
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
287
|
-
if (0 != pi->options->rb_enc) {
|
288
|
-
VALUE rstr = rb_str_new2(attrs->name);
|
289
|
-
|
290
|
-
rb_enc_associate(rstr, pi->options->rb_enc);
|
291
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
292
|
-
} else {
|
293
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
294
|
-
}
|
295
|
-
#else
|
296
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
297
|
-
#endif
|
298
|
-
// Needed for Ruby 2.2 to get around the GC of symbols
|
299
|
-
// created with to_sym which is needed for encoded symbols.
|
300
|
-
rb_ary_push(ox_sym_bank, sym);
|
301
|
-
*slot = sym;
|
302
|
-
}
|
268
|
+
sym = ox_sym_intern(attrs->name, strlen(attrs->name), NULL);
|
303
269
|
} else {
|
304
|
-
sym =
|
305
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
306
|
-
if (0 != pi->options->rb_enc) {
|
307
|
-
rb_enc_associate(sym, pi->options->rb_enc);
|
308
|
-
}
|
309
|
-
#endif
|
270
|
+
sym = ox_str_intern(attrs->name, strlen(attrs->name), NULL);
|
310
271
|
}
|
311
272
|
s = rb_str_new2(attrs->value);
|
312
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
313
273
|
if (0 != pi->options->rb_enc) {
|
314
274
|
rb_enc_associate(s, pi->options->rb_enc);
|
315
275
|
}
|
316
|
-
#endif
|
317
276
|
rb_hash_aset(ah, sym, s);
|
318
277
|
}
|
319
278
|
rb_ivar_set(e, ox_attributes_id, ah);
|
@@ -349,14 +308,12 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
|
|
349
308
|
if (0 != content) {
|
350
309
|
c = rb_str_new2(content);
|
351
310
|
}
|
352
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
353
311
|
if (0 != pi->options->rb_enc) {
|
354
312
|
rb_enc_associate(s, pi->options->rb_enc);
|
355
313
|
if (0 != content) {
|
356
314
|
rb_enc_associate(c, pi->options->rb_enc);
|
357
315
|
}
|
358
316
|
}
|
359
|
-
#endif
|
360
317
|
inst = rb_obj_alloc(ox_instruct_clas);
|
361
318
|
rb_ivar_set(inst, ox_at_value_id, s);
|
362
319
|
if (0 != content) {
|
@@ -366,43 +323,18 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
|
|
366
323
|
|
367
324
|
for (; 0 != attrs->name; attrs++) {
|
368
325
|
volatile VALUE sym;
|
369
|
-
VALUE *slot;
|
370
326
|
|
371
327
|
if (Qnil != pi->options->attr_key_mod) {
|
372
328
|
sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name));
|
373
329
|
} else if (Yes == pi->options->sym_keys) {
|
374
|
-
|
375
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
376
|
-
if (0 != pi->options->rb_enc) {
|
377
|
-
VALUE rstr = rb_str_new2(attrs->name);
|
378
|
-
|
379
|
-
rb_enc_associate(rstr, pi->options->rb_enc);
|
380
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
381
|
-
} else {
|
382
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
383
|
-
}
|
384
|
-
#else
|
385
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
386
|
-
#endif
|
387
|
-
// Needed for Ruby 2.2 to get around the GC of symbols
|
388
|
-
// created with to_sym which is needed for encoded symbols.
|
389
|
-
rb_ary_push(ox_sym_bank, sym);
|
390
|
-
*slot = sym;
|
391
|
-
}
|
330
|
+
sym = ox_sym_intern(attrs->name, strlen(attrs->name), NULL);
|
392
331
|
} else {
|
393
|
-
sym =
|
394
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
395
|
-
if (0 != pi->options->rb_enc) {
|
396
|
-
rb_enc_associate(sym, pi->options->rb_enc);
|
397
|
-
}
|
398
|
-
#endif
|
332
|
+
sym = ox_str_intern(attrs->name, strlen(attrs->name), NULL);
|
399
333
|
}
|
400
334
|
s = rb_str_new2(attrs->value);
|
401
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
402
335
|
if (0 != pi->options->rb_enc) {
|
403
336
|
rb_enc_associate(s, pi->options->rb_enc);
|
404
337
|
}
|
405
|
-
#endif
|
406
338
|
rb_hash_aset(ah, sym, s);
|
407
339
|
}
|
408
340
|
rb_ivar_set(inst, ox_attributes_id, ah);
|
data/ext/ox/hash_load.c
CHANGED
@@ -78,11 +78,9 @@ add_str(PInfo pi, VALUE s) {
|
|
78
78
|
Helper parent = helper_stack_peek(&pi->helpers);
|
79
79
|
volatile VALUE a;
|
80
80
|
|
81
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
82
81
|
if (0 != pi->options->rb_enc) {
|
83
82
|
rb_enc_associate(s, pi->options->rb_enc);
|
84
83
|
}
|
85
|
-
#endif
|
86
84
|
switch (parent->type) {
|
87
85
|
case NoCode:
|
88
86
|
parent->obj = s;
|
@@ -131,11 +129,9 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
131
129
|
key = rb_str_new2(attrs->name);
|
132
130
|
}
|
133
131
|
val = rb_str_new2(attrs->value);
|
134
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
135
132
|
if (0 != pi->options->rb_enc) {
|
136
133
|
rb_enc_associate(val, pi->options->rb_enc);
|
137
134
|
}
|
138
|
-
#endif
|
139
135
|
rb_hash_aset(h, key, val);
|
140
136
|
}
|
141
137
|
a = rb_ary_new();
|
data/ext/ox/intern.c
ADDED
@@ -0,0 +1,158 @@
|
|
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
|
+
|
11
|
+
static struct _cache *str_cache = NULL;
|
12
|
+
static VALUE str_cache_obj;
|
13
|
+
|
14
|
+
static struct _cache *sym_cache = NULL;
|
15
|
+
static VALUE sym_cache_obj;
|
16
|
+
|
17
|
+
static struct _cache *attr_cache = NULL;
|
18
|
+
static VALUE attr_cache_obj;
|
19
|
+
|
20
|
+
static struct _cache *id_cache = NULL;
|
21
|
+
static VALUE id_cache_obj;
|
22
|
+
|
23
|
+
static VALUE form_str(const char *str, size_t len) {
|
24
|
+
return rb_str_freeze(rb_utf8_str_new(str, len));
|
25
|
+
}
|
26
|
+
|
27
|
+
static VALUE form_sym(const char *str, size_t len) {
|
28
|
+
return rb_to_symbol(rb_str_freeze(rb_utf8_str_new(str, len)));
|
29
|
+
}
|
30
|
+
|
31
|
+
static VALUE form_attr(const char *str, size_t len) {
|
32
|
+
char buf[256];
|
33
|
+
|
34
|
+
if (sizeof(buf) - 2 <= len) {
|
35
|
+
char *b = ALLOC_N(char, len + 2);
|
36
|
+
ID id;
|
37
|
+
|
38
|
+
if ('~' == *str) {
|
39
|
+
memcpy(b, str + 1, len - 1);
|
40
|
+
b[len - 1] = '\0';
|
41
|
+
len -= 2;
|
42
|
+
} else {
|
43
|
+
*b = '@';
|
44
|
+
memcpy(b + 1, str, len);
|
45
|
+
b[len + 1] = '\0';
|
46
|
+
}
|
47
|
+
id = rb_intern3(buf, len + 1, rb_utf8_encoding());
|
48
|
+
xfree(b);
|
49
|
+
return id;
|
50
|
+
}
|
51
|
+
if ('~' == *str) {
|
52
|
+
memcpy(buf, str + 1, len - 1);
|
53
|
+
buf[len - 1] = '\0';
|
54
|
+
len -= 2;
|
55
|
+
} else {
|
56
|
+
*buf = '@';
|
57
|
+
memcpy(buf + 1, str, len);
|
58
|
+
buf[len + 1] = '\0';
|
59
|
+
}
|
60
|
+
return (VALUE)rb_intern3(buf, len + 1, rb_utf8_encoding());
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE form_id(const char *str, size_t len) {
|
64
|
+
return (VALUE)rb_intern3(str, len, rb_utf8_encoding());
|
65
|
+
}
|
66
|
+
|
67
|
+
void ox_hash_init() {
|
68
|
+
VALUE cache_class = rb_define_class_under(Ox, "Cache", rb_cObject);
|
69
|
+
|
70
|
+
str_cache = cache_create(0, form_str, true, false);
|
71
|
+
str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
|
72
|
+
rb_gc_register_address(&str_cache_obj);
|
73
|
+
|
74
|
+
sym_cache = cache_create(0, form_sym, true, false);
|
75
|
+
sym_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, sym_cache);
|
76
|
+
rb_gc_register_address(&sym_cache_obj);
|
77
|
+
|
78
|
+
attr_cache = cache_create(0, form_attr, false, false);
|
79
|
+
attr_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, attr_cache);
|
80
|
+
rb_gc_register_address(&attr_cache_obj);
|
81
|
+
|
82
|
+
id_cache = cache_create(0, form_id, false, false);
|
83
|
+
id_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, id_cache);
|
84
|
+
rb_gc_register_address(&id_cache_obj);
|
85
|
+
}
|
86
|
+
|
87
|
+
VALUE
|
88
|
+
ox_str_intern(const char *key, size_t len, const char **keyp) {
|
89
|
+
// For huge cache sizes over half a million the rb_enc_interned_str
|
90
|
+
// performs slightly better but at more "normal" size of a several
|
91
|
+
// thousands the cache intern performs about 20% better.
|
92
|
+
#if HAVE_RB_ENC_INTERNED_STR && 0
|
93
|
+
return rb_enc_interned_str(key, len, rb_utf8_encoding());
|
94
|
+
#else
|
95
|
+
return cache_intern(str_cache, key, len, keyp);
|
96
|
+
#endif
|
97
|
+
}
|
98
|
+
|
99
|
+
VALUE
|
100
|
+
ox_sym_intern(const char *key, size_t len, const char **keyp) {
|
101
|
+
return cache_intern(sym_cache, key, len, keyp);
|
102
|
+
}
|
103
|
+
|
104
|
+
ID ox_attr_intern(const char *key, size_t len) {
|
105
|
+
return cache_intern(attr_cache, key, len, NULL);
|
106
|
+
}
|
107
|
+
|
108
|
+
ID ox_id_intern(const char *key, size_t len) {
|
109
|
+
return cache_intern(id_cache, key, len, NULL);
|
110
|
+
}
|
111
|
+
|
112
|
+
char *ox_strndup(const char *s, size_t len) {
|
113
|
+
char *d = ALLOC_N(char, len + 1);
|
114
|
+
|
115
|
+
memcpy(d, s, len);
|
116
|
+
d[len] = '\0';
|
117
|
+
|
118
|
+
return d;
|
119
|
+
}
|
120
|
+
|
121
|
+
void intern_cleanup() {
|
122
|
+
cache_free(str_cache);
|
123
|
+
cache_free(sym_cache);
|
124
|
+
cache_free(attr_cache);
|
125
|
+
cache_free(id_cache);
|
126
|
+
}
|
127
|
+
|
128
|
+
VALUE
|
129
|
+
ox_utf8_name(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
|
130
|
+
return ox_str_intern(str, len, strp);
|
131
|
+
}
|
132
|
+
|
133
|
+
VALUE
|
134
|
+
ox_utf8_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
|
135
|
+
return ox_sym_intern(str, len, strp);
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE
|
139
|
+
ox_enc_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
|
140
|
+
VALUE sym = rb_str_new2(str);
|
141
|
+
|
142
|
+
rb_enc_associate(sym, encoding);
|
143
|
+
if (NULL != strp) {
|
144
|
+
*strp = StringValuePtr(sym);
|
145
|
+
}
|
146
|
+
return rb_to_symbol(sym);
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE
|
150
|
+
ox_enc_name(const char *str, size_t len, rb_encoding *encoding, const char **strp) {
|
151
|
+
VALUE sym = rb_str_new2(str);
|
152
|
+
|
153
|
+
rb_enc_associate(sym, encoding);
|
154
|
+
if (NULL != strp) {
|
155
|
+
*strp = StringValuePtr(sym);
|
156
|
+
}
|
157
|
+
return sym;
|
158
|
+
}
|
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 */
|
data/ext/ox/obj_load.c
CHANGED
@@ -11,11 +11,10 @@
|
|
11
11
|
#include <time.h>
|
12
12
|
|
13
13
|
#include "ruby.h"
|
14
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
15
14
|
#include "ruby/encoding.h"
|
16
|
-
#endif
|
17
15
|
#include "base64.h"
|
18
16
|
#include "ox.h"
|
17
|
+
#include "intern.h"
|
19
18
|
|
20
19
|
static void instruct(PInfo pi, const char *target, Attr attrs, const char *content);
|
21
20
|
static void add_text(PInfo pi, char *text, int closed);
|
@@ -56,56 +55,6 @@ ParseCallbacks ox_obj_callbacks = &_ox_obj_callbacks;
|
|
56
55
|
|
57
56
|
extern ParseCallbacks ox_gen_callbacks;
|
58
57
|
|
59
|
-
|
60
|
-
inline static VALUE
|
61
|
-
str2sym(const char *str, void *encoding) {
|
62
|
-
VALUE sym;
|
63
|
-
|
64
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
65
|
-
if (0 != encoding) {
|
66
|
-
VALUE rstr = rb_str_new2(str);
|
67
|
-
|
68
|
-
rb_enc_associate(rstr, (rb_encoding*)encoding);
|
69
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
70
|
-
} else {
|
71
|
-
sym = ID2SYM(rb_intern(str));
|
72
|
-
}
|
73
|
-
#else
|
74
|
-
sym = ID2SYM(rb_intern(str));
|
75
|
-
#endif
|
76
|
-
return sym;
|
77
|
-
}
|
78
|
-
|
79
|
-
inline static ID
|
80
|
-
name2var(const char *name, void *encoding) {
|
81
|
-
VALUE *slot;
|
82
|
-
ID var_id = 0;
|
83
|
-
|
84
|
-
if ('0' <= *name && *name <= '9') {
|
85
|
-
var_id = INT2NUM(atoi(name));
|
86
|
-
} else if (Qundef == (var_id = ox_cache_get(ox_attr_cache, name, &slot, 0))) {
|
87
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
88
|
-
if (0 != encoding) {
|
89
|
-
volatile VALUE rstr = rb_str_new2(name);
|
90
|
-
volatile VALUE sym;
|
91
|
-
|
92
|
-
rb_enc_associate(rstr, (rb_encoding*)encoding);
|
93
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
94
|
-
// Needed for Ruby 2.2 to get around the GC of symbols
|
95
|
-
// created with to_sym which is needed for encoded symbols.
|
96
|
-
rb_ary_push(ox_sym_bank, sym);
|
97
|
-
var_id = SYM2ID(sym);
|
98
|
-
} else {
|
99
|
-
var_id = rb_intern(name);
|
100
|
-
}
|
101
|
-
#else
|
102
|
-
var_id = rb_intern(name);
|
103
|
-
#endif
|
104
|
-
*slot = var_id;
|
105
|
-
}
|
106
|
-
return var_id;
|
107
|
-
}
|
108
|
-
|
109
58
|
inline static VALUE
|
110
59
|
resolve_classname(VALUE mod, const char *class_name, Effort effort, VALUE base_class) {
|
111
60
|
VALUE clas;
|
@@ -228,6 +177,7 @@ classname2class(const char *name, PInfo pi, VALUE base_class) {
|
|
228
177
|
*s = '\0';
|
229
178
|
if (Qundef != (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) {
|
230
179
|
*slot = clas;
|
180
|
+
rb_gc_register_address(slot);
|
231
181
|
}
|
232
182
|
}
|
233
183
|
return clas;
|
@@ -237,8 +187,12 @@ static ID
|
|
237
187
|
get_var_sym_from_attrs(Attr a, void *encoding) {
|
238
188
|
for (; 0 != a->name; a++) {
|
239
189
|
if ('a' == *a->name && '\0' == *(a->name + 1)) {
|
240
|
-
|
241
|
-
|
190
|
+
const char *val = a->value;
|
191
|
+
|
192
|
+
if ('0' <= *val && *val <= '9') {
|
193
|
+
return INT2NUM(atoi(val));
|
194
|
+
}
|
195
|
+
return ox_id_intern(val, strlen(val));
|
242
196
|
}
|
243
197
|
}
|
244
198
|
return 0;
|
@@ -376,13 +330,11 @@ parse_regexp(const char *text) {
|
|
376
330
|
static void
|
377
331
|
instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
|
378
332
|
if (0 == strcmp("xml", target)) {
|
379
|
-
#if HAVE_RB_ENC_FIND
|
380
333
|
for (; 0 != attrs->name; attrs++) {
|
381
334
|
if (0 == strcmp("encoding", attrs->name)) {
|
382
335
|
pi->options->rb_enc = rb_enc_find(attrs->value);
|
383
336
|
}
|
384
337
|
}
|
385
|
-
#endif
|
386
338
|
}
|
387
339
|
}
|
388
340
|
|
@@ -408,11 +360,9 @@ add_text(PInfo pi, char *text, int closed) {
|
|
408
360
|
case NoCode:
|
409
361
|
case StringCode:
|
410
362
|
h->obj = rb_str_new2(text);
|
411
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
412
363
|
if (0 != pi->options->rb_enc) {
|
413
364
|
rb_enc_associate(h->obj, pi->options->rb_enc);
|
414
365
|
}
|
415
|
-
#endif
|
416
366
|
if (0 != pi->circ_array) {
|
417
367
|
circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id);
|
418
368
|
}
|
@@ -446,20 +396,8 @@ add_text(PInfo pi, char *text, int closed) {
|
|
446
396
|
h->obj = rb_float_new(strtod(text, 0));
|
447
397
|
break;
|
448
398
|
case SymbolCode:
|
449
|
-
|
450
|
-
VALUE sym;
|
451
|
-
VALUE *slot;
|
452
|
-
|
453
|
-
if (Qundef == (sym = ox_cache_get(ox_symbol_cache, text, &slot, 0))) {
|
454
|
-
sym = str2sym(text, (void*)pi->options->rb_enc);
|
455
|
-
// Needed for Ruby 2.2 to get around the GC of symbols created with
|
456
|
-
// to_sym which is needed for encoded symbols.
|
457
|
-
rb_ary_push(ox_sym_bank, sym);
|
458
|
-
*slot = sym;
|
459
|
-
}
|
460
|
-
h->obj = sym;
|
399
|
+
h->obj = ox_sym_intern(text, strlen(text), NULL);
|
461
400
|
break;
|
462
|
-
}
|
463
401
|
case DateCode:
|
464
402
|
{
|
465
403
|
VALUE args[1];
|
@@ -481,11 +419,9 @@ add_text(PInfo pi, char *text, int closed) {
|
|
481
419
|
|
482
420
|
from_base64(text, (uchar*)str);
|
483
421
|
v = rb_str_new(str, str_size);
|
484
|
-
#if HAVE_RB_ENC_ASSOCIATE
|
485
422
|
if (0 != pi->options->rb_enc) {
|
486
423
|
rb_enc_associate(v, pi->options->rb_enc);
|
487
424
|
}
|
488
|
-
#endif
|
489
425
|
if (0 != pi->circ_array) {
|
490
426
|
circ_array_set(pi->circ_array, v, (unsigned long)h->obj);
|
491
427
|
}
|
@@ -494,20 +430,11 @@ add_text(PInfo pi, char *text, int closed) {
|
|
494
430
|
}
|
495
431
|
case Symbol64Code:
|
496
432
|
{
|
497
|
-
VALUE sym;
|
498
|
-
VALUE *slot;
|
499
433
|
unsigned long str_size = b64_orig_size(text);
|
500
434
|
char *str = ALLOCA_N(char, str_size + 1);
|
501
435
|
|
502
436
|
from_base64(text, (uchar*)str);
|
503
|
-
|
504
|
-
sym = str2sym(str, (void*)pi->options->rb_enc);
|
505
|
-
// Needed for Ruby 2.2 to get around the GC of symbols created with
|
506
|
-
// to_sym which is needed for encoded symbols.
|
507
|
-
rb_ary_push(ox_sym_bank, sym);
|
508
|
-
*slot = sym;
|
509
|
-
}
|
510
|
-
h->obj = sym;
|
437
|
+
h->obj = ox_sym_intern(str, strlen(str), NULL);
|
511
438
|
break;
|
512
439
|
}
|
513
440
|
case RegexpCode:
|
@@ -843,7 +770,7 @@ parse_double_time(const char *text, VALUE clas) {
|
|
843
770
|
for (; text - dot <= 9; text++) {
|
844
771
|
v2 *= 10;
|
845
772
|
}
|
846
|
-
#if
|
773
|
+
#if HAVE_RB_TIME_NANO_NEW
|
847
774
|
return rb_time_nano_new(v, v2);
|
848
775
|
#else
|
849
776
|
return rb_time_new(v, v2 / 1000);
|
@@ -899,7 +826,7 @@ parse_xsd_time(const char *text, VALUE clas) {
|
|
899
826
|
tm.tm_hour = (int)cargs[3];
|
900
827
|
tm.tm_min = (int)cargs[4];
|
901
828
|
tm.tm_sec = (int)cargs[5];
|
902
|
-
#if
|
829
|
+
#if HAVE_RB_TIME_NANO_NEW
|
903
830
|
return rb_time_nano_new(mktime(&tm), cargs[6]);
|
904
831
|
#else
|
905
832
|
return rb_time_new(mktime(&tm), cargs[6] / 1000);
|