ox 2.14.12 → 2.14.17

Sign up to get free protection for your applications and to get access to all the features.
data/ext/ox/ox.c CHANGED
@@ -23,7 +23,7 @@
23
23
  typedef struct _yesNoOpt {
24
24
  VALUE sym;
25
25
  char *attr;
26
- } * YesNoOpt;
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 = 0;
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 VALUE load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
744
- VALUE obj;
745
- struct _options options = ox_default_options;
746
-
747
- if (1 == argc && rb_cHash == rb_obj_class(*argv)) {
748
- VALUE h = *argv;
749
- VALUE v;
750
-
751
- if (Qnil != (v = rb_hash_lookup(h, mode_sym))) {
752
- if (object_sym == v) {
753
- options.mode = ObjMode;
754
- } else if (optimized_sym == v) {
755
- options.mode = ObjMode;
756
- } else if (generic_sym == v) {
757
- options.mode = GenMode;
758
- } else if (limited_sym == v) {
759
- options.mode = LimMode;
760
- } else if (hash_sym == v) {
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
- options.element_key_mod = rb_hash_lookup2(h, element_key_mod_sym, options.element_key_mod);
801
- options.attr_key_mod = rb_hash_lookup2(h, attr_key_mod_sym, options.attr_key_mod);
802
-
803
- if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
804
- options.convert_special = (Qfalse != v);
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
- if (Qnil != (v = rb_hash_lookup(h, no_empty_sym))) {
807
- options.no_empty = (Qfalse != v);
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 = rb_hash_lookup(h, invalid_replace_sym);
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
- if (Qtrue == rb_funcall(h, has_key_id, 1, invalid_replace_sym)) {
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(options.inv_repl) - 2 < (size_t)slen) {
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(options.inv_repl) - 2);
799
+ (int)sizeof(copts->inv_repl) - 2);
824
800
  }
825
- strncpy(options.inv_repl + 1, StringValuePtr(v), sizeof(options.inv_repl) - 1);
826
- options.inv_repl[sizeof(options.inv_repl) - 1] = '\0';
827
- *options.inv_repl = (char)slen;
828
- options.allow_invalid = No;
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
- v = rb_hash_lookup(h, strip_namespace_sym);
806
+ } else if (strip_namespace_sym == k) {
831
807
  if (Qfalse == v) {
832
- *options.strip_ns = '\0';
808
+ *copts->strip_ns = '\0';
833
809
  } else if (Qtrue == v) {
834
- *options.strip_ns = '*';
835
- options.strip_ns[1] = '\0';
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(options.strip_ns) - 1 < (size_t)slen) {
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(options.strip_ns) - 1);
820
+ (int)sizeof(copts->strip_ns) - 1);
845
821
  }
846
- strncpy(options.strip_ns, StringValuePtr(v), sizeof(options.strip_ns) - 1);
847
- options.strip_ns[sizeof(options.strip_ns) - 1] = '\0';
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
- v = rb_hash_lookup(h, margin_sym);
850
- if (Qnil != v) {
851
- long slen;
825
+ } else if (margin_sym == k) {
826
+ long slen;
852
827
 
853
- Check_Type(v, T_STRING);
854
- slen = RSTRING_LEN(v);
855
- if (sizeof(options.margin) - 1 < (size_t)slen) {
856
- rb_raise(ox_parse_error_class,
857
- ":margin can be no longer than %d characters.",
858
- (int)sizeof(options.margin) - 1);
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
- } * ParseCallbacks;
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
- } * CircArray;
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 *rb_enc;
132
- } * Options;
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; // last character read, rarely set
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;