ox 2.12.0 → 2.13.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -0
- data/README.md +31 -0
- data/ext/ox/builder.c +13 -7
- data/ext/ox/dump.c +18 -24
- data/ext/ox/extconf.rb +16 -34
- data/ext/ox/gen_load.c +18 -96
- data/ext/ox/hash_load.c +62 -26
- data/ext/ox/obj_load.c +14 -46
- data/ext/ox/ox.c +34 -46
- data/ext/ox/ox.h +10 -16
- data/ext/ox/parse.c +59 -67
- data/ext/ox/sax.c +84 -134
- data/ext/ox/sax.h +2 -4
- data/ext/ox/sax_as.c +2 -6
- data/ext/ox/sax_buf.c +1 -1
- data/ext/ox/special.c +346 -0
- data/ext/ox/special.h +1 -0
- data/lib/ox/element.rb +1 -0
- data/lib/ox/version.rb +1 -1
- metadata +7 -7
data/ext/ox/hash_load.c
CHANGED
@@ -13,12 +13,14 @@
|
|
13
13
|
#include "ruby.h"
|
14
14
|
#include "ox.h"
|
15
15
|
|
16
|
+
#define MARK_INC 256
|
17
|
+
|
16
18
|
// The approach taken for the hash and has_no_attrs parsing is to push just
|
17
19
|
// the key on to the stack and then decide what to do on the way up/out.
|
18
20
|
|
19
21
|
static VALUE
|
20
22
|
create_top(PInfo pi) {
|
21
|
-
volatile VALUE top = rb_hash_new()
|
23
|
+
volatile VALUE top = rb_hash_new();
|
22
24
|
|
23
25
|
helper_stack_push(&pi->helpers, 0, top, HashCode);
|
24
26
|
pi->obj = top;
|
@@ -26,20 +28,61 @@ create_top(PInfo pi) {
|
|
26
28
|
return top;
|
27
29
|
}
|
28
30
|
|
31
|
+
static void
|
32
|
+
mark_value(PInfo pi, VALUE val) {
|
33
|
+
if (NULL == pi->marked) {
|
34
|
+
pi->marked = ALLOC_N(VALUE, MARK_INC);
|
35
|
+
pi->mark_size = MARK_INC;
|
36
|
+
} else if (pi->mark_size <= pi->mark_cnt) {
|
37
|
+
pi->mark_size += MARK_INC;
|
38
|
+
pi->marked = REALLOC_N(pi->marked, VALUE, pi->mark_size);
|
39
|
+
}
|
40
|
+
pi->marked[pi->mark_cnt] = val;
|
41
|
+
pi->mark_cnt++;
|
42
|
+
}
|
43
|
+
|
44
|
+
static bool
|
45
|
+
marked(PInfo pi, VALUE val) {
|
46
|
+
if (NULL != pi->marked) {
|
47
|
+
VALUE *vp = pi->marked + pi->mark_cnt - 1;
|
48
|
+
|
49
|
+
for (; pi->marked <= vp; vp--) {
|
50
|
+
if (val == *vp) {
|
51
|
+
return true;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
return false;
|
56
|
+
}
|
57
|
+
|
58
|
+
static void
|
59
|
+
unmark(PInfo pi, VALUE val) {
|
60
|
+
if (NULL != pi->marked) {
|
61
|
+
VALUE *vp = pi->marked + pi->mark_cnt - 1;
|
62
|
+
int i;
|
63
|
+
|
64
|
+
for (i = 0; pi->marked <= vp; vp--, i++) {
|
65
|
+
if (val == *vp) {
|
66
|
+
for (; 0 < i; i--, vp++) {
|
67
|
+
*vp = *(vp + 1);
|
68
|
+
}
|
69
|
+
pi->mark_cnt--;
|
70
|
+
break;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
29
76
|
static void
|
30
77
|
add_text(PInfo pi, char *text, int closed) {
|
31
78
|
Helper parent = helper_stack_peek(&pi->helpers);
|
32
79
|
volatile VALUE s = rb_str_new2(text);
|
33
80
|
volatile VALUE a;
|
34
81
|
|
35
|
-
#if
|
82
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
36
83
|
if (0 != pi->options->rb_enc) {
|
37
84
|
rb_enc_associate(s, pi->options->rb_enc);
|
38
85
|
}
|
39
|
-
#elif HAS_PRIVATE_ENCODING
|
40
|
-
if (Qnil != pi->options->rb_enc) {
|
41
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
42
|
-
}
|
43
86
|
#endif
|
44
87
|
switch (parent->type) {
|
45
88
|
case NoCode:
|
@@ -79,20 +122,16 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
79
122
|
key = rb_str_new2(attrs->name);
|
80
123
|
}
|
81
124
|
val = rb_str_new2(attrs->value);
|
82
|
-
#if
|
125
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
83
126
|
if (0 != pi->options->rb_enc) {
|
84
127
|
rb_enc_associate(val, pi->options->rb_enc);
|
85
128
|
}
|
86
|
-
#elif HAS_PRIVATE_ENCODING
|
87
|
-
if (Qnil != pi->options->rb_enc) {
|
88
|
-
rb_funcall(val, ox_force_encoding_id, 1, pi->options->rb_enc);
|
89
|
-
}
|
90
129
|
#endif
|
91
130
|
rb_hash_aset(h, key, val);
|
92
131
|
}
|
93
132
|
a = rb_ary_new();
|
94
133
|
rb_ary_push(a, h);
|
95
|
-
|
134
|
+
mark_value(pi, a);
|
96
135
|
helper_stack_push(&pi->helpers, rb_intern(ename), a, ArrayCode);
|
97
136
|
} else {
|
98
137
|
helper_stack_push(&pi->helpers, rb_intern(ename), Qnil, NoCode);
|
@@ -108,15 +147,14 @@ add_element_no_attrs(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
108
147
|
}
|
109
148
|
|
110
149
|
static int
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
}
|
150
|
+
umark_hash_cb(VALUE key, VALUE value, VALUE x) {
|
151
|
+
unmark((PInfo)x, value);
|
152
|
+
|
115
153
|
return ST_CONTINUE;
|
116
154
|
}
|
117
155
|
|
118
156
|
static void
|
119
|
-
end_element_core(PInfo pi, const char *ename, bool
|
157
|
+
end_element_core(PInfo pi, const char *ename, bool check_marked) {
|
120
158
|
Helper e = helper_stack_pop(&pi->helpers);
|
121
159
|
Helper parent = helper_stack_peek(&pi->helpers);
|
122
160
|
volatile VALUE pobj = parent->obj;
|
@@ -161,8 +199,8 @@ end_element_core(PInfo pi, const char *ename, bool check_taint) {
|
|
161
199
|
if (Qundef == found) {
|
162
200
|
rb_hash_aset(pobj, key, e->obj);
|
163
201
|
} else if (RUBY_T_ARRAY == rb_type(found)) {
|
164
|
-
if (
|
165
|
-
|
202
|
+
if (check_marked && marked(pi, found)) {
|
203
|
+
unmark(pi, found);
|
166
204
|
a = rb_ary_new();
|
167
205
|
rb_ary_push(a, found);
|
168
206
|
rb_ary_push(a, e->obj);
|
@@ -171,16 +209,16 @@ end_element_core(PInfo pi, const char *ename, bool check_taint) {
|
|
171
209
|
rb_ary_push(found, e->obj);
|
172
210
|
}
|
173
211
|
} else { // something there other than an array
|
174
|
-
if (
|
175
|
-
|
212
|
+
if (check_marked && marked(pi, e->obj)) {
|
213
|
+
unmark(pi, e->obj);
|
176
214
|
}
|
177
215
|
a = rb_ary_new();
|
178
216
|
rb_ary_push(a, found);
|
179
217
|
rb_ary_push(a, e->obj);
|
180
218
|
rb_hash_aset(pobj, key, a);
|
181
219
|
}
|
182
|
-
if (
|
183
|
-
rb_hash_foreach(e->obj,
|
220
|
+
if (check_marked && NULL != pi->marked && RUBY_T_HASH == rb_type(e->obj)) {
|
221
|
+
rb_hash_foreach(e->obj, umark_hash_cb, (VALUE)pi);
|
184
222
|
}
|
185
223
|
}
|
186
224
|
|
@@ -196,9 +234,7 @@ end_element_no_attrs(PInfo pi, const char *ename) {
|
|
196
234
|
|
197
235
|
static void
|
198
236
|
finish(PInfo pi) {
|
199
|
-
|
200
|
-
rb_hash_foreach(pi->obj, untaint_hash_cb, Qnil);
|
201
|
-
}
|
237
|
+
xfree(pi->marked);
|
202
238
|
}
|
203
239
|
|
204
240
|
struct _parseCallbacks _ox_hash_callbacks = {
|
data/ext/ox/obj_load.c
CHANGED
@@ -11,6 +11,9 @@
|
|
11
11
|
#include <time.h>
|
12
12
|
|
13
13
|
#include "ruby.h"
|
14
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
15
|
+
#include "ruby/encoding.h"
|
16
|
+
#endif
|
14
17
|
#include "base64.h"
|
15
18
|
#include "ox.h"
|
16
19
|
|
@@ -143,7 +146,6 @@ classname2obj(const char *name, PInfo pi, VALUE base_class) {
|
|
143
146
|
}
|
144
147
|
}
|
145
148
|
|
146
|
-
#if HAS_RSTRUCT
|
147
149
|
inline static VALUE
|
148
150
|
structname2obj(const char *name) {
|
149
151
|
VALUE ost;
|
@@ -159,16 +161,12 @@ structname2obj(const char *name) {
|
|
159
161
|
}
|
160
162
|
}
|
161
163
|
ost = rb_const_get(ox_struct_class, rb_intern(s));
|
162
|
-
|
163
|
-
#if HAS_ENCODING_SUPPORT
|
164
|
-
return rb_struct_alloc_noinit(ost);
|
165
|
-
#elif HAS_PRIVATE_ENCODING
|
164
|
+
#if HAVE_RB_STRUCT_ALLOC_NOINIT
|
166
165
|
return rb_struct_alloc_noinit(ost);
|
167
166
|
#else
|
168
167
|
return rb_struct_new(ost);
|
169
168
|
#endif
|
170
169
|
}
|
171
|
-
#endif
|
172
170
|
|
173
171
|
inline static VALUE
|
174
172
|
parse_ulong(const char *s, PInfo pi) {
|
@@ -239,6 +237,7 @@ static ID
|
|
239
237
|
get_var_sym_from_attrs(Attr a, void *encoding) {
|
240
238
|
for (; 0 != a->name; a++) {
|
241
239
|
if ('a' == *a->name && '\0' == *(a->name + 1)) {
|
240
|
+
name2var(a->value, encoding);
|
242
241
|
return name2var(a->value, encoding);
|
243
242
|
}
|
244
243
|
}
|
@@ -255,7 +254,6 @@ get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class) {
|
|
255
254
|
return Qundef;
|
256
255
|
}
|
257
256
|
|
258
|
-
#if HAS_RSTRUCT
|
259
257
|
static VALUE
|
260
258
|
get_struct_from_attrs(Attr a) {
|
261
259
|
for (; 0 != a->name; a++) {
|
@@ -265,7 +263,6 @@ get_struct_from_attrs(Attr a) {
|
|
265
263
|
}
|
266
264
|
return Qundef;
|
267
265
|
}
|
268
|
-
#endif
|
269
266
|
|
270
267
|
static VALUE
|
271
268
|
get_class_from_attrs(Attr a, PInfo pi, VALUE base_class) {
|
@@ -363,7 +360,7 @@ parse_regexp(const char *text) {
|
|
363
360
|
int options = 0;
|
364
361
|
|
365
362
|
te = text + strlen(text) - 1;
|
366
|
-
#
|
363
|
+
#ifdef ONIG_OPTION_IGNORECASE
|
367
364
|
for (; text < te && '/' != *te; te--) {
|
368
365
|
switch (*te) {
|
369
366
|
case 'i': options |= ONIG_OPTION_IGNORECASE; break;
|
@@ -379,18 +376,12 @@ parse_regexp(const char *text) {
|
|
379
376
|
static void
|
380
377
|
instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
|
381
378
|
if (0 == strcmp("xml", target)) {
|
382
|
-
#if
|
379
|
+
#if HAVE_RB_ENC_FIND
|
383
380
|
for (; 0 != attrs->name; attrs++) {
|
384
381
|
if (0 == strcmp("encoding", attrs->name)) {
|
385
382
|
pi->options->rb_enc = rb_enc_find(attrs->value);
|
386
383
|
}
|
387
384
|
}
|
388
|
-
#elif HAS_PRIVATE_ENCODING
|
389
|
-
for (; 0 != attrs->name; attrs++) {
|
390
|
-
if (0 == strcmp("encoding", attrs->name)) {
|
391
|
-
pi->options->rb_enc = rb_str_new2(attrs->value);
|
392
|
-
}
|
393
|
-
}
|
394
385
|
#endif
|
395
386
|
}
|
396
387
|
}
|
@@ -417,14 +408,10 @@ add_text(PInfo pi, char *text, int closed) {
|
|
417
408
|
case NoCode:
|
418
409
|
case StringCode:
|
419
410
|
h->obj = rb_str_new2(text);
|
420
|
-
#if
|
411
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
421
412
|
if (0 != pi->options->rb_enc) {
|
422
413
|
rb_enc_associate(h->obj, pi->options->rb_enc);
|
423
414
|
}
|
424
|
-
#elif HAS_PRIVATE_ENCODING
|
425
|
-
if (Qnil != pi->options->rb_enc) {
|
426
|
-
rb_funcall(h->obj, ox_force_encoding_id, 1, pi->options->rb_enc);
|
427
|
-
}
|
428
415
|
#endif
|
429
416
|
if (0 != pi->circ_array) {
|
430
417
|
circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id);
|
@@ -494,14 +481,10 @@ add_text(PInfo pi, char *text, int closed) {
|
|
494
481
|
|
495
482
|
from_base64(text, (uchar*)str);
|
496
483
|
v = rb_str_new(str, str_size);
|
497
|
-
#if
|
484
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
498
485
|
if (0 != pi->options->rb_enc) {
|
499
486
|
rb_enc_associate(v, pi->options->rb_enc);
|
500
487
|
}
|
501
|
-
#elif HAS_PRIVATE_ENCODING
|
502
|
-
if (0 != pi->options->rb_enc) {
|
503
|
-
rb_funcall(v, ox_force_encoding_id, 1, pi->options->rb_enc);
|
504
|
-
}
|
505
488
|
#endif
|
506
489
|
if (0 != pi->circ_array) {
|
507
490
|
circ_array_set(pi->circ_array, v, (unsigned long)h->obj);
|
@@ -542,11 +525,7 @@ add_text(PInfo pi, char *text, int closed) {
|
|
542
525
|
h->obj = rb_cstr_to_inum(text, 10, 1);
|
543
526
|
break;
|
544
527
|
case BigDecimalCode:
|
545
|
-
#if HAS_BIGDECIMAL
|
546
528
|
h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text));
|
547
|
-
#else
|
548
|
-
h->obj = Qnil;
|
549
|
-
#endif
|
550
529
|
break;
|
551
530
|
default:
|
552
531
|
h->obj = Qnil;
|
@@ -670,15 +649,10 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
670
649
|
}
|
671
650
|
break;
|
672
651
|
case StructCode:
|
673
|
-
#if HAS_RSTRUCT
|
674
652
|
h->obj = get_struct_from_attrs(attrs);
|
675
653
|
if (0 != pi->circ_array) {
|
676
654
|
circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
|
677
655
|
}
|
678
|
-
#else
|
679
|
-
set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
|
680
|
-
return;
|
681
|
-
#endif
|
682
656
|
break;
|
683
657
|
case ClassCode:
|
684
658
|
if (Qundef == (h->obj = get_class_from_attrs(attrs, pi, ox_bag_clas))) {
|
@@ -742,31 +716,29 @@ end_element(PInfo pi, const char *ename) {
|
|
742
716
|
case ExceptionCode:
|
743
717
|
case ObjectCode:
|
744
718
|
if (Qnil != ph->obj) {
|
745
|
-
if (0 == h->var) {
|
719
|
+
if (0 == h->var || NULL == rb_id2name(h->var )) {
|
746
720
|
set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
|
747
721
|
return;
|
748
722
|
}
|
723
|
+
if (RUBY_T_OBJECT != rb_type(ph->obj)) {
|
724
|
+
set_error(&pi->err, "Corrupt object encoding", pi->str, pi->s);
|
725
|
+
return;
|
726
|
+
}
|
749
727
|
rb_ivar_set(ph->obj, h->var, h->obj);
|
750
728
|
}
|
751
729
|
break;
|
752
730
|
case StructCode:
|
753
|
-
#if HAS_RSTRUCT
|
754
731
|
if (0 == h->var) {
|
755
732
|
set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
|
756
733
|
return;
|
757
734
|
}
|
758
735
|
rb_struct_aset(ph->obj, h->var, h->obj);
|
759
|
-
#else
|
760
|
-
set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
|
761
|
-
return;
|
762
|
-
#endif
|
763
736
|
break;
|
764
737
|
case HashCode:
|
765
738
|
// put back h
|
766
739
|
helper_stack_push(&pi->helpers, h->var, h->obj, KeyCode);
|
767
740
|
break;
|
768
741
|
case RangeCode:
|
769
|
-
#if HAS_RSTRUCT
|
770
742
|
if (ox_beg_id == h->var) {
|
771
743
|
RSTRUCT_SET(ph->obj, 0, h->obj);
|
772
744
|
} else if (ox_end_id == h->var) {
|
@@ -777,10 +749,6 @@ end_element(PInfo pi, const char *ename) {
|
|
777
749
|
set_error(&pi->err, "Invalid range attribute", pi->str, pi->s);
|
778
750
|
return;
|
779
751
|
}
|
780
|
-
#else
|
781
|
-
set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
|
782
|
-
return;
|
783
|
-
#endif
|
784
752
|
break;
|
785
753
|
case KeyCode:
|
786
754
|
{
|
data/ext/ox/ox.c
CHANGED
@@ -154,10 +154,8 @@ static VALUE element_key_mod_sym;
|
|
154
154
|
static ID encoding_id;
|
155
155
|
static ID has_key_id;
|
156
156
|
|
157
|
-
#if
|
157
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
158
158
|
rb_encoding *ox_utf8_encoding = 0;
|
159
|
-
#elif HAS_PRIVATE_ENCODING
|
160
|
-
VALUE ox_utf8_encoding = Qnil;
|
161
159
|
#else
|
162
160
|
void *ox_utf8_encoding = 0;
|
163
161
|
#endif
|
@@ -186,11 +184,7 @@ struct _options ox_default_options = {
|
|
186
184
|
NULL, // html_hints
|
187
185
|
Qnil, // attr_key_mod;
|
188
186
|
Qnil, // element_key_mod;
|
189
|
-
#if HAS_PRIVATE_ENCODING
|
190
|
-
Qnil // rb_enc
|
191
|
-
#else
|
192
187
|
0 // rb_enc
|
193
|
-
#endif
|
194
188
|
};
|
195
189
|
|
196
190
|
extern ParseCallbacks ox_obj_callbacks;
|
@@ -470,11 +464,8 @@ set_def_opts(VALUE self, VALUE opts) {
|
|
470
464
|
} else {
|
471
465
|
Check_Type(v, T_STRING);
|
472
466
|
strncpy(ox_default_options.encoding, StringValuePtr(v), sizeof(ox_default_options.encoding) - 1);
|
473
|
-
#if
|
467
|
+
#if HAVE_RB_ENC_FIND
|
474
468
|
ox_default_options.rb_enc = rb_enc_find(ox_default_options.encoding);
|
475
|
-
#elif HAS_PRIVATE_ENCODING
|
476
|
-
ox_default_options.rb_enc = rb_str_new2(ox_default_options.encoding);
|
477
|
-
rb_gc_register_address(&ox_default_options.rb_enc);
|
478
469
|
#endif
|
479
470
|
}
|
480
471
|
|
@@ -674,14 +665,14 @@ to_obj(VALUE self, VALUE ruby_xml) {
|
|
674
665
|
xml = ALLOCA_N(char, len);
|
675
666
|
}
|
676
667
|
memcpy(xml, x, len);
|
677
|
-
#
|
668
|
+
#ifdef RB_GC_GUARD
|
678
669
|
rb_gc_disable();
|
679
670
|
#endif
|
680
671
|
obj = ox_parse(xml, len - 1, ox_obj_callbacks, 0, &options, &err);
|
681
672
|
if (SMALL_XML < len) {
|
682
673
|
xfree(xml);
|
683
674
|
}
|
684
|
-
#
|
675
|
+
#ifdef RB_GC_GUARD
|
685
676
|
RB_GC_GUARD(obj);
|
686
677
|
rb_gc_enable();
|
687
678
|
#endif
|
@@ -848,7 +839,7 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
|
|
848
839
|
options.margin_len = strlen(options.margin);
|
849
840
|
}
|
850
841
|
}
|
851
|
-
#if
|
842
|
+
#if HAVE_RB_ENC_FIND
|
852
843
|
if ('\0' == *options.encoding) {
|
853
844
|
if (Qnil != encoding) {
|
854
845
|
options.rb_enc = rb_enc_from_index(rb_enc_get_index(encoding));
|
@@ -858,26 +849,15 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
|
|
858
849
|
} else if (0 == options.rb_enc) {
|
859
850
|
options.rb_enc = rb_enc_find(options.encoding);
|
860
851
|
}
|
861
|
-
#elif HAS_PRIVATE_ENCODING
|
862
|
-
if ('\0' == *options.encoding) {
|
863
|
-
if (Qnil != encoding) {
|
864
|
-
options.rb_enc = encoding;
|
865
|
-
} else {
|
866
|
-
options.rb_enc = Qnil;
|
867
|
-
}
|
868
|
-
} else if (0 == options.rb_enc) {
|
869
|
-
options.rb_enc = rb_str_new2(options.encoding);
|
870
|
-
rb_gc_register_address(&options.rb_enc);
|
871
|
-
}
|
872
852
|
#endif
|
873
853
|
xml = defuse_bom(xml, &options);
|
874
854
|
switch (options.mode) {
|
875
855
|
case ObjMode:
|
876
|
-
#
|
856
|
+
#ifdef RB_GC_GUARD
|
877
857
|
rb_gc_disable();
|
878
858
|
#endif
|
879
859
|
obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err);
|
880
|
-
#
|
860
|
+
#ifdef RB_GC_GUARD
|
881
861
|
RB_GC_GUARD(obj);
|
882
862
|
rb_gc_enable();
|
883
863
|
#endif
|
@@ -946,14 +926,8 @@ load_str(int argc, VALUE *argv, VALUE self) {
|
|
946
926
|
} else {
|
947
927
|
xml = ALLOCA_N(char, len);
|
948
928
|
}
|
949
|
-
#if
|
950
|
-
#ifdef MACRUBY_RUBY
|
951
|
-
encoding = rb_funcall(*argv, encoding_id, 0);
|
952
|
-
#else
|
929
|
+
#if HAVE_RB_OBJ_ENCODING
|
953
930
|
encoding = rb_obj_encoding(*argv);
|
954
|
-
#endif
|
955
|
-
#elif HAS_PRIVATE_ENCODING
|
956
|
-
encoding = rb_funcall(*argv, encoding_id, 0);
|
957
931
|
#else
|
958
932
|
encoding = Qnil;
|
959
933
|
#endif
|
@@ -1319,21 +1293,38 @@ dump(int argc, VALUE *argv, VALUE self) {
|
|
1319
1293
|
rb_raise(rb_eNoMemError, "Not enough memory.\n");
|
1320
1294
|
}
|
1321
1295
|
rstr = rb_str_new2(xml);
|
1322
|
-
#if
|
1296
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
1323
1297
|
if ('\0' != *copts.encoding) {
|
1324
1298
|
rb_enc_associate(rstr, rb_enc_find(copts.encoding));
|
1325
1299
|
}
|
1326
|
-
#elif HAS_PRIVATE_ENCODING
|
1327
|
-
if ('\0' != *copts.encoding) {
|
1328
|
-
rb_funcall(rstr, ox_force_encoding_id, 1, rb_str_new2(copts.encoding));
|
1329
|
-
}
|
1330
1300
|
#endif
|
1331
1301
|
xfree(xml);
|
1332
1302
|
|
1333
1303
|
return rstr;
|
1334
1304
|
}
|
1335
1305
|
|
1336
|
-
/* call-seq:
|
1306
|
+
/* call-seq: to_xml(obj, options) => xml-string
|
1307
|
+
*
|
1308
|
+
* Dumps an Object (obj) to a string.
|
1309
|
+
* - +obj+ [Object] Object to serialize as an XML document String
|
1310
|
+
* - +options+ [Hash] formating options
|
1311
|
+
* - *:indent* [Fixnum] format expected
|
1312
|
+
* - *:no_empty* [true|false] if true don't output empty elements
|
1313
|
+
* - *:xsd_date* [true|false] use XSD date format if true, default: false
|
1314
|
+
* - *:circular* [true|false] allow circular references, default: false
|
1315
|
+
* - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: :strict
|
1316
|
+
* - _:strict_ - raise an NotImplementedError if an undumpable object is encountered
|
1317
|
+
* - _:tolerant_ - replaces undumplable objects with nil
|
1318
|
+
*
|
1319
|
+
* Note that an indent of less than zero will result in a tight one line output
|
1320
|
+
* unless the text in the XML fields contain new line characters.
|
1321
|
+
*/
|
1322
|
+
static VALUE
|
1323
|
+
to_xml(int argc, VALUE *argv, VALUE self) {
|
1324
|
+
return dump(argc, argv, self);
|
1325
|
+
}
|
1326
|
+
|
1327
|
+
/* call-seq: to_file(file_path, obj, options) => Object
|
1337
1328
|
*
|
1338
1329
|
* Dumps an Object to the specified file.
|
1339
1330
|
* - +file_path+ [String] file path to write the XML document to
|
@@ -1392,7 +1383,7 @@ void Init_ox() {
|
|
1392
1383
|
rb_define_module_function(Ox, "sax_parse", sax_parse, -1);
|
1393
1384
|
rb_define_module_function(Ox, "sax_html", sax_html, -1);
|
1394
1385
|
|
1395
|
-
rb_define_module_function(Ox, "to_xml",
|
1386
|
+
rb_define_module_function(Ox, "to_xml", to_xml, -1);
|
1396
1387
|
rb_define_module_function(Ox, "dump", dump, -1);
|
1397
1388
|
|
1398
1389
|
rb_define_module_function(Ox, "load_file", load_file, -1);
|
@@ -1555,11 +1546,8 @@ void Init_ox() {
|
|
1555
1546
|
rb_define _module_function(Ox, "cache8_test", cache8_test, 0);
|
1556
1547
|
#endif
|
1557
1548
|
|
1558
|
-
#if
|
1549
|
+
#if HAVE_RB_ENC_FIND
|
1559
1550
|
ox_utf8_encoding = rb_enc_find("UTF-8");
|
1560
|
-
#elif HAS_PRIVATE_ENCODING
|
1561
|
-
ox_utf8_encoding = rb_str_new2("UTF-8");
|
1562
|
-
rb_gc_register_address(&ox_utf8_encoding);
|
1563
1551
|
#endif
|
1564
1552
|
}
|
1565
1553
|
|
@@ -1580,7 +1568,7 @@ _ox_raise_error(const char *msg, const char *xml, const char *current, const cha
|
|
1580
1568
|
xline++;
|
1581
1569
|
}
|
1582
1570
|
}
|
1583
|
-
#
|
1571
|
+
#ifdef RB_GC_GUARD
|
1584
1572
|
rb_gc_enable();
|
1585
1573
|
#endif
|
1586
1574
|
rb_raise(ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line);
|