ox 2.14.14 → 2.14.17
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|