libxml-ruby 1.1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. data/{CHANGES → HISTORY} +35 -0
  2. data/LICENSE +1 -0
  3. data/MANIFEST +165 -0
  4. data/{README → README.rdoc} +2 -2
  5. data/Rakefile +47 -147
  6. data/ext/libxml/libxml.c +17 -1
  7. data/ext/libxml/ruby_libxml.h +9 -1
  8. data/ext/libxml/ruby_xml_attr.c +3 -3
  9. data/ext/libxml/ruby_xml_attr_decl.c +32 -32
  10. data/ext/libxml/ruby_xml_attributes.c +1 -1
  11. data/ext/libxml/ruby_xml_cbg.c +1 -2
  12. data/ext/libxml/ruby_xml_document.c +26 -4
  13. data/ext/libxml/ruby_xml_dtd.c +3 -3
  14. data/ext/libxml/ruby_xml_encoding.c +92 -5
  15. data/ext/libxml/ruby_xml_encoding.h +4 -0
  16. data/ext/libxml/ruby_xml_namespace.c +2 -2
  17. data/ext/libxml/ruby_xml_node.c +14 -14
  18. data/ext/libxml/ruby_xml_parser_context.c +8 -8
  19. data/ext/libxml/ruby_xml_reader.c +98 -43
  20. data/ext/libxml/ruby_xml_sax2_handler.c +13 -1
  21. data/ext/libxml/ruby_xml_sax_parser.c +4 -5
  22. data/ext/libxml/ruby_xml_version.h +5 -5
  23. data/ext/libxml/ruby_xml_xpath_context.c +9 -6
  24. data/ext/libxml/ruby_xml_xpath_object.c +1 -1
  25. data/ext/vc/libxml_ruby.sln +4 -4
  26. data/lib/libxml.rb +29 -29
  27. data/lib/libxml/attr.rb +112 -110
  28. data/lib/libxml/attr_decl.rb +2 -0
  29. data/lib/libxml/attributes.rb +13 -11
  30. data/lib/libxml/document.rb +192 -190
  31. data/lib/libxml/error.rb +89 -87
  32. data/lib/libxml/hpricot.rb +77 -75
  33. data/lib/libxml/html_parser.rb +96 -94
  34. data/lib/libxml/namespace.rb +61 -59
  35. data/lib/libxml/namespaces.rb +37 -35
  36. data/lib/libxml/node.rb +398 -384
  37. data/lib/libxml/ns.rb +21 -19
  38. data/lib/libxml/parser.rb +366 -364
  39. data/lib/libxml/properties.rb +22 -20
  40. data/lib/libxml/reader.rb +2 -0
  41. data/lib/libxml/sax_callbacks.rb +179 -177
  42. data/lib/libxml/sax_parser.rb +57 -55
  43. data/lib/libxml/tree.rb +28 -26
  44. data/lib/libxml/xpath_object.rb +15 -13
  45. data/lib/xml.rb +16 -14
  46. data/lib/xml/libxml.rb +10 -8
  47. data/libxml-ruby.gemspec +50 -0
  48. data/script/benchmark/depixelate +634 -0
  49. data/script/benchmark/hamlet.xml +9055 -0
  50. data/script/benchmark/parsecount +170 -0
  51. data/script/benchmark/sock_entries.xml +507 -0
  52. data/script/benchmark/throughput +41 -0
  53. data/script/test +6 -0
  54. data/test/etc_doc_to_s.rb +21 -19
  55. data/test/ets_doc_file.rb +17 -15
  56. data/test/ets_doc_to_s.rb +23 -21
  57. data/test/ets_gpx.rb +28 -26
  58. data/test/ets_node_gc.rb +23 -21
  59. data/test/ets_tsr.rb +11 -9
  60. data/test/model/bands.iso-8859-1.xml +5 -0
  61. data/test/model/bands.utf-8.xml +5 -0
  62. data/test/rb-magic-comment.rb +33 -0
  63. data/test/tc_attr.rb +181 -170
  64. data/test/tc_attr_decl.rb +3 -1
  65. data/test/tc_attributes.rb +134 -132
  66. data/test/tc_deprecated_require.rb +13 -11
  67. data/test/tc_document.rb +119 -113
  68. data/test/tc_document_write.rb +186 -117
  69. data/test/tc_dtd.rb +125 -123
  70. data/test/tc_error.rb +3 -1
  71. data/test/tc_html_parser.rb +139 -137
  72. data/test/tc_namespace.rb +61 -58
  73. data/test/tc_namespaces.rb +176 -173
  74. data/test/tc_node.rb +257 -180
  75. data/test/tc_node_cdata.rb +51 -49
  76. data/test/tc_node_comment.rb +33 -30
  77. data/test/tc_node_copy.rb +42 -40
  78. data/test/tc_node_edit.rb +159 -157
  79. data/test/tc_node_text.rb +71 -69
  80. data/test/tc_node_write.rb +41 -16
  81. data/test/tc_node_xlink.rb +29 -26
  82. data/test/tc_parser.rb +335 -329
  83. data/test/tc_parser_context.rb +188 -185
  84. data/test/tc_properties.rb +39 -36
  85. data/test/tc_reader.rb +297 -283
  86. data/test/tc_relaxng.rb +54 -51
  87. data/test/tc_sax_parser.rb +275 -273
  88. data/test/tc_schema.rb +53 -51
  89. data/test/tc_traversal.rb +222 -220
  90. data/test/tc_xinclude.rb +21 -19
  91. data/test/tc_xml.rb +3 -1
  92. data/test/tc_xpath.rb +195 -193
  93. data/test/tc_xpath_context.rb +80 -78
  94. data/test/tc_xpath_expression.rb +38 -35
  95. data/test/tc_xpointer.rb +74 -72
  96. data/test/test_helper.rb +14 -0
  97. data/test/test_suite.rb +39 -33
  98. metadata +65 -105
  99. data/doc/css/normal.css +0 -182
  100. data/doc/img/raze-tiny.png +0 -0
  101. data/doc/img/red-cube.jpg +0 -0
  102. data/doc/img/xml-ruby.png +0 -0
  103. data/doc/index.xml +0 -43
  104. data/doc/install.xml +0 -77
  105. data/doc/layout.rhtml +0 -38
  106. data/doc/layout.xsl +0 -67
  107. data/doc/license.xml +0 -32
  108. data/doc/log/changelog.xml +0 -1324
  109. data/doc/log/changelog.xsl +0 -42
  110. data/ext/libxml/Makefile +0 -156
  111. data/ext/libxml/extconf.h +0 -5
  112. data/ext/libxml/libxml-ruby.so.a +0 -0
  113. data/ext/libxml/libxml.o +0 -0
  114. data/ext/libxml/libxml_ruby.so +0 -0
  115. data/ext/libxml/mkmf.log +0 -129
  116. data/ext/libxml/ruby_xml.o +0 -0
  117. data/ext/libxml/ruby_xml_attr.o +0 -0
  118. data/ext/libxml/ruby_xml_attr_decl.o +0 -0
  119. data/ext/libxml/ruby_xml_attributes.o +0 -0
  120. data/ext/libxml/ruby_xml_cbg.o +0 -0
  121. data/ext/libxml/ruby_xml_document.o +0 -0
  122. data/ext/libxml/ruby_xml_dtd.o +0 -0
  123. data/ext/libxml/ruby_xml_encoding.o +0 -0
  124. data/ext/libxml/ruby_xml_error.o +0 -0
  125. data/ext/libxml/ruby_xml_html_parser.o +0 -0
  126. data/ext/libxml/ruby_xml_html_parser_context.o +0 -0
  127. data/ext/libxml/ruby_xml_html_parser_options.o +0 -0
  128. data/ext/libxml/ruby_xml_input_cbg.o +0 -0
  129. data/ext/libxml/ruby_xml_io.o +0 -0
  130. data/ext/libxml/ruby_xml_namespace.o +0 -0
  131. data/ext/libxml/ruby_xml_namespaces.o +0 -0
  132. data/ext/libxml/ruby_xml_node.o +0 -0
  133. data/ext/libxml/ruby_xml_parser.o +0 -0
  134. data/ext/libxml/ruby_xml_parser_context.o +0 -0
  135. data/ext/libxml/ruby_xml_parser_options.o +0 -0
  136. data/ext/libxml/ruby_xml_reader.o +0 -0
  137. data/ext/libxml/ruby_xml_relaxng.o +0 -0
  138. data/ext/libxml/ruby_xml_sax2_handler.o +0 -0
  139. data/ext/libxml/ruby_xml_sax_parser.o +0 -0
  140. data/ext/libxml/ruby_xml_schema.o +0 -0
  141. data/ext/libxml/ruby_xml_xinclude.o +0 -0
  142. data/ext/libxml/ruby_xml_xpath.o +0 -0
  143. data/ext/libxml/ruby_xml_xpath_context.o +0 -0
  144. data/ext/libxml/ruby_xml_xpath_expression.o +0 -0
  145. data/ext/libxml/ruby_xml_xpath_object.o +0 -0
  146. data/ext/libxml/ruby_xml_xpointer.o +0 -0
