ox 2.14.16 → 2.14.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ba2060f84fb1cfb231c2dd8be4e8cf54e1533f7381f88ce45ab75ff18bb5ed5
4
- data.tar.gz: c3a4ef0949a291c44a1502ce21bdecd6d1a594f6b2260f37dd042e0f87fe676d
3
+ metadata.gz: fd178b1fd415d3a97ef3b60e73896d52fd3eea1e9ef7a32dd0de316e00a21542
4
+ data.tar.gz: f9813bab8a071e6ba9efa07a92c228d3ea783a29503cfc763e72e73220899fe8
5
5
  SHA512:
6
- metadata.gz: c63630cec28f306285cc3126dca0feb2f997da02394519b7a8649bfb05d00604f4b54778dc07434acb202dfa575ca1cfab35f1cb5f9904c4939a7ce694f5d802
7
- data.tar.gz: 6f01842a610c01ae966bf897f79232cb17b46e6d3ea4c9b5c58996bd59ccd3f60a60626d4fdc76b4d5c78d1b79ceedf82ab7ea7cd2b3b9fa0802103a40ae9655
6
+ metadata.gz: 1a7cfc1bfbe0693f52f66f662d4f0f8eeabe20bc50ddefb854abde16e1f1e1c8236b64a2c1ebd51d6de18a697f588ff4d60f854e7b50b383db14ad6eed57ae92
7
+ data.tar.gz: ae9344f3607e94721eafda29f7255be6a36a0340dd4de3b03d249e616126ec340f5c9485f855ba342f33c951d7153c1b47e0b95aaada4e1936741f2b6755452c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All changes to the Ox gem are documented here. Releases follow semantic versioning.
4
4
 
5
+ ## [2.14.18] - 2024-03-21
6
+
7
+ ### Fixed
8
+
9
+ - UTF8 element names now load correctly thansk to @Uelb.
10
+
11
+ ## [2.14.17] - 2023-07-14
12
+
13
+ ### Fixed
14
+
15
+ - The sax parser in html mode now allows unquoted attribute values with complaints.
16
+
5
17
  ## [2.14.16] - 2023-04-11
6
18
 
7
19
  ### Fixed
