ox 2.14.14 → 2.14.17
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 +18 -0
- data/README.md +1 -1
- data/ext/ox/attr.h +33 -39
- data/ext/ox/base64.c +48 -42
- data/ext/ox/base64.h +4 -4
- data/ext/ox/buf.h +80 -86
- data/ext/ox/builder.c +377 -456
- data/ext/ox/cache.c +2 -2
- data/ext/ox/cache8.c +37 -40
- data/ext/ox/cache8.h +7 -7
- data/ext/ox/dump.c +811 -889
- data/ext/ox/err.c +16 -13
- data/ext/ox/err.h +11 -12
- data/ext/ox/extconf.rb +5 -10
- data/ext/ox/gen_load.c +135 -139
- data/ext/ox/hash_load.c +130 -148
- data/ext/ox/helper.h +32 -39
- data/ext/ox/intern.c +1 -2
- data/ext/ox/obj_load.c +586 -662
- data/ext/ox/ox.c +93 -132
- data/ext/ox/ox.h +5 -10
- data/ext/ox/parse.c +836 -874
- data/ext/ox/sax.c +56 -31
- data/ext/ox/sax.h +2 -2
- data/ext/ox/sax_as.c +78 -102
- data/ext/ox/sax_buf.c +85 -94
- data/ext/ox/sax_buf.h +101 -120
- data/ext/ox/sax_hint.c +175 -184
- data/ext/ox/sax_hint.h +19 -19
- data/ext/ox/sax_stack.h +59 -45
- data/ext/ox/slotcache.c +3 -3
- data/ext/ox/slotcache.h +4 -4
- data/ext/ox/special.c +320 -327
- data/ext/ox/special.h +2 -2
- data/ext/ox/type.h +19 -19
- data/lib/ox/bag.rb +13 -9
- data/lib/ox/cdata.rb +0 -2
- data/lib/ox/comment.rb +0 -2
- data/lib/ox/doctype.rb +0 -2
- data/lib/ox/document.rb +3 -5
- data/lib/ox/element.rb +41 -26
- data/lib/ox/error.rb +0 -3
- data/lib/ox/hasattrs.rb +7 -8
- data/lib/ox/instruct.rb +4 -6
- data/lib/ox/node.rb +3 -4
- data/lib/ox/raw.rb +0 -2
- data/lib/ox/sax.rb +20 -36
- data/lib/ox/version.rb +1 -2
- data/lib/ox/xmlrpc_adapter.rb +5 -6
- data/lib/ox.rb +15 -16
- metadata +27 -6
data/ext/ox/ox.c
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
typedef struct _yesNoOpt {
|
24
24
|
VALUE sym;
|
25
25
|
char *attr;
|
26
|
-
} *
|
26
|
+
} *YesNoOpt;
|
27
27
|
|
28
28
|
void Init_ox();
|
29
29
|
|
@@ -73,11 +73,6 @@ ID ox_start_element_id;
|
|
73
73
|
ID ox_string_id;
|
74
74
|
ID ox_text_id;
|
75
75
|
ID ox_to_c_id;
|
76
|
-
ID ox_to_s_id;
|
77
|
-
ID ox_to_sym_id;
|
78
|
-
ID ox_tv_nsec_id;
|
79
|
-
ID ox_tv_sec_id;
|
80
|
-
ID ox_tv_usec_id;
|
81
76
|
ID ox_value_id;
|
82
77
|
|
83
78
|
VALUE ox_encoding_sym;
|
@@ -107,7 +102,7 @@ VALUE ox_struct_class;
|
|
107
102
|
VALUE ox_syntax_error_class;
|
108
103
|
VALUE ox_time_class;
|
109
104
|
|
110
|
-
SlotCache ox_class_cache
|
105
|
+
SlotCache ox_class_cache = 0;
|
111
106
|
|
112
107
|
static VALUE abort_sym;
|
113
108
|
static VALUE active_sym;
|
@@ -687,17 +682,13 @@ static VALUE to_obj(VALUE self, VALUE ruby_xml) {
|
|
687
682
|
xml = ALLOCA_N(char, len);
|
688
683
|
}
|
689
684
|
memcpy(xml, x, len);
|
690
|
-
#ifdef RB_GC_GUARD
|
691
685
|
rb_gc_disable();
|
692
|
-
#endif
|
693
686
|
obj = ox_parse(xml, len - 1, ox_obj_callbacks, 0, &options, &err);
|
694
687
|
if (SMALL_XML < len) {
|
695
688
|
xfree(xml);
|
696
689
|
}
|
697
|
-
#ifdef RB_GC_GUARD
|
698
690
|
RB_GC_GUARD(obj);
|
699
691
|
rb_gc_enable();
|
700
|
-
#endif
|
701
692
|
if (err_has(&err)) {
|
702
693
|
ox_err_raise(&err);
|
703
694
|
}
|
@@ -740,130 +731,123 @@ static VALUE to_gen(VALUE self, VALUE ruby_xml) {
|
|
740
731
|
return obj;
|
741
732
|
}
|
742
733
|
|
743
|
-
static
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
if (
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
options.mode = HashMode;
|
762
|
-
} else if (hash_no_attrs_sym == v) {
|
763
|
-
options.mode = HashNoAttrMode;
|
764
|
-
} else {
|
765
|
-
rb_raise(ox_parse_error_class, ":mode must be :generic, :object, :limited, :hash, :hash_no_attrs.\n");
|
766
|
-
}
|
767
|
-
}
|
768
|
-
if (Qnil != (v = rb_hash_lookup(h, effort_sym))) {
|
769
|
-
if (auto_define_sym == v) {
|
770
|
-
options.effort = AutoEffort;
|
771
|
-
} else if (tolerant_sym == v) {
|
772
|
-
options.effort = TolerantEffort;
|
773
|
-
} else if (strict_sym == v) {
|
774
|
-
options.effort = StrictEffort;
|
775
|
-
} else {
|
776
|
-
rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
|
777
|
-
}
|
778
|
-
}
|
779
|
-
if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
|
780
|
-
if (skip_none_sym == v) {
|
781
|
-
options.skip = NoSkip;
|
782
|
-
} else if (skip_off_sym == v) {
|
783
|
-
options.skip = OffSkip;
|
784
|
-
} else if (skip_return_sym == v) {
|
785
|
-
options.skip = CrSkip;
|
786
|
-
} else if (skip_white_sym == v) {
|
787
|
-
options.skip = SpcSkip;
|
788
|
-
} else {
|
789
|
-
rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, or :skip_off.\n");
|
790
|
-
}
|
791
|
-
}
|
792
|
-
|
793
|
-
if (Qnil != (v = rb_hash_lookup(h, trace_sym))) {
|
794
|
-
Check_Type(v, T_FIXNUM);
|
795
|
-
options.trace = FIX2INT(v);
|
796
|
-
}
|
797
|
-
if (Qnil != (v = rb_hash_lookup(h, symbolize_keys_sym))) {
|
798
|
-
options.sym_keys = (Qfalse == v) ? No : Yes;
|
734
|
+
static int load_options_cb(VALUE k, VALUE v, VALUE opts) {
|
735
|
+
Options copts = (Options)opts;
|
736
|
+
|
737
|
+
if (mode_sym == k) {
|
738
|
+
if (object_sym == v) {
|
739
|
+
copts->mode = ObjMode;
|
740
|
+
} else if (optimized_sym == v) {
|
741
|
+
copts->mode = ObjMode;
|
742
|
+
} else if (generic_sym == v) {
|
743
|
+
copts->mode = GenMode;
|
744
|
+
} else if (limited_sym == v) {
|
745
|
+
copts->mode = LimMode;
|
746
|
+
} else if (hash_sym == v) {
|
747
|
+
copts->mode = HashMode;
|
748
|
+
} else if (hash_no_attrs_sym == v) {
|
749
|
+
copts->mode = HashNoAttrMode;
|
750
|
+
} else {
|
751
|
+
rb_raise(ox_parse_error_class, ":mode must be :generic, :object, :limited, :hash, :hash_no_attrs.\n");
|
799
752
|
}
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
if (
|
804
|
-
|
753
|
+
} else if (effort_sym == k) {
|
754
|
+
if (auto_define_sym == v) {
|
755
|
+
copts->effort = AutoEffort;
|
756
|
+
} else if (tolerant_sym == v) {
|
757
|
+
copts->effort = TolerantEffort;
|
758
|
+
} else if (strict_sym == v) {
|
759
|
+
copts->effort = StrictEffort;
|
760
|
+
} else {
|
761
|
+
rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
|
805
762
|
}
|
806
|
-
|
807
|
-
|
763
|
+
} else if (skip_sym == k) {
|
764
|
+
if (skip_none_sym == v) {
|
765
|
+
copts->skip = NoSkip;
|
766
|
+
} else if (skip_off_sym == v) {
|
767
|
+
copts->skip = OffSkip;
|
768
|
+
} else if (skip_return_sym == v) {
|
769
|
+
copts->skip = CrSkip;
|
770
|
+
} else if (skip_white_sym == v) {
|
771
|
+
copts->skip = SpcSkip;
|
772
|
+
} else {
|
773
|
+
rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, or :skip_off.\n");
|
808
774
|
}
|
809
|
-
|
810
|
-
v
|
775
|
+
} else if (trace_sym == k) {
|
776
|
+
Check_Type(v, T_FIXNUM);
|
777
|
+
copts->trace = FIX2INT(v);
|
778
|
+
} else if (symbolize_keys_sym == k) {
|
779
|
+
copts->sym_keys = (Qfalse == v) ? No : Yes;
|
780
|
+
} else if (element_key_mod_sym == k) {
|
781
|
+
copts->element_key_mod = v;
|
782
|
+
} else if (attr_key_mod_sym == k) {
|
783
|
+
copts->attr_key_mod = v;
|
784
|
+
} else if (convert_special_sym == k) {
|
785
|
+
copts->convert_special = (Qfalse != v);
|
786
|
+
} else if (no_empty_sym == k) {
|
787
|
+
copts->no_empty = (Qfalse != v);
|
788
|
+
} else if (invalid_replace_sym == k) {
|
811
789
|
if (Qnil == v) {
|
812
|
-
|
813
|
-
options.allow_invalid = Yes;
|
814
|
-
}
|
790
|
+
copts->allow_invalid = Yes;
|
815
791
|
} else {
|
816
792
|
long slen;
|
817
793
|
|
818
794
|
Check_Type(v, T_STRING);
|
819
795
|
slen = RSTRING_LEN(v);
|
820
|
-
if (sizeof(
|
796
|
+
if (sizeof(copts->inv_repl) - 2 < (size_t)slen) {
|
821
797
|
rb_raise(ox_parse_error_class,
|
822
798
|
":invalid_replace can be no longer than %d characters.",
|
823
|
-
(int)sizeof(
|
799
|
+
(int)sizeof(copts->inv_repl) - 2);
|
824
800
|
}
|
825
|
-
strncpy(
|
826
|
-
|
827
|
-
*
|
828
|
-
|
801
|
+
strncpy(copts->inv_repl + 1, StringValuePtr(v), sizeof(copts->inv_repl) - 1);
|
802
|
+
copts->inv_repl[sizeof(copts->inv_repl) - 1] = '\0';
|
803
|
+
*copts->inv_repl = (char)slen;
|
804
|
+
copts->allow_invalid = No;
|
829
805
|
}
|
830
|
-
|
806
|
+
} else if (strip_namespace_sym == k) {
|
831
807
|
if (Qfalse == v) {
|
832
|
-
*
|
808
|
+
*copts->strip_ns = '\0';
|
833
809
|
} else if (Qtrue == v) {
|
834
|
-
*
|
835
|
-
|
810
|
+
*copts->strip_ns = '*';
|
811
|
+
copts->strip_ns[1] = '\0';
|
836
812
|
} else if (Qnil != v) {
|
837
813
|
long slen;
|
838
814
|
|
839
815
|
Check_Type(v, T_STRING);
|
840
816
|
slen = RSTRING_LEN(v);
|
841
|
-
if (sizeof(
|
817
|
+
if (sizeof(copts->strip_ns) - 1 < (size_t)slen) {
|
842
818
|
rb_raise(ox_parse_error_class,
|
843
819
|
":strip_namespace can be no longer than %d characters.",
|
844
|
-
(int)sizeof(
|
820
|
+
(int)sizeof(copts->strip_ns) - 1);
|
845
821
|
}
|
846
|
-
strncpy(
|
847
|
-
|
822
|
+
strncpy(copts->strip_ns, StringValuePtr(v), sizeof(copts->strip_ns) - 1);
|
823
|
+
copts->strip_ns[sizeof(copts->strip_ns) - 1] = '\0';
|
848
824
|
}
|
849
|
-
|
850
|
-
|
851
|
-
long slen;
|
825
|
+
} else if (margin_sym == k) {
|
826
|
+
long slen;
|
852
827
|
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
}
|
860
|
-
strncpy(options.margin, StringValuePtr(v), sizeof(options.margin) - 1);
|
861
|
-
options.margin[sizeof(options.margin) - 1] = '\0';
|
862
|
-
options.margin_len = strlen(options.margin);
|
863
|
-
}
|
864
|
-
if (Qnil != (v = rb_hash_lookup(h, with_cdata_sym))) {
|
865
|
-
options.with_cdata = (Qtrue == v);
|
828
|
+
Check_Type(v, T_STRING);
|
829
|
+
slen = RSTRING_LEN(v);
|
830
|
+
if (sizeof(copts->margin) - 1 < (size_t)slen) {
|
831
|
+
rb_raise(ox_parse_error_class,
|
832
|
+
":margin can be no longer than %d characters.",
|
833
|
+
(int)sizeof(copts->margin) - 1);
|
866
834
|
}
|
835
|
+
strncpy(copts->margin, StringValuePtr(v), sizeof(copts->margin) - 1);
|
836
|
+
copts->margin[sizeof(copts->margin) - 1] = '\0';
|
837
|
+
copts->margin_len = strlen(copts->margin);
|
838
|
+
} else if (with_cdata_sym == k) {
|
839
|
+
copts->with_cdata = (Qtrue == v);
|
840
|
+
}
|
841
|
+
|
842
|
+
return ST_CONTINUE;
|
843
|
+
}
|
844
|
+
|
845
|
+
static VALUE load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
|
846
|
+
VALUE obj;
|
847
|
+
struct _options options = ox_default_options;
|
848
|
+
|
849
|
+
if (1 == argc && rb_cHash == rb_obj_class(*argv)) {
|
850
|
+
rb_hash_foreach(*argv, load_options_cb, (VALUE)&options);
|
867
851
|
}
|
868
852
|
if ('\0' == *options.encoding) {
|
869
853
|
if (Qnil != encoding) {
|
@@ -877,14 +861,10 @@ static VALUE load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALU
|
|
877
861
|
xml = defuse_bom(xml, &options);
|
878
862
|
switch (options.mode) {
|
879
863
|
case ObjMode:
|
880
|
-
#ifdef RB_GC_GUARD
|
881
864
|
rb_gc_disable();
|
882
|
-
#endif
|
883
865
|
obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err);
|
884
|
-
#ifdef RB_GC_GUARD
|
885
866
|
RB_GC_GUARD(obj);
|
886
867
|
rb_gc_enable();
|
887
|
-
#endif
|
888
868
|
break;
|
889
869
|
case GenMode: obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err); break;
|
890
870
|
case LimMode: obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err); break;
|
@@ -952,11 +932,7 @@ static VALUE load_str(int argc, VALUE *argv, VALUE self) {
|
|
952
932
|
} else {
|
953
933
|
xml = ALLOCA_N(char, len);
|
954
934
|
}
|
955
|
-
#if HAVE_RB_OBJ_ENCODING
|
956
935
|
encoding = rb_obj_encoding(*argv);
|
957
|
-
#else
|
958
|
-
encoding = Qnil;
|
959
|
-
#endif
|
960
936
|
memcpy(xml, StringValuePtr(*argv), len);
|
961
937
|
xml[len - 1] = '\0';
|
962
938
|
obj = load(xml, len - 1, argc - 1, argv + 1, self, encoding, &err);
|
@@ -1201,21 +1177,13 @@ static void parse_dump_options(VALUE ropts, Options copts) {
|
|
1201
1177
|
VALUE v;
|
1202
1178
|
|
1203
1179
|
if (Qnil != (v = rb_hash_lookup(ropts, ox_indent_sym))) {
|
1204
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
1205
1180
|
if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) {
|
1206
|
-
#else
|
1207
|
-
if (rb_cFixnum != rb_obj_class(v)) {
|
1208
|
-
#endif
|
1209
1181
|
rb_raise(ox_parse_error_class, ":indent must be a Fixnum.\n");
|
1210
1182
|
}
|
1211
1183
|
copts->indent = NUM2INT(v);
|
1212
1184
|
}
|
1213
1185
|
if (Qnil != (v = rb_hash_lookup(ropts, trace_sym))) {
|
1214
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
1215
1186
|
if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) {
|
1216
|
-
#else
|
1217
|
-
if (rb_cFixnum != rb_obj_class(v)) {
|
1218
|
-
#endif
|
1219
1187
|
rb_raise(ox_parse_error_class, ":trace must be a Fixnum.\n");
|
1220
1188
|
}
|
1221
1189
|
copts->trace = NUM2INT(v);
|
@@ -1469,11 +1437,6 @@ void Init_ox() {
|
|
1469
1437
|
ox_string_id = rb_intern("string");
|
1470
1438
|
ox_text_id = rb_intern("text");
|
1471
1439
|
ox_to_c_id = rb_intern("to_c");
|
1472
|
-
ox_to_s_id = rb_intern("to_s");
|
1473
|
-
ox_to_sym_id = rb_intern("to_sym");
|
1474
|
-
ox_tv_nsec_id = rb_intern("tv_nsec");
|
1475
|
-
ox_tv_sec_id = rb_intern("tv_sec");
|
1476
|
-
ox_tv_usec_id = rb_intern("tv_usec");
|
1477
1440
|
ox_value_id = rb_intern("value");
|
1478
1441
|
|
1479
1442
|
encoding_id = rb_intern("encoding");
|
@@ -1675,8 +1638,6 @@ _ox_raise_error(const char *msg, const char *xml, const char *current, const cha
|
|
1675
1638
|
xline++;
|
1676
1639
|
}
|
1677
1640
|
}
|
1678
|
-
#ifdef RB_GC_GUARD
|
1679
1641
|
rb_gc_enable();
|
1680
|
-
#endif
|
1681
1642
|
rb_raise(ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line);
|
1682
1643
|
}
|
data/ext/ox/ox.h
CHANGED
@@ -94,14 +94,14 @@ typedef struct _parseCallbacks {
|
|
94
94
|
void (*add_element)(PInfo pi, const char *ename, Attr attrs, int hasChildren);
|
95
95
|
void (*end_element)(PInfo pi, const char *ename);
|
96
96
|
void (*finish)(PInfo pi);
|
97
|
-
} *
|
97
|
+
} *ParseCallbacks;
|
98
98
|
|
99
99
|
typedef struct _circArray {
|
100
100
|
VALUE obj_array[1024];
|
101
101
|
VALUE *objs;
|
102
102
|
unsigned long size; /* allocated size or initial array size */
|
103
103
|
unsigned long cnt;
|
104
|
-
} *
|
104
|
+
} *CircArray;
|
105
105
|
|
106
106
|
typedef struct _options {
|
107
107
|
char encoding[64]; // encoding, stored in the option to avoid GC invalidation in default values
|
@@ -128,8 +128,8 @@ typedef struct _options {
|
|
128
128
|
struct _hints *html_hints; // html hints
|
129
129
|
VALUE attr_key_mod;
|
130
130
|
VALUE element_key_mod;
|
131
|
-
rb_encoding
|
132
|
-
} *
|
131
|
+
rb_encoding *rb_enc;
|
132
|
+
} *Options;
|
133
133
|
|
134
134
|
// parse information structure
|
135
135
|
struct _pInfo {
|
@@ -146,7 +146,7 @@ struct _pInfo {
|
|
146
146
|
VALUE *marked;
|
147
147
|
int mark_size; // allocated size
|
148
148
|
int mark_cnt;
|
149
|
-
char last;
|
149
|
+
char last; // last character read, rarely set
|
150
150
|
};
|
151
151
|
|
152
152
|
extern VALUE ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options, Err err);
|
@@ -205,11 +205,6 @@ extern ID ox_start_element_id;
|
|
205
205
|
extern ID ox_string_id;
|
206
206
|
extern ID ox_text_id;
|
207
207
|
extern ID ox_to_c_id;
|
208
|
-
extern ID ox_to_s_id;
|
209
|
-
extern ID ox_to_sym_id;
|
210
|
-
extern ID ox_tv_sec_id;
|
211
|
-
extern ID ox_tv_nsec_id;
|
212
|
-
extern ID ox_tv_usec_id;
|
213
208
|
extern ID ox_value_id;
|
214
209
|
|
215
210
|
extern rb_encoding *ox_utf8_encoding;
|