@@ -9,4 +9,8 @@ extern VALUE mXMLEncoding;
9
9
 
10
10
  void rxml_init_encoding();
11
11
 
12
+ #ifdef HAVE_RUBY_ENCODING_H
13
+ VALUE rxml_xml_encoding_to_rb_encoding(VALUE klass, xmlCharEncoding xmlEncoding);
14
+ #endif
15
+
12
16
  #endif
@@ -98,7 +98,7 @@ static VALUE rxml_namespace_href_get(VALUE self)
98
98
  if (xns->href == NULL)
99
99
  return Qnil;
100
100
  else
101
- return rb_str_new2((const char*) xns->href);
101
+ return rxml_str_new2((const char*) xns->href, xns->context ? xns->context->encoding : NULL);
102
102
  }
103
103
 
104
104
  /*
@@ -133,7 +133,7 @@ static VALUE rxml_namespace_prefix_get(VALUE self)
133
133
  if (xns->prefix == NULL)
134
134
  return Qnil;
135
135
  else
136
- return rb_str_new2((const char*) xns->prefix);
136
+ return rxml_str_new2((const char*) xns->prefix, xns->context ? xns->context->encoding : NULL);
137
137
  }
138
138
 
139
139
  /*
@@ -279,7 +279,7 @@ static VALUE rxml_node_base_uri_get(VALUE self)
279
279
  base_uri = xmlNodeGetBase(xnode->doc, xnode);
280
280
  if (base_uri)
281
281
  {
282
- result = rb_str_new2((const char*) base_uri);
282
+ result = rxml_str_new2((const char*) base_uri, xnode->doc ? xnode->doc->encoding : NULL);
283
283
  xmlFree(base_uri);
284
284
  }
285
285
 
@@ -323,7 +323,7 @@ static VALUE rxml_node_content_get(VALUE self)
323
323
  content = xmlNodeGetContent(xnode);
324
324
  if (content)
325
325
  {
326
- result = rb_str_new2((const char *) content);
326
+ result = rxml_str_new2((const char *) content, xnode->doc ? xnode->doc->encoding : NULL);
327
327
  xmlFree(content);
328
328
  }
329
329
 
@@ -370,7 +370,7 @@ static VALUE rxml_node_content_stripped_get(VALUE self)
370
370
  content = xmlNodeGetContent(xnode);
371
371
  if (content)
372
372
  {
373
- result = rb_str_new2((const char*) content);
373
+ result = rxml_str_new2((const char*) content, xnode->doc ? xnode->doc->encoding : NULL);
374
374
  xmlFree(content);
375
375
  }
376
376
  return (result);
@@ -538,7 +538,7 @@ static VALUE rxml_node_to_s(int argc, VALUE *argv, VALUE self)
538
538
 
539
539
  int level = 0;
540
540
  int indent = 1;
541
- const char *xencoding = NULL;
541
+ const char *xencoding = "UTF-8";
542
542
 
543
543
  rb_scan_args(argc, argv, "01", &options);
544
544
 
@@ -572,9 +572,9 @@ static VALUE rxml_node_to_s(int argc, VALUE *argv, VALUE self)
572
572
  xmlOutputBufferFlush(output);
573
573
 
574
574
  if (output->conv)
575
- result = rb_str_new2((const char*) output->conv->content);
575
+ result = rxml_str_new2((const char*) output->conv->content, xencoding);
576
576
  else
577
- result = rb_str_new2((const char*) output->buffer->content);
577
+ result = rxml_str_new2((const char*) output->buffer->content, xencoding);
578
578
 
579
579
  xmlOutputBufferClose(output);
580
580
 
@@ -678,7 +678,7 @@ static VALUE rxml_node_lang_get(VALUE self)
678
678
 
679
679
  if (lang)
680
680
  {
681
- result = rb_str_new2((const char*) lang);
681
+ result = rxml_str_new2((const char*) lang, xnode->doc ? xnode->doc->encoding : NULL);
682
682
  xmlFree(lang);
683
683
  }
684
684
 
@@ -811,11 +811,11 @@ static VALUE rxml_node_xlink_type_name(VALUE self)
811
811
  case XLINK_TYPE_NONE:
812
812
  return (Qnil);
813
813
  case XLINK_TYPE_SIMPLE:
814
- return (rb_str_new2("simple"));
814
+ return (rxml_str_new2("simple", xnode->doc ? xnode->doc->encoding : NULL));
815
815
  case XLINK_TYPE_EXTENDED:
816
- return (rb_str_new2("extended"));
816
+ return (rxml_str_new2("extended", xnode->doc ? xnode->doc->encoding : NULL));
817
817
  case XLINK_TYPE_EXTENDED_SET:
818
- return (rb_str_new2("extended_set"));
818
+ return (rxml_str_new2("extended_set", xnode->doc ? xnode->doc->encoding : NULL));
819
819
  default:
820
820
  rb_fatal("Unknowng xlink type, %d", xlt);
821
821
  }
@@ -866,7 +866,7 @@ static VALUE rxml_node_name_get(VALUE self)
866
866
  if (xnode->name == NULL)
867
867
  return (Qnil);
868
868
  else
869
- return (rb_str_new2((const char*) name));
869
+ return (rxml_str_new2((const char*) name, xnode->doc ? xnode->doc->encoding : NULL));
870
870
  }
871
871
 
872
872
  /*
@@ -958,7 +958,7 @@ static VALUE rxml_node_path(VALUE self)
958
958
  if (path == NULL)
959
959
  return (Qnil);
960
960
  else
961
- return (rb_str_new2((const char*) path));
961
+ return (rxml_str_new2((const char*) path, xnode->doc ? xnode->doc->encoding : NULL));
962
962
  }
963
963
 
964
964
  /*
@@ -1233,9 +1233,9 @@ static VALUE rxml_node_space_preserve_set(VALUE self, VALUE bool)
1233
1233
  Data_Get_Struct(self, xmlNode, xnode);
1234
1234
 
1235
1235
  if (TYPE(bool) == T_FALSE)
1236
- xmlNodeSetSpacePreserve(xnode, 1);
1237
- else
1238
1236
  xmlNodeSetSpacePreserve(xnode, 0);
1237
+ else
1238
+ xmlNodeSetSpacePreserve(xnode, 1);
1239
1239
 
1240
1240
  return (Qnil);
1241
1241
  }
@@ -190,7 +190,7 @@ static VALUE rxml_parser_context_base_uri_get(VALUE self)
190
190
  Data_Get_Struct(self, xmlParserCtxt, ctxt);
191
191
 
192
192
  if (ctxt->input && ctxt->input->filename)
193
- return rb_str_new2(ctxt->input->filename);
193
+ return rxml_str_new2(ctxt->input->filename, ctxt->encoding);
194
194
  else
195
195
  return Qnil;
196
196
  }
@@ -231,7 +231,7 @@ static VALUE rxml_parser_context_data_directory_get(VALUE self)
231
231
  if (ctxt->directory == NULL)
232
232
  return (Qnil);
233
233
  else
234
- return (rb_str_new2(ctxt->directory));
234
+ return (rxml_str_new2(ctxt->directory, ctxt->encoding));
235
235
  }
236
236
 
237
237
  /*
@@ -489,7 +489,7 @@ static VALUE rxml_parser_context_name_node_get(VALUE self)
489
489
  if (ctxt->name == NULL)
490
490
  return (Qnil);
491
491
  else
492
- return (rb_str_new2((const char*) ctxt->name));
492
+ return (rxml_str_new2((const char*) ctxt->name, ctxt->encoding));
493
493
  }
494
494
 
495
495
  /*
@@ -516,7 +516,7 @@ static VALUE rxml_parser_context_name_tab_get(VALUE self)
516
516
  if (ctxt->nameTab[i] == NULL)
517
517
  continue;
518
518
  else
519
- rb_ary_push(tab_ary, rb_str_new2((const char*) ctxt->nameTab[i]));
519
+ rb_ary_push(tab_ary, rxml_str_new2((const char*) ctxt->nameTab[i], ctxt->encoding));
520
520
  }
521
521
 
522
522
  return (tab_ary);
@@ -782,7 +782,7 @@ static VALUE rxml_parser_context_subset_name_get(VALUE self)
782
782
  if (ctxt->intSubName == NULL)
783
783
  return (Qnil);
784
784
  else
785
- return (rb_str_new2((const char*) ctxt->intSubName));
785
+ return (rxml_str_new2((const char*) ctxt->intSubName, ctxt->encoding));
786
786
  }
787
787
 
788
788
  /*
@@ -801,7 +801,7 @@ static VALUE rxml_parser_context_subset_external_uri_get(VALUE self)
801
801
  if (ctxt->extSubURI == NULL)
802
802
  return (Qnil);
803
803
  else
804
- return (rb_str_new2((const char*) ctxt->extSubURI));
804
+ return (rxml_str_new2((const char*) ctxt->extSubURI, ctxt->encoding));
805
805
  }
806
806
 
807
807
  /*
@@ -820,7 +820,7 @@ static VALUE rxml_parser_context_subset_external_system_id_get(VALUE self)
820
820
  if (ctxt->extSubSystem == NULL)
821
821
  return (Qnil);
822
822
  else
823
- return (rb_str_new2((const char*) ctxt->extSubSystem));
823
+ return (rxml_str_new2((const char*) ctxt->extSubSystem, ctxt->encoding));
824
824
  }
825
825
 
826
826
  /*
@@ -905,7 +905,7 @@ static VALUE rxml_parser_context_version_get(VALUE self)
905
905
  if (ctxt->version == NULL)
906
906
  return (Qnil);
907
907
  else
908
- return (rb_str_new2((const char*) ctxt->version));
908
+ return (rxml_str_new2((const char*) ctxt->version, ctxt->encoding));
909
909
  }
910
910
 
911
911
  /*
@@ -238,6 +238,7 @@ static VALUE rxml_reader_string(int argc, VALUE *argv, VALUE klass)
238
238
  VALUE encoding = Qnil;
239
239
  VALUE parserOptions = Qnil;
240
240
 
241
+ int foo;
241
242
  Check_Type(options, T_HASH);
242
243
 
243
244
  baseurl = rb_hash_aref(options, BASE_URI_SYMBOL);
@@ -458,8 +459,19 @@ static VALUE rxml_reader_read_attr_value(VALUE self)
458
459
  */
