ox 2.12.1 → 2.14.0

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