data/ext/ox/builder.c CHANGED
@@ -337,21 +337,13 @@ static VALUE builder_new(int argc, VALUE *argv, VALUE self) {
337
337
 
338
338
  rb_check_type(*argv, T_HASH);
339
339
  if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) {
340
- #ifdef RUBY_INTEGER_UNIFICATION
341
340
  if (rb_cInteger != rb_obj_class(v)) {
342
- #else
343
- if (rb_cFixnum != rb_obj_class(v)) {
344
- #endif
345
341
  rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
346
342
  }
347
343
  indent = NUM2INT(v);
348
344
  }
349
345
  if (Qnil != (v = rb_hash_lookup(*argv, ox_size_sym))) {
350
- #ifdef RUBY_INTEGER_UNIFICATION
351
346
  if (rb_cInteger != rb_obj_class(v)) {
352
- #else
353
- if (rb_cFixnum != rb_obj_class(v)) {
354
- #endif
355
347
  rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
356
348
  }
357
349
  buf_size = NUM2LONG(v);
@@ -400,21 +392,13 @@ static VALUE builder_file(int argc, VALUE *argv, VALUE self) {
400
392
 
401
393
  rb_check_type(argv[1], T_HASH);
402
394
  if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
403
- #ifdef RUBY_INTEGER_UNIFICATION
404
395
  if (rb_cInteger != rb_obj_class(v)) {
405
- #else
406
- if (rb_cFixnum != rb_obj_class(v)) {
407
- #endif
408
396
  rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
409
397
  }
410
398
  indent = NUM2INT(v);
411
399
  }
412
400
  if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
413
- #ifdef RUBY_INTEGER_UNIFICATION
414
401
  if (rb_cInteger != rb_obj_class(v)) {
415
- #else
416
- if (rb_cFixnum != rb_obj_class(v)) {
417
- #endif
418
402
  rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
419
403
  }
420
404
  buf_size = NUM2LONG(v);
@@ -461,21 +445,13 @@ static VALUE builder_io(int argc, VALUE *argv, VALUE self) {
461
445
 
462
446
  rb_check_type(argv[1], T_HASH);
463
447
  if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) {
464
- #ifdef RUBY_INTEGER_UNIFICATION
465
448
  if (rb_cInteger != rb_obj_class(v)) {
466
- #else
467
- if (rb_cFixnum != rb_obj_class(v)) {
468
- #endif
469
449
  rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n");
470
450
  }
471
451
  indent = NUM2INT(v);
472
452
  }
473
453
  if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) {
474
- #ifdef RUBY_INTEGER_UNIFICATION
475
454
  if (rb_cInteger != rb_obj_class(v)) {
476
- #else
477
- if (rb_cFixnum != rb_obj_class(v)) {
478
- #endif
479
455
  rb_raise(ox_parse_error_class, ":size must be a fixnum.\n");
480
456
  }
481
457
  buf_size = NUM2LONG(v);
@@ -732,9 +708,7 @@ static VALUE builder_text(int argc, VALUE *argv, VALUE self) {
732
708
  strip_invalid_chars = Qfalse;
733
709
  }
734
710
 
735
- if (T_STRING != rb_type(v)) {
736
- v = rb_funcall(v, ox_to_s_id, 0);
737
- }
711
+ v = rb_String(v);
738
712
  i_am_a_child(b, true);
739
713
  append_string(b, StringValuePtr(v), RSTRING_LEN(v), xml_element_chars, RTEST(strip_invalid_chars));
740
714
 
@@ -754,9 +728,7 @@ static VALUE builder_cdata(VALUE self, VALUE data) {
754
728
  const char *end;
755
729
  int len;
756
730
 
757
- if (T_STRING != rb_type(v)) {
758
- v = rb_funcall(v, ox_to_s_id, 0);
759
- }
731
+ v = rb_String(v);
760
732
  str = StringValuePtr(v);
761
733
  len = (int)RSTRING_LEN(v);
762
734
  s = str;
@@ -796,9 +768,7 @@ static VALUE builder_raw(VALUE self, VALUE text) {
796
768
  const char *end;
797
769
  int len;
798
770
 
799
- if (T_STRING != rb_type(v)) {
800
- v = rb_funcall(v, ox_to_s_id, 0);
801
- }
771
+ v = rb_String(v);
802
772
  str = StringValuePtr(v);
803
773
  len = (int)RSTRING_LEN(v);
804
774
  s = str;
@@ -857,11 +827,7 @@ static VALUE builder_get_indent(VALUE self) {
857
827
  * - +indent+ (Fixnum) indentaion level, negative values excludes terminating newline
858
828
  */
859
829
  static VALUE builder_set_indent(VALUE self, VALUE indent) {
860
- #ifdef RUBY_INTEGER_UNIFICATION
861
830
  if (rb_cInteger != rb_obj_class(indent)) {
862
- #else
863
- if (rb_cFixnum != rb_obj_class(indent)) {
864
- #endif
865
831
  rb_raise(ox_parse_error_class, "indent must be a fixnum.\n");
866
832
  }
867
833
 
data/ext/ox/dump.c CHANGED
@@ -159,12 +159,8 @@ static Type obj_class_code(VALUE obj) {
159
159
  case T_OBJECT: return (ox_document_clas == clas || ox_element_clas == clas) ? RawCode : ObjectCode;
160
160
  case T_REGEXP: return RegexpCode;
161
161
  case T_BIGNUM: return BignumCode;
162
- #ifdef T_COMPLEX
163
162
  case T_COMPLEX: return ComplexCode;
164
- #endif
165
- #ifdef T_RATIONAL
166
163
  case T_RATIONAL: return RationalCode;
167
- #endif
168
164
  case T_CLASS: return ClassCode;
169
165
  default: return 0;
170
166
  }
@@ -440,19 +436,13 @@ inline static void dump_num(Out out, VALUE obj) {
440
436
  }
441
437
 
442
438
  static void dump_time_thin(Out out, VALUE obj) {
443
- char buf[64];
444
- char *b = buf + sizeof(buf) - 1;
445
- #if HAVE_RB_TIME_TIMESPEC
439
+ char buf[64];
440
+ char *b = buf + sizeof(buf) - 1;
446
441
  struct timespec ts = rb_time_timespec(obj);
447
442
  time_t sec = ts.tv_sec;
448
443
  long nsec = ts.tv_nsec;
449
- #else
450
- time_t sec = NUM2LONG(rb_funcall2(obj, ox_tv_sec_id, 0, 0));
451
- long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_nsec_id, 0, 0));
452
- // long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_usec_id, 0, 0)) * 1000;
453
- #endif
454
- char *dot = b - 10;
455
- long size;
444
+ char *dot = b - 10;
445
+ long size;
456
446
 
457
447
  *b-- = '\0';
458
448
  for (; dot < b; b--, nsec /= 10) {
@@ -495,18 +485,12 @@ static void dump_date(Out out, VALUE obj) {
495
485
  }
496
486
 
497
487
  static void dump_time_xsd(Out out, VALUE obj) {
498
- struct tm *tm;
499
- #if HAVE_RB_TIME_TIMESPEC
488
+ struct tm *tm;
500
489
  struct timespec ts = rb_time_timespec(obj);
501
490
  time_t sec = ts.tv_sec;
502
491
  long nsec = ts.tv_nsec;
503
- #else
504
- time_t sec = NUM2LONG(rb_funcall2(obj, ox_tv_sec_id, 0, 0));
505
- long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_nsec_id, 0, 0));
506
- // long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_usec_id, 0, 0)) * 1000;
507
- #endif
508
- int tzhour, tzmin;
509
- char tzsign = '+';
492
+ int tzhour, tzmin;
493
+ char tzsign = '+';
510
494
 
511
495
  if (out->end - out->cur <= 33) {
512
496
  grow(out, 33);
@@ -777,7 +761,7 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
777
761
  e.indent = -1;
778
762
  out->w_end(out, &e);
779
763
  } else if (0 == strcmp("BigDecimal", classname)) {
780
- volatile VALUE rs = rb_funcall(obj, ox_to_s_id, 0);
764
+ volatile VALUE rs = rb_String(obj);
781
765
 
782
766
  e.type = BigDecimalCode;
783
767
  out->w_start(out, &e);
@@ -821,13 +805,8 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
821
805
  } else {
822
806
  char num_buf[16];
823
807
  int d2 = depth + 1;
824
- #ifdef RUBY_INTEGER_UNIFICATION
825
808
  long i;
826
- long cnt = NUM2LONG(rb_struct_size(obj));
827
- #else // UNIFY_FIXNUM_AND_INTEGER
828
- int i;
829
- int cnt = (int)RSTRUCT_LEN(obj);
830
- #endif // UNIFY_FIXNUM_AND_INTEGER
809
+ long cnt = NUM2LONG(rb_struct_size(obj));
831
810
  e.type = StructCode;
832
811
  e.clas.str = rb_class2name(clas);
833
812
  e.clas.len = strlen(e.clas.str);
@@ -866,7 +845,6 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
866
845
  dump_gen_element(obj, depth + 1, out);
867
846
  out->w_end(out, &e);
868
847
  } else { /* Object */
869
- #if HAVE_RB_IVAR_FOREACH
870
848
  e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
871
849
  cnt = (int)rb_ivar_count(obj);
872
850
  e.closed = (0 >= cnt);
@@ -879,29 +857,6 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
879
857
  out->depth = od;
880
858
  out->w_end(out, &e);
881
859
  }
882
- #else
883
- volatile VALUE vars = rb_obj_instance_variables(obj);
884
- // volatile VALUE vars = rb_funcall2(obj, rb_intern("instance_variables"), 0, 0);
885
-
886
- e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
887
- cnt = (int)RARRAY_LEN(vars);
888
- e.closed = (0 >= cnt);
889
- out->w_start(out, &e);
890
- if (0 < cnt) {
891
- const VALUE *np = RARRAY_PTR(vars);
892
- ID vid;
893
- unsigned int od = out->depth;
894
- int i;
895
-
896
- out->depth = depth + 1;
897
- for (i = cnt; 0 < i; i--, np++) {
898
- vid = rb_to_id(*np);
899
- dump_var(vid, rb_ivar_get(obj, vid), out);
900
- }
901
- out->depth = od;
902
- out->w_end(out, &e);
903
- }
904
- #endif
905
860
  }
906
861
  break;
907
862
  }
@@ -940,7 +895,6 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
940
895
  out->w_end(out, &e);
941
896
  break;
942
897
  }
943
- #ifdef T_COMPLEX
944
898
  case T_COMPLEX: e.type = ComplexCode; out->w_start(out, &e);
945
899
  #ifdef RCOMPLEX
946
900
  dump_obj(0, RCOMPLEX(obj)->real, depth + 1, out);
@@ -951,8 +905,6 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
951
905
  #endif
952
906
  out->w_end(out, &e);
953
907
  break;
954
- #endif
955
- #ifdef T_RATIONAL
956
908
  case T_RATIONAL: e.type = RationalCode; out->w_start(out, &e);
957
909
  #ifdef RRATIONAL
958
910
  dump_obj(0, RRATIONAL(obj)->num, depth + 1, out);
@@ -963,7 +915,6 @@ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
963
915
  #endif
964
916
  out->w_end(out, &e);
965
917
  break;
966
- #endif
967
918
  case T_CLASS: {
968
919
  e.type = ClassCode;
969
920
  e.clas.str = rb_class2name(obj);
data/ext/ox/extconf.rb CHANGED
@@ -32,14 +32,9 @@ CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
32
32
  CONFIG['warnflags'].slice!(/ -Wdeclaration-after-statement/)
33
33
  CONFIG['warnflags'].slice!(/ -Wmissing-noreturn/)
34
34
 
35
- have_func('rb_time_timespec')
36
- have_func('rb_struct_alloc_noinit')
37
- have_func('rb_obj_encoding')
38
- have_func('rb_ivar_foreach')
39
35
  have_func('rb_ext_ractor_safe', 'ruby.h')
40
36
  have_func('pthread_mutex_init')
41
37
  have_func('rb_enc_interned_str')
42
- have_func('rb_time_nano_new')
43
38
  have_func('index')
44
39
 
45
40
  have_header('ruby/st.h')
data/ext/ox/gen_load.c CHANGED
@@ -73,9 +73,7 @@ static void create_doc(PInfo pi) {
73
73
 
74
74
  helper_stack_init(&pi->helpers);
75
75
  doc = rb_obj_alloc(ox_document_clas);
76
- #ifdef RB_GC_GUARD
77
76
  RB_GC_GUARD(doc);
78
- #endif
79
77
  nodes = rb_ary_new();
80
78
  rb_ivar_set(doc, ox_attributes_id, rb_hash_new());
81
79
  rb_ivar_set(doc, ox_nodes_id, nodes);
@@ -104,7 +102,7 @@ static void create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
104
102
  VALUE rstr = rb_str_new2(attrs->name);
105
103
 
106
104
  rb_enc_associate(rstr, pi->options->rb_enc);
107
- sym = rb_funcall(rstr, ox_to_sym_id, 0);
105
+ sym = rb_str_intern(rstr);
108
106
  } else {
109
107
  sym = ID2SYM(rb_intern(attrs->name));
110
108
  }
data/ext/ox/hash_load.c CHANGED
@@ -93,14 +93,26 @@ static void add_str(PInfo pi, VALUE s) {
93
93
  }
94
94
 
95
95
  static void add_text(PInfo pi, char *text, int closed) {
96
- add_str(pi, rb_str_new2(text));
96
+ VALUE s = rb_str_new2(text);
97
+ if (0 != pi->options->rb_enc) {
98
+ rb_enc_associate(s, pi->options->rb_enc);
99
+ }
100
+ add_str(pi, s);
97
101
  }
98
102
 
99
103
  static void add_cdata(PInfo pi, const char *text, size_t len) {
100
- add_str(pi, rb_str_new(text, len));
104
+ VALUE s = rb_str_new2(text);
105
+ if (0 != pi->options->rb_enc) {
106
+ rb_enc_associate(s, pi->options->rb_enc);
107
+ }
108
+ add_str(pi, s);
101
109
  }
102
110
 
103
111
  static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
112
+ VALUE s = rb_str_new2(ename);
113
+ if (0 != pi->options->rb_enc) {
114
+ rb_enc_associate(s, pi->options->rb_enc);
115
+ }
104
116
  if (helper_stack_empty(&pi->helpers)) {
105
117
  create_top(pi);
106
118
  }
@@ -111,12 +123,14 @@ static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren
111
123
  volatile VALUE a;
112
124
 
113
125
  for (; 0 != attrs->name; attrs++) {
126
+ key = rb_str_new2(attrs->name);
127
+ if (0 != pi->options->rb_enc) {
128
+ rb_enc_associate(key, pi->options->rb_enc);
129
+ }
114
130
  if (Qnil != pi->options->attr_key_mod) {
115
- key = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name));
131
+ key = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, key);
116
132
  } else if (Yes == pi->options->sym_keys) {
117
- key = rb_id2sym(rb_intern(attrs->name));
118
- } else {
119
- key = rb_str_new2(attrs->name);
133
+ key = rb_id2sym(rb_intern_str(key));
120
134
  }
121
135
  val = rb_str_new2(attrs->value);
122
136
  if (0 != pi->options->rb_enc) {
@@ -127,17 +141,21 @@ static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren
127
141
  a = rb_ary_new();
128
142
  rb_ary_push(a, h);
129
143
  mark_value(pi, a);
130
- helper_stack_push(&pi->helpers, rb_intern(ename), a, ArrayCode);
144
+ helper_stack_push(&pi->helpers, rb_intern_str(s), a, ArrayCode);
131
145
  } else {
132
- helper_stack_push(&pi->helpers, rb_intern(ename), Qnil, NoCode);
146
+ helper_stack_push(&pi->helpers, rb_intern_str(s), Qnil, NoCode);
133
147
  }
134
148
  }
135
149
 
136
150
  static void add_element_no_attrs(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
151
+ VALUE s = rb_str_new2(ename);
152
+ if (0 != pi->options->rb_enc) {
153
+ rb_enc_associate(s, pi->options->rb_enc);
154
+ }
137
155
  if (helper_stack_empty(&pi->helpers)) {
138
156
  create_top(pi);
139
157
  }
140
- helper_stack_push(&pi->helpers, rb_intern(ename), Qnil, NoCode);
158
+ helper_stack_push(&pi->helpers, rb_intern_str(s), Qnil, NoCode);
141
159
  }
142
160
 
143
161
  static int umark_hash_cb(VALUE key, VALUE value, VALUE x) {
@@ -224,8 +242,22 @@ static void finish(PInfo pi) {
224
242
  xfree(pi->marked);
225
243
  }
226
244
 
245
+ static void set_encoding_from_instruct(PInfo pi, Attr attrs) {
246
+ for (; 0 != attrs->name; attrs++) {
247
+ if (0 == strcmp("encoding", attrs->name)) {
248
+ pi->options->rb_enc = rb_enc_find(attrs->value);
249
+ }
250
+ }
251
+ }
252
+
253
+ static void instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
254
+ if (0 == strcmp("xml", target)) {
255
+ set_encoding_from_instruct(pi, attrs);
256
+ }
257
+ }
258
+
227
259
  struct _parseCallbacks _ox_hash_callbacks = {
228
- NULL,
260
+ instruct,
229
261
  NULL,
230
262
  NULL,
231
263
  NULL,
@@ -238,7 +270,7 @@ struct _parseCallbacks _ox_hash_callbacks = {
238
270
  ParseCallbacks ox_hash_callbacks = &_ox_hash_callbacks;
239
271
 
240
272
  struct _parseCallbacks _ox_hash_cdata_callbacks = {
241
- NULL,
273
+ instruct,
242
274
  NULL,
243
275
  NULL,
244
276
  add_cdata,
@@ -251,7 +283,7 @@ struct _parseCallbacks _ox_hash_cdata_callbacks = {
251
283
  ParseCallbacks ox_hash_cdata_callbacks = &_ox_hash_cdata_callbacks;
252
284
 
253
285
  struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
254
- NULL,
286
+ instruct,
255
287
  NULL,
256
288
  NULL,
257
289
  NULL,
@@ -264,7 +296,7 @@ struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
264
296
  ParseCallbacks ox_hash_no_attrs_callbacks = &_ox_hash_no_attrs_callbacks;
265
297
 
266
298
  struct _parseCallbacks _ox_hash_no_attrs_cdata_callbacks = {
267
- NULL,
299
+ instruct,
268
300
  NULL,
269
301
  NULL,
270
302
  add_cdata,
data/ext/ox/obj_load.c CHANGED
@@ -106,11 +106,7 @@ inline static VALUE structname2obj(const char *name) {
106
106
  }
107
107
  }
108
108
  ost = rb_const_get(ox_struct_class, rb_intern(s));
109
- #if HAVE_RB_STRUCT_ALLOC_NOINIT
110
109
  return rb_struct_alloc_noinit(ost);
111
- #else
112
- return rb_struct_new(ost);
113
- #endif
114
110
  }
115
111
 
116
112
  inline static VALUE parse_ulong(const char *s, PInfo pi) {
@@ -643,27 +639,21 @@ static void end_element(PInfo pi, const char *ename) {
643
639
  rb_hash_aset(gh->obj, ph->obj, h->obj);
644
640
  } break;
645
641
  case ComplexCode:
646
- #ifdef T_COMPLEX
647
642
  if (Qundef == ph->obj) {
648
643
  ph->obj = h->obj;
649
644
  } else {
650
645
  ph->obj = rb_complex_new(ph->obj, h->obj);
651
646
  }
652
- #else
653
- set_error(&pi->err, "Complex Objects not implemented in Ruby 1.8.7", pi->str, pi->s);
654
- return;
655
- #endif
656
647
  break;
657
648
  case RationalCode: {
658
649
  if (Qundef == h->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
659
650
  set_error(&pi->err, "Invalid object format", pi->str, pi->s);
660
651
  return;
661
652
  }
662
- #ifdef T_RATIONAL
663
653
  if (Qundef == ph->obj) {
664
654
  ph->obj = h->obj;
665
655
  } else {
666
- if (Qundef == ph->obj || RUBY_T_FIXNUM != rb_type(h->obj)) {
656
+ if (Qundef == ph->obj || RUBY_T_FIXNUM != rb_type(ph->obj)) {
667
657
  set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s);
668
658
  return;
669
659
  }
@@ -673,10 +663,6 @@ static void end_element(PInfo pi, const char *ename) {
673
663
  ph->obj = rb_rational_new(ph->obj, h->obj);
674
664
  #endif
675
665
  }
676
- #else
677
- set_error(&pi->err, "Rational Objects not implemented in Ruby 1.8.7", pi->str, pi->s);
678
- return;
679
- #endif
680
666
  break;
681
667
  }
682
668
  default:
@@ -719,11 +705,7 @@ static VALUE parse_double_time(const char *text, VALUE clas) {
719
705
  for (; text - dot <= 9; text++) {
720
706
  v2 *= 10;
721
707
  }
722
- #if HAVE_RB_TIME_NANO_NEW
723
708
  return rb_time_nano_new(v, v2);
724
- #else
725
- return rb_time_new(v, v2 / 1000);
726
- #endif
727
709
  }
728
710
 
729
711
  typedef struct _tp {
@@ -774,11 +756,7 @@ static VALUE parse_xsd_time(const char *text, VALUE clas) {
774
756
  tm.tm_hour = (int)cargs[3];
775
757
  tm.tm_min = (int)cargs[4];
776
758
  tm.tm_sec = (int)cargs[5];
777
- #if HAVE_RB_TIME_NANO_NEW
778
759
  return rb_time_nano_new(mktime(&tm), cargs[6]);
779
- #else
780
- return rb_time_new(mktime(&tm), cargs[6] / 1000);
781
- #endif
782
760
  }
783
761
 
784
762
  // debug functions
@@ -816,7 +794,7 @@ static void debug_stack(PInfo pi, const char *comment) {
816
794
  if (HashCode == h->type) {
817
795
  VALUE v;
818
796
 
819
- v = rb_funcall2(h->var, rb_intern("to_s"), 0, 0);
797
+ v = rb_String(h->var);
820
798
  key = StringValuePtr(v);
821
799
  } else if (ObjectCode == (h - 1)->type || ExceptionCode == (h - 1)->type ||
822
800
  RangeCode == (h - 1)->type || StructCode == (h - 1)->type) {
data/ext/ox/ox.c CHANGED
@@ -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;
@@ -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
@@ -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;
data/ext/ox/parse.c CHANGED
@@ -167,7 +167,7 @@ ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options
167
167
  helper_stack_cleanup(&pi.helpers);
168
168
  return Qnil;
169
169
  }
170
- pi.s++; // past <
170
+ pi.s++; // past <
171
171
  switch (*pi.s) {
172
172
  case '?': // processing instruction
173
173
  pi.s++;
data/ext/ox/sax.c CHANGED
@@ -55,7 +55,7 @@ static char read_text(SaxDrive dr);
55
55
  static char read_jump(SaxDrive dr, const char *pat);
56
56
  static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req, Hint h);
57
57
  static char read_name_token(SaxDrive dr);
58
- static char read_quoted_value(SaxDrive dr);
58
+ static char read_quoted_value(SaxDrive dr, bool inst);
59
59
 
60
60
  static void hint_clear_empty(SaxDrive dr);
61
61
  static Nv hint_try_close(SaxDrive dr, const char *name);
@@ -469,7 +469,7 @@ DONE:
469
469
  Nv sp;
470
470
 
471
471
  for (sp = dr->stack.tail - 1; dr->stack.head <= sp; sp--) {
472
- snprintf(msg, sizeof(msg) - 1, "%selement '%s' not closed", EL_MISMATCH, sp->name);
472
+ snprintf(msg, sizeof(msg) - 1, "%selement '%s' not closed", EL_MISMATCH, nv_name(sp));
473
473
  ox_sax_drive_error_at(dr, msg, dr->buf.pos, dr->buf.line, dr->buf.col);
474
474
  end_element_cb(dr, sp->val, dr->buf.pos, dr->buf.line, dr->buf.col, sp->hint);
475
475
  }
@@ -1219,6 +1219,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
1219
1219
  c = buf_next_non_white(&dr->buf);
1220
1220
  }
1221
1221
  if ('=' != c) {
1222
+ // TBD allow in smart mode
1222
1223
  if (eq_req) {
1223
1224
  dr->err = 1;
1224
1225
  return c;
@@ -1230,7 +1231,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
1230
1231
  pos = dr->buf.pos + 1;
1231
1232
  line = dr->buf.line;
1232
1233
  col = dr->buf.col + 1;
1233
- c = read_quoted_value(dr);
1234
+ c = read_quoted_value(dr, '?' == termc);
1234
1235
  attr_value = dr->buf.str;
1235
1236
 
1236
1237
  if (is_encoding) {
@@ -1297,10 +1298,11 @@ static char read_name_token(SaxDrive dr) {
1297
1298
  return '\0';
1298
1299
  }
1299
1300
 
1300
- /* The character after the quote or if there is no quote, the character after the word is returned. dr->buf.tail is one
1301
- * past that. dr->buf.str will point to the token which will be '\0' terminated.
1301
+ /* The character after the quote or if there is no quote, the character after
1302
+ * the word is returned. dr->buf.tail is one past that. dr->buf.str will point
1303
+ * to the token which will be '\0' terminated.
1302
1304
  */
1303
- static char read_quoted_value(SaxDrive dr) {
1305
+ static char read_quoted_value(SaxDrive dr, bool inst) {
1304
1306
  char c;
1305
1307
 
1306
1308
  c = buf_get(&dr->buf);
@@ -1324,19 +1326,27 @@ static char read_quoted_value(SaxDrive dr) {
1324
1326
  }
1325
1327
  // not quoted, look for something that terminates the string
1326
1328
  dr->buf.str = dr->buf.tail - 1;
1327
- ox_sax_drive_error(dr, WRONG_CHAR "attribute value not in quotes");
1329
+ // TBD if smart or html then no error
1330
+ if (!(dr->options.smart && ox_hints_html() != dr->options.hints)) {
1331
+ ox_sax_drive_error(dr, WRONG_CHAR "attribute value not in quotes");
1332
+ }
1328
1333
  while ('\0' != (c = buf_get(&dr->buf))) {
1329
1334
  switch (c) {
1330
1335
  case ' ':
1331
1336
  // case '/':
1332
1337
  case '>':
1333
- case '?': // for instructions
1334
1338
  case '\t':
1335
1339
  case '\n':
1336
1340
  case '\r':
1337
1341
  *(dr->buf.tail - 1) = '\0'; /* terminate value */
1338
1342
  // dr->buf.tail is in the correct position, one after the word terminator
1339
1343
  return c;
1344
+ case '?':
1345
+ if (inst) {
1346
+ *(dr->buf.tail - 1) = '\0'; /* terminate value */
1347
+ return c;
1348
+ }
1349
+ break;
1340
1350
  default: break;
1341
1351
  }
1342
1352
  }
data/ext/ox/sax_as.c CHANGED
@@ -43,11 +43,7 @@ static VALUE parse_double_time(const char *text) {
43
43
  for (; text - dot <= 9; text++) {
44
44
  v2 *= 10;
45
45
  }
46
- #if HAVE_RB_TIME_NANO_NEW
47
46
  return rb_time_nano_new(v, v2);
48
- #else
49
- return rb_time_new(v, v2 / 1000);
50
- #endif
51
47
  }
52
48
 
53
49
  typedef struct _tp {
@@ -102,11 +98,7 @@ static VALUE parse_xsd_time(const char *text) {
102
98
  tm.tm_hour = (int)cargs[3];
103
99
  tm.tm_min = (int)cargs[4];
104
100
  tm.tm_sec = (int)cargs[5];
105
- #if HAVE_RB_TIME_NANO_NEW
106
101
  return rb_time_nano_new(mktime(&tm), cargs[6]);
107
- #else
108
- return rb_time_new(mktime(&tm), cargs[6] / 1000);
109
- #endif
110
102
  }
111
103
 
112
104
  /* call-seq: as_s()
data/ext/ox/sax_buf.c CHANGED
@@ -79,7 +79,7 @@ int ox_sax_buf_read(Buf buf) {
79
79
  } else {
80
80
  shift = buf->pro - buf->head - 1; // leave one character so we cab backup one
81
81
  }
82
- if (0 >= shift) { /* no space left so allocate more */
82
+ if (0 >= shift) { /* no space left so allocate more */
83
83
  char *old = buf->head;
84
84
  size_t size = buf->end - buf->head + BUF_PAD;
85
85
 
data/ext/ox/slotcache.c CHANGED
@@ -82,8 +82,8 @@ slot_cache_get(SlotCache cache, const char *key, VALUE **slot, const char **keyp
82
82
  orig->key = form_key(key);
83
83
  orig->value = Qundef;
84
84
  }
85
- } else { /* not exact match but on the path */
86
- if (0 != cache->key) { /* there is a key/value here already */
85
+ } else { /* not exact match but on the path */
86
+ if (0 != cache->key) { /* there is a key/value here already */
87
87
  if (depth == *cache->key || (255 <= depth && 0 == strncmp(cache->key, key, depth) &&
88
88
  '\0' == cache->key[depth])) { /* key belongs here */
89
89
  continue;
@@ -145,7 +145,7 @@ static void slot_print(SlotCache c, unsigned int depth) {
145
145
  vs = "undefined";
146
146
  clas = "";
147
147
  } else {
148
- VALUE rs = rb_funcall2((*cp)->value, rb_intern("to_s"), 0, 0);
148
+ VALUE rs = rb_String((*cp)->value);
149
149
 
150
150
  vs = StringValuePtr(rs);
151
151
  clas = rb_class2name(rb_obj_class((*cp)->value));
data/lib/ox/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Ox
2
2
  # Current version of the module.
3
- VERSION = '2.14.16'
3
+ VERSION = '2.14.18'
4
4
  end
@@ -12,6 +12,7 @@ module Ox
12
12
  class StreamParser < XMLRPC::XMLParser::AbstractStreamParser
13
13
  # Create a new instance.
14
14
  def initialize
15
+ super
15
16
  @parser_class = OxParser
16
17
  end
17
18
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.14.16
4
+ version: 2.14.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-12 00:00:00.000000000 Z
11
+ date: 2024-03-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: "A fast XML parser and object serializer that uses only standard C lib.\n\nOptimized
14
14
  XML (Ox), as the name implies was written to provide speed optimized\nXML handling.
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
107
  requirements: []
108
- rubygems_version: 3.4.1
108
+ rubygems_version: 3.4.10
109
109
  signing_key:
110
110
  specification_version: 4
111
111
  summary: A fast XML parser and object serializer.