459
460
  static VALUE rxml_reader_read_inner_xml(VALUE self)
460
461
  {
461
- const xmlChar *result = xmlTextReaderReadInnerXml(rxml_text_reader_get(self));
462
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
462
+ VALUE result = Qnil;
463
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
464
+
465
+ xmlChar *xml = xmlTextReaderReadInnerXml(xReader);
466
+
467
+ if (xml != NULL)
468
+ {
469
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
470
+ result = rxml_str_new2((const char*) xml, xencoding);
471
+ xmlFree(xml);
472
+ }
473
+
474
+ return result;
463
475
  }
464
476
 
465
477
  /*
@@ -473,8 +485,19 @@ static VALUE rxml_reader_read_inner_xml(VALUE self)
473
485
  */
474
486
  static VALUE rxml_reader_read_outer_xml(VALUE self)
475
487
  {
476
- const xmlChar *result = xmlTextReaderReadOuterXml(rxml_text_reader_get(self));
477
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
488
+ VALUE result = Qnil;
489
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
490
+
491
+ xmlChar *xml = xmlTextReaderReadOuterXml(xReader);
492
+
493
+ if (xml != NULL)
494
+ {
495
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
496
+ result = rxml_str_new2((const char*) xml, xencoding);
497
+ xmlFree(xml);
498
+ }
499
+
500
+ return result;
478
501
  }
