ox 2.12.1 → 2.14.0

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.
@@ -74,19 +74,14 @@ unmark(PInfo pi, VALUE val) {
74
74
  }
75
75
 
76
76
  static void
77
- add_text(PInfo pi, char *text, int closed) {
77
+ add_str(PInfo pi, VALUE s) {
78
78
  Helper parent = helper_stack_peek(&pi->helpers);
79
- volatile VALUE s = rb_str_new2(text);
80
79
  volatile VALUE a;
81
80
 
82
- #if HAS_ENCODING_SUPPORT
81
+ #if HAVE_RB_ENC_ASSOCIATE
83
82
  if (0 != pi->options->rb_enc) {
84
83
  rb_enc_associate(s, pi->options->rb_enc);
85
84
  }
86
- #elif HAS_PRIVATE_ENCODING
87
- if (Qnil != pi->options->rb_enc) {
88
- rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
89
- }
90
85
  #endif
91
86
  switch (parent->type) {
92
87
  case NoCode:
@@ -106,6 +101,16 @@ add_text(PInfo pi, char *text, int closed) {
106
101
  }
107
102
  }
108
103
 
104
+ static void
105
+ add_text(PInfo pi, char *text, int closed) {
106
+ add_str(pi, rb_str_new2(text));
107
+ }
108
+
109
+ static void
110
+ add_cdata(PInfo pi, const char *text, size_t len) {
111
+ add_str(pi, rb_str_new(text, len));
112
+ }
113
+
109
114
  static void
110
115
  add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
111
116
  if (helper_stack_empty(&pi->helpers)) {
@@ -126,14 +131,10 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
126
131
  key = rb_str_new2(attrs->name);
127
132
  }
128
133
  val = rb_str_new2(attrs->value);
129
- #if HAS_ENCODING_SUPPORT
134
+ #if HAVE_RB_ENC_ASSOCIATE
130
135
  if (0 != pi->options->rb_enc) {
131
136
  rb_enc_associate(val, pi->options->rb_enc);
132
137
  }
133
- #elif HAS_PRIVATE_ENCODING
134
- if (Qnil != pi->options->rb_enc) {
135
- rb_funcall(val, ox_force_encoding_id, 1, pi->options->rb_enc);
136
- }
137
138
  #endif
138
139
  rb_hash_aset(h, key, val);
139
140
  }
@@ -258,6 +259,19 @@ struct _parseCallbacks _ox_hash_callbacks = {
258
259
 
259
260
  ParseCallbacks ox_hash_callbacks = &_ox_hash_callbacks;
260
261
 
262
+ struct _parseCallbacks _ox_hash_cdata_callbacks = {
263
+ NULL,
264
+ NULL,
265
+ NULL,
266
+ add_cdata,
267
+ add_text,
268
+ add_element,
269
+ end_element,
270
+ finish,
271
+ };
272
+
273
+ ParseCallbacks ox_hash_cdata_callbacks = &_ox_hash_cdata_callbacks;
274
+
261
275
  struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
262
276
  NULL,
263
277
  NULL,
@@ -270,3 +284,16 @@ struct _parseCallbacks _ox_hash_no_attrs_callbacks = {
270
284
  };
271
285
 
272
286
  ParseCallbacks ox_hash_no_attrs_callbacks = &_ox_hash_no_attrs_callbacks;
287
+
288
+ struct _parseCallbacks _ox_hash_no_attrs_cdata_callbacks = {
289
+ NULL,
290
+ NULL,
291
+ NULL,
292
+ add_cdata,
293
+ add_text,
294
+ add_element_no_attrs,
295
+ end_element_no_attrs,
296
+ NULL,
297
+ };
298
+
299
+ ParseCallbacks ox_hash_no_attrs_cdata_callbacks = &_ox_hash_no_attrs_cdata_callbacks;
@@ -11,6 +11,9 @@
11
11
  #include <time.h>
12
12
 
13
13
  #include "ruby.h"
14
+ #if HAVE_RB_ENC_ASSOCIATE
15
+ #include "ruby/encoding.h"
16
+ #endif
14
17
  #include "base64.h"
15
18
  #include "ox.h"
16
19
 
@@ -143,7 +146,6 @@ classname2obj(const char *name, PInfo pi, VALUE base_class) {
143
146
  }
144
147
  }
145
148
 
146
- #if HAS_RSTRUCT
147
149
  inline static VALUE
148
150
  structname2obj(const char *name) {
149
151
  VALUE ost;
@@ -159,16 +161,12 @@ structname2obj(const char *name) {
159
161
  }
160
162
  }
161
163
  ost = rb_const_get(ox_struct_class, rb_intern(s));
162
- /* use encoding as the indicator for Ruby 1.8.7 or 1.9.x */
163
- #if HAS_ENCODING_SUPPORT
164
- return rb_struct_alloc_noinit(ost);
165
- #elif HAS_PRIVATE_ENCODING
164
+ #if HAVE_RB_STRUCT_ALLOC_NOINIT
166
165
  return rb_struct_alloc_noinit(ost);
167
166
  #else
168
167
  return rb_struct_new(ost);
169
168
  #endif
170
169
  }
