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.
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;