479
502
 
480
503
  /*
@@ -499,8 +522,19 @@ static VALUE rxml_reader_read_state(VALUE self)
499
522
  */
500
523
  static VALUE rxml_reader_read_string(VALUE self)
501
524
  {
502
- const xmlChar *result = xmlTextReaderReadString(rxml_text_reader_get(self));
503
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
525
+ VALUE result = Qnil;
526
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
527
+
528
+ xmlChar *xml = xmlTextReaderReadString(xReader);
529
+
530
+ if (xml != NULL)
531
+ {
532
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
533
+ result = rxml_str_new2((const char*) xml, xencoding);
534
+ xmlFree(xml);
535
+ }
536
+
537
+ return result;
504
538
  }
505
539
 
506
540
  /*
@@ -549,8 +583,11 @@ rxml_reader_schema_validate(VALUE self, VALUE xsd)
549
583
  */
550
584
  static VALUE rxml_reader_name(VALUE self)
551
585
  {
552
- const xmlChar *result = xmlTextReaderConstName(rxml_text_reader_get(self));
553
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
586
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
587
+ const xmlChar *result = xmlTextReaderConstName(xReader);
588
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
589
+
590
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
554
591
  }
555
592
 
556
593
  /*
@@ -561,8 +598,11 @@ static VALUE rxml_reader_name(VALUE self)
561
598
  */