171
- #endif
172
170
 
173
171
  inline static VALUE
174
172
  parse_ulong(const char *s, PInfo pi) {
@@ -239,6 +237,7 @@ static ID
239
237
  get_var_sym_from_attrs(Attr a, void *encoding) {
240
238
  for (; 0 != a->name; a++) {
241
239
  if ('a' == *a->name && '\0' == *(a->name + 1)) {
240
+ name2var(a->value, encoding);
242
241
  return name2var(a->value, encoding);
243
242
  }
244
243
  }
@@ -255,7 +254,6 @@ get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class) {
255
254
  return Qundef;
256
255
  }
257
256
 
258
- #if HAS_RSTRUCT
259
257
  static VALUE
260
258
  get_struct_from_attrs(Attr a) {
261
259
  for (; 0 != a->name; a++) {
@@ -265,7 +263,6 @@ get_struct_from_attrs(Attr a) {
265
263
  }
266
264
  return Qundef;
267
265
  }
268
- #endif
269
266
 
270
267
  static VALUE
271
268
  get_class_from_attrs(Attr a, PInfo pi, VALUE base_class) {
@@ -363,7 +360,7 @@ parse_regexp(const char *text) {
363
360
  int options = 0;
364
361
 
365
362
  te = text + strlen(text) - 1;
366
- #if HAS_ONIG
363
+ #ifdef ONIG_OPTION_IGNORECASE
367
364
  for (; text < te && '/' != *te; te--) {
368
365
  switch (*te) {
369
366
  case 'i': options |= ONIG_OPTION_IGNORECASE; break;
@@ -379,18 +376,12 @@ parse_regexp(const char *text) {
379
376
  static void
380
377
  instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
381
378
  if (0 == strcmp("xml", target)) {
382
- #if HAS_ENCODING_SUPPORT
379
+ #if HAVE_RB_ENC_FIND
383
380
  for (; 0 != attrs->name; attrs++) {
384
381
  if (0 == strcmp("encoding", attrs->name)) {
385
382
  pi->options->rb_enc = rb_enc_find(attrs->value);
386
383
  }
387
384
  }
388
- #elif HAS_PRIVATE_ENCODING
389
- for (; 0 != attrs->name; attrs++) {
390
- if (0 == strcmp("encoding", attrs->name)) {
391
- pi->options->rb_enc = rb_str_new2(attrs->value);
392
- }
393
- }
394
385
  #endif
395
386
  }
396
387
  }
@@ -417,14 +408,10 @@ add_text(PInfo pi, char *text, int closed) {
417
408
  case NoCode:
418
409
  case StringCode:
419
410
  h->obj = rb_str_new2(text);
420
- #if HAS_ENCODING_SUPPORT
411
+ #if HAVE_RB_ENC_ASSOCIATE
421
412
  if (0 != pi->options->rb_enc) {
422
413
  rb_enc_associate(h->obj, pi->options->rb_enc);
423
414
  }
424
- #elif HAS_PRIVATE_ENCODING
425
- if (Qnil != pi->options->rb_enc) {
426
- rb_funcall(h->obj, ox_force_encoding_id, 1, pi->options->rb_enc);
427
- }
428
415
  #endif
429
416
  if (0 != pi->circ_array) {
430
417
  circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id);
@@ -494,14 +481,10 @@ add_text(PInfo pi, char *text, int closed) {
494
481
 
495
482
  from_base64(text, (uchar*)str);
496
483
  v = rb_str_new(str, str_size);
497
- #if HAS_ENCODING_SUPPORT
484
+ #if HAVE_RB_ENC_ASSOCIATE
498
485
  if (0 != pi->options->rb_enc) {
499
486
  rb_enc_associate(v, pi->options->rb_enc);
500
487
  }
501
- #elif HAS_PRIVATE_ENCODING
502
- if (0 != pi->options->rb_enc) {
503
- rb_funcall(v, ox_force_encoding_id, 1, pi->options->rb_enc);
504
- }
505
488
  #endif
506
489
  if (0 != pi->circ_array) {
507
490
  circ_array_set(pi->circ_array, v, (unsigned long)h->obj);
@@ -542,11 +525,7 @@ add_text(PInfo pi, char *text, int closed) {
542
525
  h->obj = rb_cstr_to_inum(text, 10, 1);
543
526
  break;
544
527
  case BigDecimalCode:
545
- #if HAS_BIGDECIMAL
546
528
  h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text));
547
- #else
548
- h->obj = Qnil;
549
- #endif
550
529
  break;
551
530
  default:
552
531
  h->obj = Qnil;
@@ -670,15 +649,10 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
670
649
  }
671
650
  break;
672
651
  case StructCode:
673
- #if HAS_RSTRUCT
674
652
  h->obj = get_struct_from_attrs(attrs);
675
653
  if (0 != pi->circ_array) {
676
654
  circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
677
655
  }
678
- #else
679
- set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
680
- return;
681
- #endif
682
656
  break;
683
657
  case ClassCode:
684
658
  if (Qundef == (h->obj = get_class_from_attrs(attrs, pi, ox_bag_clas))) {
@@ -742,31 +716,29 @@ end_element(PInfo pi, const char *ename) {
742
716
  case ExceptionCode:
743
717
  case ObjectCode:
744
718
  if (Qnil != ph->obj) {
745
- if (0 == h->var) {
719
+ if (0 == h->var || NULL == rb_id2name(h->var )) {
746
720
  set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
747
721
  return;
748
722
  }
723
+ if (RUBY_T_OBJECT != rb_type(ph->obj)) {
724
+ set_error(&pi->err, "Corrupt object encoding", pi->str, pi->s);
725
+ return;
726
+ }
749
727
  rb_ivar_set(ph->obj, h->var, h->obj);
750
728
  }
751
729
  break;
752
730
  case StructCode:
753
- #if HAS_RSTRUCT
754
731
  if (0 == h->var) {
755
732
  set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
756
733
  return;
757
734
  }
758
735
  rb_struct_aset(ph->obj, h->var, h->obj);
759
- #else
760
- set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
761
- return;
762
- #endif
763
736
  break;
764
737
  case HashCode:
765
738
  // put back h
766
739
  helper_stack_push(&pi->helpers, h->var, h->obj, KeyCode);
767
740
  break;
768
741
  case RangeCode:
769
- #if HAS_RSTRUCT
770
742
  if (ox_beg_id == h->var) {
771
743
  RSTRUCT_SET(ph->obj, 0, h->obj);
772
744
  } else if (ox_end_id == h->var) {
@@ -777,10 +749,6 @@ end_element(PInfo pi, const char *ename) {
777
749
  set_error(&pi->err, "Invalid range attribute", pi->str, pi->s);
778
750
  return;
779
751
  }
780
- #else
781
- set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
782
- return;
783
- #endif
784
752
  break;
785
753
  case KeyCode:
786
754
  {
@@ -145,6 +145,7 @@ static VALUE symbolize_keys_sym;
145
145
  static VALUE symbolize_sym;
146
146
  static VALUE tolerant_sym;
147
147
  static VALUE trace_sym;
148
+ static VALUE with_cdata_sym;
148
149
  static VALUE with_dtd_sym;
149
150
  static VALUE with_instruct_sym;
150
151
  static VALUE with_xml_sym;
@@ -154,10 +155,8 @@ static VALUE element_key_mod_sym;
154
155
  static ID encoding_id;
155
156
  static ID has_key_id;
156
157
 
157
- #if HAS_ENCODING_SUPPORT
158
+ #if HAVE_RB_ENC_ASSOCIATE
158
159
  rb_encoding *ox_utf8_encoding = 0;
159
- #elif HAS_PRIVATE_ENCODING
160
- VALUE ox_utf8_encoding = Qnil;
161
160
  #else
162
161
  void *ox_utf8_encoding = 0;
163
162
  #endif
@@ -181,16 +180,13 @@ struct _options ox_default_options = {
181
180
  true, // convert_special
182
181
  No, // allow_invalid
183
182
  false, // no_empty
183
+ false, // with_cdata
184
184
  { '\0' }, // inv_repl
185
185
  { '\0' }, // strip_ns
186
186
  NULL, // html_hints
187
187
  Qnil, // attr_key_mod;
188
188
  Qnil, // element_key_mod;
189
- #if HAS_PRIVATE_ENCODING
190
- Qnil // rb_enc
191
- #else
192
189
  0 // rb_enc
193
- #endif
194
190
  };
195
191
 
196
192
  extern ParseCallbacks ox_obj_callbacks;
@@ -198,7 +194,9 @@ extern ParseCallbacks ox_gen_callbacks;
198
194
  extern ParseCallbacks ox_limited_callbacks;
199
195
  extern ParseCallbacks ox_nomode_callbacks;
200
196
  extern ParseCallbacks ox_hash_callbacks;
197
+ extern ParseCallbacks ox_hash_cdata_callbacks;
201
198
  extern ParseCallbacks ox_hash_no_attrs_callbacks;
199
+ extern ParseCallbacks ox_hash_no_attrs_cdata_callbacks;
202
200
 
203
201
  static void parse_dump_options(VALUE ropts, Options copts);
204
202
 
@@ -296,6 +294,7 @@ hints_to_overlay(Hints hints) {
296
294
  * - _:convert_special_ [true|false|nil] flag indicating special characters like &lt; are converted with the SAX parser
297
295
  * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
298
296
  * - _:no_empty_ [true|false|nil] flag indicating there should be no empty elements in a dump
297
+ * - _:with_cdata_ [true|false] includes cdata in hash_load results
299
298
  * - _:strip_namespace_ [String|true|false] false or "" results in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
300
299
  * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
301
300
  * - _:active_ - make the normal callback for the element
@@ -330,6 +329,7 @@ get_def_opts(VALUE self) {
330
329
  rb_hash_aset(opts, smart_sym, (Yes == ox_default_options.smart) ? Qtrue : ((No == ox_default_options.smart) ? Qfalse : Qnil));
331
330
  rb_hash_aset(opts, convert_special_sym, (ox_default_options.convert_special) ? Qtrue : Qfalse);
332
331
  rb_hash_aset(opts, no_empty_sym, (ox_default_options.no_empty) ? Qtrue : Qfalse);
332
+ rb_hash_aset(opts, with_cdata_sym, (ox_default_options.with_cdata) ? Qtrue : Qfalse);
333
333
  switch (ox_default_options.mode) {
334
334
  case ObjMode: rb_hash_aset(opts, mode_sym, object_sym); break;
335
335
  case GenMode: rb_hash_aset(opts, mode_sym, generic_sym); break;
@@ -437,6 +437,7 @@ sax_html_overlay(VALUE self) {
437
437
  * - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html)
438
438
  * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
439
439
  * - _:strip_namespace_ [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
440
+ * - _:with_cdata_ [true|false] includes cdata in hash_load results
440
441
  * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
441
442
  * - _:active_ - make the normal callback for the element
442
443
  * - _:nest_ok_ - active but ignore nest check
@@ -470,11 +471,8 @@ set_def_opts(VALUE self, VALUE opts) {
470
471
  } else {
471
472
  Check_Type(v, T_STRING);
472
473
  strncpy(ox_default_options.encoding, StringValuePtr(v), sizeof(ox_default_options.encoding) - 1);
473
- #if HAS_ENCODING_SUPPORT
474
+ #if HAVE_RB_ENC_FIND
474
475
  ox_default_options.rb_enc = rb_enc_find(ox_default_options.encoding);
475
- #elif HAS_PRIVATE_ENCODING
476
- ox_default_options.rb_enc = rb_str_new2(ox_default_options.encoding);
477
- rb_gc_register_address(&ox_default_options.rb_enc);
478
476
  #endif
479
477
  }
480
478
 
@@ -639,6 +637,10 @@ set_def_opts(VALUE self, VALUE opts) {
639
637
  rb_hash_foreach(v, set_overlay, (VALUE)ox_default_options.html_hints);
640
638
  }
641
639
  }
640
+ if (Qnil != (v = rb_hash_lookup(opts, with_cdata_sym))) {
641
+ ox_default_options.with_cdata = (Qtrue == v);
642
+ }
643
+
642
644
  ox_default_options.element_key_mod = rb_hash_lookup2(opts, element_key_mod_sym, ox_default_options.element_key_mod);
643
645
  ox_default_options.attr_key_mod = rb_hash_lookup2(opts, attr_key_mod_sym, ox_default_options.attr_key_mod);
644
646
 
@@ -674,14 +676,14 @@ to_obj(VALUE self, VALUE ruby_xml) {
674
676
  xml = ALLOCA_N(char, len);
675
677
  }
676
678
  memcpy(xml, x, len);
677
- #if HAS_GC_GUARD
679
+ #ifdef RB_GC_GUARD
678
680
  rb_gc_disable();
679
681
  #endif
680
682
  obj = ox_parse(xml, len - 1, ox_obj_callbacks, 0, &options, &err);
681
683
  if (SMALL_XML < len) {
682
684
  xfree(xml);
683
685
  }
684
- #if HAS_GC_GUARD
686
+ #ifdef RB_GC_GUARD
685
687
  RB_GC_GUARD(obj);
686
688
  rb_gc_enable();
687
689
  #endif
@@ -847,8 +849,11 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
847
849
  options.margin[sizeof(options.margin) - 1] = '\0';
848
850
  options.margin_len = strlen(options.margin);
849
851
  }
852
+ if (Qnil != (v = rb_hash_lookup(h, with_cdata_sym))) {
853
+ options.with_cdata = (Qtrue == v);
854
+ }
850
855
  }
851
- #if HAS_ENCODING_SUPPORT
856
+ #if HAVE_RB_ENC_FIND
852
857
  if ('\0' == *options.encoding) {
853
858
  if (Qnil != encoding) {
854
859
  options.rb_enc = rb_enc_from_index(rb_enc_get_index(encoding));
@@ -858,26 +863,15 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
858
863
  } else if (0 == options.rb_enc) {
859
864
  options.rb_enc = rb_enc_find(options.encoding);
860
865
  }
861
- #elif HAS_PRIVATE_ENCODING
862
- if ('\0' == *options.encoding) {
863
- if (Qnil != encoding) {
864
- options.rb_enc = encoding;
865
- } else {
866
- options.rb_enc = Qnil;
867
- }
868
- } else if (0 == options.rb_enc) {
869
- options.rb_enc = rb_str_new2(options.encoding);
870
- rb_gc_register_address(&options.rb_enc);
871
- }
872
866
  #endif
873
867
  xml = defuse_bom(xml, &options);
874
868
  switch (options.mode) {
875
869
  case ObjMode:
876
- #if HAS_GC_GUARD
870
+ #ifdef RB_GC_GUARD
877
871
  rb_gc_disable();
878
872
  #endif
879
873
  obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err);
880
- #if HAS_GC_GUARD
874
+ #ifdef RB_GC_GUARD
881
875
  RB_GC_GUARD(obj);
882
876
  rb_gc_enable();
883
877
  #endif
@@ -889,10 +883,18 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
889
883
  obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err);
890
884
  break;
891
885
  case HashMode:
892
- obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
886
+ if (options.with_cdata) {
887
+ obj = ox_parse(xml, len, ox_hash_cdata_callbacks, 0, &options, err);
888
+ } else {
889
+ obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
890
+ }
893
891
  break;
894
892
  case HashNoAttrMode:
895
- obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
893
+ if (options.with_cdata) {
894
+ obj = ox_parse(xml, len, ox_hash_no_attrs_cdata_callbacks, 0, &options, err);
895
+ } else {
896
+ obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
897
+ }
896
898
  break;
897
899
  case NoMode:
898
900
  obj = ox_parse(xml, len, ox_nomode_callbacks, 0, &options, err);
@@ -928,6 +930,7 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
928
930
  * - *:symbolize_keys* [true|false|nil] symbolize element attribute keys or leave as Strings
929
931
  * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
930
932
  * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
933
+ * - *:with_cdata* [true|false] if true cdata is included in hash_load output otherwise it is not.
931
934
  */
932
935
  static VALUE
933
936
  load_str(int argc, VALUE *argv, VALUE self) {
@@ -946,14 +949,8 @@ load_str(int argc, VALUE *argv, VALUE self) {
946
949
  } else {
947
950
  xml = ALLOCA_N(char, len);
948
951
  }
949
- #if HAS_ENCODING_SUPPORT
950
- #ifdef MACRUBY_RUBY
951
- encoding = rb_funcall(*argv, encoding_id, 0);
952
- #else
952
+ #if HAVE_RB_OBJ_ENCODING
953
953
  encoding = rb_obj_encoding(*argv);
954
- #endif
955
- #elif HAS_PRIVATE_ENCODING
956
- encoding = rb_funcall(*argv, encoding_id, 0);
957
954
  #else
958
955
  encoding = Qnil;
959
956
  #endif
@@ -1319,21 +1316,38 @@ dump(int argc, VALUE *argv, VALUE self) {
1319
1316
  rb_raise(rb_eNoMemError, "Not enough memory.\n");
1320
1317
  }
1321
1318
  rstr = rb_str_new2(xml);
1322
- #if HAS_ENCODING_SUPPORT
1319
+ #if HAVE_RB_ENC_ASSOCIATE
1323
1320
  if ('\0' != *copts.encoding) {
1324
1321
  rb_enc_associate(rstr, rb_enc_find(copts.encoding));
1325
1322
  }
1326
- #elif HAS_PRIVATE_ENCODING
1327
- if ('\0' != *copts.encoding) {
1328
- rb_funcall(rstr, ox_force_encoding_id, 1, rb_str_new2(copts.encoding));
1329
- }
1330
1323
  #endif
1331
1324
  xfree(xml);
1332
1325
 
1333
1326
  return rstr;
1334
1327
  }
1335
1328
 
1336
- /* call-seq: to_file(file_path, obj, options)
1329
+ /* call-seq: to_xml(obj, options) => xml-string
1330
+ *
1331
+ * Dumps an Object (obj) to a string.
1332
+ * - +obj+ [Object] Object to serialize as an XML document String
1333
+ * - +options+ [Hash] formating options
1334
+ * - *:indent* [Fixnum] format expected
1335
+ * - *:no_empty* [true|false] if true don't output empty elements
1336
+ * - *:xsd_date* [true|false] use XSD date format if true, default: false
1337
+ * - *:circular* [true|false] allow circular references, default: false
1338
+ * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: :strict
1339
+ * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered
1340
+ * - _:tolerant_ - replaces undumplable objects with nil
1341
+ *
1342
+ * Note that an indent of less than zero will result in a tight one line output
1343
+ * unless the text in the XML fields contain new line characters.
1344
+ */
1345
+ static VALUE
1346
+ to_xml(int argc, VALUE *argv, VALUE self) {
1347
+ return dump(argc, argv, self);
1348
+ }
1349
+
1350
+ /* call-seq: to_file(file_path, obj, options) => Object
1337
1351
  *
1338
1352
  * Dumps an Object to the specified file.
1339
1353
  * - +file_path+ [String] file path to write the XML document to
@@ -1392,7 +1406,7 @@ void Init_ox() {
1392
1406
  rb_define_module_function(Ox, "sax_parse", sax_parse, -1);
1393
1407
  rb_define_module_function(Ox, "sax_html", sax_html, -1);
1394
1408
 
1395
- rb_define_module_function(Ox, "to_xml", dump, -1);
1409
+ rb_define_module_function(Ox, "to_xml", to_xml, -1);
1396
1410
  rb_define_module_function(Ox, "dump", dump, -1);
1397
1411
 
1398
1412
  rb_define_module_function(Ox, "load_file", load_file, -1);
@@ -1525,6 +1539,7 @@ void Init_ox() {
1525
1539
  symbolize_sym = ID2SYM(rb_intern("symbolize")); rb_gc_register_address(&symbolize_sym);
1526
1540
  tolerant_sym = ID2SYM(rb_intern("tolerant")); rb_gc_register_address(&tolerant_sym);
1527
1541
  trace_sym = ID2SYM(rb_intern("trace")); rb_gc_register_address(&trace_sym);
1542
+ with_cdata_sym = ID2SYM(rb_intern("with_cdata")); rb_gc_register_address(&with_cdata_sym);
1528
1543
  with_dtd_sym = ID2SYM(rb_intern("with_dtd")); rb_gc_register_address(&with_dtd_sym);
1529
1544
  with_instruct_sym = ID2SYM(rb_intern("with_instructions")); rb_gc_register_address(&with_instruct_sym);
1530
1545
  with_xml_sym = ID2SYM(rb_intern("with_xml")); rb_gc_register_address(&with_xml_sym);
@@ -1555,11 +1570,8 @@ void Init_ox() {
1555
1570
  rb_define _module_function(Ox, "cache8_test", cache8_test, 0);
1556
1571
  #endif
1557
1572
 
1558
- #if HAS_ENCODING_SUPPORT
1573
+ #if HAVE_RB_ENC_FIND
1559
1574
  ox_utf8_encoding = rb_enc_find("UTF-8");
1560
- #elif HAS_PRIVATE_ENCODING
1561
- ox_utf8_encoding = rb_str_new2("UTF-8");
1562
- rb_gc_register_address(&ox_utf8_encoding);
1563
1575
  #endif
1564
1576
  }
1565
1577
 
@@ -1580,7 +1592,7 @@ _ox_raise_error(const char *msg, const char *xml, const char *current, const cha
1580
1592
  xline++;
1581
1593
  }
1582
1594
  }
1583
- #if HAS_GC_GUARD
1595
+ #ifdef RB_GC_GUARD
1584
1596
  rb_gc_enable();
1585
1597
  #endif
1586
1598
  rb_raise(ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line);