562
599
  static VALUE rxml_reader_local_name(VALUE self)
563
600
  {
564
- const xmlChar *result = xmlTextReaderConstLocalName(rxml_text_reader_get(self));
565
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
601
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
602
+ const xmlChar *result = xmlTextReaderConstLocalName(xReader);
603
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
604
+
605
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
566
606
  }
567
607
 
568
608
  /*
@@ -610,8 +650,11 @@ static VALUE rxml_reader_encoding(VALUE self)
610
650
  */
611
651
  static VALUE rxml_reader_base_uri(VALUE self)
612
652
  {
613
- const xmlChar *result = xmlTextReaderConstBaseUri(rxml_text_reader_get(self));
614
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
653
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
654
+ const xmlChar *result = xmlTextReaderConstBaseUri(xReader);
655
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
656
+
657
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
615
658
  }
616
659
 
617
660
  /*
@@ -622,8 +665,11 @@ static VALUE rxml_reader_base_uri(VALUE self)
622
665
  */
623
666
  static VALUE rxml_reader_namespace_uri(VALUE self)
624
667
  {
625
- const xmlChar *result = xmlTextReaderConstNamespaceUri(rxml_text_reader_get(self));
626
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
668
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
669
+ const xmlChar *result = xmlTextReaderConstNamespaceUri(xReader);
670
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
671
+
672
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
627
673
  }
628
674
 
629
675
  /*
@@ -634,8 +680,11 @@ static VALUE rxml_reader_namespace_uri(VALUE self)
634
680
  */
635
681
  static VALUE rxml_reader_value(VALUE self)
636
682
  {
637
- const xmlChar *result = xmlTextReaderConstValue(rxml_text_reader_get(self));
638
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
683
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
684
+ const xmlChar *result = xmlTextReaderConstValue(xReader);
685
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
686
+
687
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
639
688
  }
640
689
 
641
690
  /*
@@ -646,8 +695,11 @@ static VALUE rxml_reader_value(VALUE self)
646
695
  */
647
696
  static VALUE rxml_reader_prefix(VALUE self)
648
697
  {
649
- const xmlChar *result = xmlTextReaderConstPrefix(rxml_text_reader_get(self));
650
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
698
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
699
+ const xmlChar *result = xmlTextReaderConstPrefix(xReader);
700
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
701
+
702
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
651
703
  }
652
704
 
653
705
  /*
@@ -696,8 +748,11 @@ static VALUE rxml_reader_standalone(VALUE self)
696
748
  */
697
749
  static VALUE rxml_reader_xml_lang(VALUE self)
698
750
  {
699
- const xmlChar *result = xmlTextReaderConstXmlLang(rxml_text_reader_get(self));
700
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
751
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
752
+ const xmlChar *result = xmlTextReaderConstXmlLang(xReader);
753
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
754
+
755
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
701
756
  }
702
757
 
703
758
  /*
@@ -708,8 +763,11 @@ static VALUE rxml_reader_xml_lang(VALUE self)
708
763
  */
709
764
  static VALUE rxml_reader_xml_version(VALUE self)
710
765
  {
711
- const xmlChar *result = xmlTextReaderConstXmlVersion(rxml_text_reader_get(self));
712
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
766
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
767
+ const xmlChar *result = xmlTextReaderConstXmlVersion(xReader);
768
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
769
+
770
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
713
771
  }
714
772
 
715
773
  /*
@@ -747,18 +805,19 @@ static VALUE rxml_reader_attribute(VALUE self, VALUE key)
747
805
  {
748
806
  xmlTextReaderPtr reader;
749
807
  xmlChar *attr;
808
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
809
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
750
810
 
751
- reader = rxml_text_reader_get(self);
752
811
 
753
812
  if (TYPE(key) == T_FIXNUM)
754
813
  {
755
- attr = xmlTextReaderGetAttributeNo(reader, FIX2INT(key));
814
+ attr = xmlTextReaderGetAttributeNo(xReader, FIX2INT(key));
756
815
  }
757
816
  else
758
817
  {
759
- attr = xmlTextReaderGetAttribute(reader, (const xmlChar *) StringValueCStr(key));
818
+ attr = xmlTextReaderGetAttribute(xReader, (const xmlChar *) StringValueCStr(key));
760
819
  }
761
- return (attr == NULL ? Qnil : rb_str_new2((const char*)attr));
820
+ return (attr == NULL ? Qnil : rxml_str_new2(attr, xencoding));
762
821
  }
763
822
 
764
823
  /*
@@ -770,9 +829,11 @@ static VALUE rxml_reader_attribute(VALUE self, VALUE key)
770
829
  */
771
830
  static VALUE rxml_reader_lookup_namespace(VALUE self, VALUE prefix)
772
831
  {
773
- const xmlChar *result = xmlTextReaderLookupNamespace(rxml_text_reader_get(
774
- self), (const xmlChar *) StringValueCStr(prefix));
775
- return (result == NULL ? Qnil : rb_str_new2((const char*)result));
832
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
833
+ const xmlChar *result = xmlTextReaderLookupNamespace(xReader, (const xmlChar *) StringValueCStr(prefix));
834
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
835
+
836
+ return (result == NULL ? Qnil : rxml_str_new2(result, xencoding));
776
837
  }
777
838
 
778
839
  /*
@@ -786,25 +847,19 @@ static VALUE rxml_reader_lookup_namespace(VALUE self, VALUE prefix)
786
847
  */
787
848
  static VALUE rxml_reader_expand(VALUE self)
788
849
  {
789
- xmlNodePtr node;
790
- xmlDocPtr doc;
850
+ xmlNodePtr node, nodec;
791
851
  xmlTextReaderPtr reader = rxml_text_reader_get(self);
792
852
  node = xmlTextReaderExpand(reader);
793
853
 
794
854
  if (!node)
795
855
  return Qnil;
796
-
797
- /* Okay this is tricky. By accessing the returned node, we
798
- take ownership of the reader's document. Thus we need to
799
- tell the reader to not free it. Otherwise it will be
800
- freed twice - once when the Ruby document wrapper goes
801
- out of scope and once when the reader goes out of scope. */
802
-
803
- xmlTextReaderPreserve(reader);
804
- doc = xmlTextReaderCurrentDoc(reader);
805
- rxml_document_wrap(doc);
806
-
807
- return rxml_node_wrap(node);
856
+ else {
857
+ nodec = xmlCopyNode(node, 1);
858
+ if (!nodec)
859
+ return Qnil;
860
+ else
861
+ return rxml_node_wrap(nodec);
862
+ }
808
863
  }
809
864
 
810
865
  #if LIBXML_VERSION >= 20618
@@ -253,7 +253,19 @@ static void start_element_ns_callback(void *ctx,
253
253
 
254
254
  static void structured_error_callback(void *ctx, xmlErrorPtr xerror)
255
255
  {
256
- VALUE handler = (VALUE) ctx;
256
+ /* Older versions of Libxml will pass a NULL context from the sax parser. Fixed on
257
+ Feb 23, 2011. See:
258
+
259
+ http://git.gnome.org/browse/libxml2/commit/?id=241d4a1069e6bedd0ee2295d7b43858109c1c6d1 */
260
+
261
+ VALUE handler;
262
+
263
+ #if LIBXML_VERSION <= 20708
264
+ xmlParserCtxtPtr ctxt = (xmlParserCtxt*)(xerror->ctxt);
265
+ ctx = ctxt->userData;
266
+ #endif
267
+
268
+ handler = (VALUE) ctx;
257
269
 
258
270
  if (handler != Qnil)
259
271
  {