nokogiri 1.11.0.rc2 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/LICENSE-DEPENDENCIES.md +1015 -947
  4. data/LICENSE.md +1 -1
  5. data/README.md +171 -94
  6. data/ext/nokogiri/depend +37 -358
  7. data/ext/nokogiri/extconf.rb +581 -374
  8. data/ext/nokogiri/html_document.c +78 -82
  9. data/ext/nokogiri/html_element_description.c +84 -71
  10. data/ext/nokogiri/html_entity_lookup.c +21 -16
  11. data/ext/nokogiri/html_sax_parser_context.c +69 -66
  12. data/ext/nokogiri/html_sax_push_parser.c +42 -34
  13. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  14. data/ext/nokogiri/nokogiri.c +192 -93
  15. data/ext/nokogiri/nokogiri.h +177 -98
  16. data/ext/nokogiri/test_global_handlers.c +40 -0
  17. data/ext/nokogiri/xml_attr.c +15 -15
  18. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  19. data/ext/nokogiri/xml_cdata.c +13 -18
  20. data/ext/nokogiri/xml_comment.c +19 -26
  21. data/ext/nokogiri/xml_document.c +225 -163
  22. data/ext/nokogiri/xml_document_fragment.c +13 -15
  23. data/ext/nokogiri/xml_dtd.c +54 -48
  24. data/ext/nokogiri/xml_element_content.c +30 -27
  25. data/ext/nokogiri/xml_element_decl.c +22 -22
  26. data/ext/nokogiri/xml_encoding_handler.c +17 -11
  27. data/ext/nokogiri/xml_entity_decl.c +32 -30
  28. data/ext/nokogiri/xml_entity_reference.c +16 -18
  29. data/ext/nokogiri/xml_namespace.c +56 -49
  30. data/ext/nokogiri/xml_node.c +338 -286
  31. data/ext/nokogiri/xml_node_set.c +168 -156
  32. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  33. data/ext/nokogiri/xml_reader.c +191 -157
  34. data/ext/nokogiri/xml_relax_ng.c +52 -28
  35. data/ext/nokogiri/xml_sax_parser.c +118 -118
  36. data/ext/nokogiri/xml_sax_parser_context.c +103 -86
  37. data/ext/nokogiri/xml_sax_push_parser.c +36 -27
  38. data/ext/nokogiri/xml_schema.c +95 -47
  39. data/ext/nokogiri/xml_syntax_error.c +42 -21
  40. data/ext/nokogiri/xml_text.c +13 -17
  41. data/ext/nokogiri/xml_xpath_context.c +206 -123
  42. data/ext/nokogiri/xslt_stylesheet.c +158 -161
  43. data/lib/nokogiri.rb +4 -8
  44. data/lib/nokogiri/css/parser.rb +62 -62
  45. data/lib/nokogiri/css/parser.y +2 -2
  46. data/lib/nokogiri/css/xpath_visitor.rb +70 -42
  47. data/lib/nokogiri/extension.rb +26 -0
  48. data/lib/nokogiri/html/document.rb +12 -26
  49. data/lib/nokogiri/html/document_fragment.rb +15 -15
  50. data/lib/nokogiri/version.rb +2 -148
  51. data/lib/nokogiri/version/constant.rb +5 -0
  52. data/lib/nokogiri/version/info.rb +205 -0
  53. data/lib/nokogiri/xml/builder.rb +2 -2
  54. data/lib/nokogiri/xml/document.rb +48 -18
  55. data/lib/nokogiri/xml/document_fragment.rb +4 -6
  56. data/lib/nokogiri/xml/node.rb +88 -69
  57. data/lib/nokogiri/xml/parse_options.rb +6 -0
  58. data/lib/nokogiri/xml/reader.rb +2 -9
  59. data/lib/nokogiri/xml/relax_ng.rb +6 -2
  60. data/lib/nokogiri/xml/schema.rb +12 -4
  61. data/lib/nokogiri/xml/searchable.rb +3 -1
  62. data/lib/nokogiri/xml/xpath.rb +1 -3
  63. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  64. data/patches/libxml2/0006-htmlParseComment-treat-as-if-it-closed-the-comment.patch +73 -0
  65. data/patches/libxml2/0007-use-new-htmlParseLookupCommentEnd-to-find-comment-en.patch +103 -0
  66. data/patches/libxml2/0008-use-glibc-strlen.patch +53 -0
  67. data/patches/libxml2/0009-avoid-isnan-isinf.patch +81 -0
  68. data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +70 -0
  69. metadata +85 -155
  70. data/ext/nokogiri/html_document.h +0 -10
  71. data/ext/nokogiri/html_element_description.h +0 -10
  72. data/ext/nokogiri/html_entity_lookup.h +0 -8
  73. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  74. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  75. data/ext/nokogiri/xml_attr.h +0 -9
  76. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  77. data/ext/nokogiri/xml_cdata.h +0 -9
  78. data/ext/nokogiri/xml_comment.h +0 -9
  79. data/ext/nokogiri/xml_document.h +0 -23
  80. data/ext/nokogiri/xml_document_fragment.h +0 -10
  81. data/ext/nokogiri/xml_dtd.h +0 -10
  82. data/ext/nokogiri/xml_element_content.h +0 -10
  83. data/ext/nokogiri/xml_element_decl.h +0 -9
  84. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  85. data/ext/nokogiri/xml_entity_decl.h +0 -10
  86. data/ext/nokogiri/xml_entity_reference.h +0 -9
  87. data/ext/nokogiri/xml_io.c +0 -61
  88. data/ext/nokogiri/xml_io.h +0 -11
  89. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  90. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  91. data/ext/nokogiri/xml_namespace.h +0 -14
  92. data/ext/nokogiri/xml_node.h +0 -13
  93. data/ext/nokogiri/xml_node_set.h +0 -12
  94. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  95. data/ext/nokogiri/xml_reader.h +0 -10
  96. data/ext/nokogiri/xml_relax_ng.h +0 -9
  97. data/ext/nokogiri/xml_sax_parser.h +0 -39
  98. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  99. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  100. data/ext/nokogiri/xml_schema.h +0 -9
  101. data/ext/nokogiri/xml_syntax_error.h +0 -13
  102. data/ext/nokogiri/xml_text.h +0 -9
  103. data/ext/nokogiri/xml_xpath_context.h +0 -10
  104. data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -0,0 +1,40 @@
1
+ #include <nokogiri.h>
2
+
3
+ static VALUE foreign_error_handler_block = Qnil;
4
+
5
+ static void
6
+ foreign_error_handler(void *user_data, xmlErrorPtr c_error)
7
+ {
8
+ rb_funcall(foreign_error_handler_block, rb_intern("call"), 0);
9
+ }
10
+
11
+ /*
12
+ * call-seq:
13
+ * __foreign_error_handler { ... } -> nil
14
+ *
15
+ * Override libxml2's global error handlers to call the block. This method thus has very little
16
+ * value except to test that Nokogiri is properly setting error handlers elsewhere in the code. See
17
+ * test/helper.rb for how this is being used.
18
+ */
19
+ static VALUE
20
+ rb_foreign_error_handler(VALUE klass)
21
+ {
22
+ rb_need_block();
23
+ foreign_error_handler_block = rb_block_proc();
24
+ xmlSetStructuredErrorFunc(NULL, foreign_error_handler);
25
+ return Qnil;
26
+ }
27
+
28
+ /*
29
+ * Document-module: Nokogiri::Test
30
+ *
31
+ * The Nokogiri::Test module should only be used for testing Nokogiri.
32
+ * Do NOT use this outside of the Nokogiri test suite.
33
+ */
34
+ void
35
+ noko_init_test_global_handlers()
36
+ {
37
+ VALUE mNokogiriTest = rb_define_module_under(mNokogiri, "Test");
38
+
39
+ rb_define_singleton_method(mNokogiriTest, "__foreign_error_handler", rb_foreign_error_handler, 0);
40
+ }
@@ -1,4 +1,6 @@
1
- #include <xml_attr.h>
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlAttr;
2
4
 
3
5
  /*
4
6
  * call-seq:
@@ -7,7 +9,8 @@
7
9
  * Set the value for this Attr to +content+. Use `nil` to remove the value
8
10
  * (e.g., a HTML boolean attribute).
9
11
  */
10
- static VALUE set_value(VALUE self, VALUE content)
12
+ static VALUE
13
+ set_value(VALUE self, VALUE content)
11
14
  {
12
15
  xmlAttrPtr attr;
13
16
  xmlChar *value;
@@ -49,7 +52,8 @@ static VALUE set_value(VALUE self, VALUE content)
49
52
  *
50
53
  * Create a new Attr element on the +document+ with +name+
51
54
  */
52
- static VALUE new(int argc, VALUE *argv, VALUE klass)
55
+ static VALUE
56
+ new (int argc, VALUE *argv, VALUE klass)
53
57
  {
54
58
  xmlDocPtr xml_doc;
55
59
  VALUE document;
@@ -72,9 +76,9 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
72
76
  NULL
73
77
  );
74
78
 
75
- nokogiri_root_node((xmlNodePtr)node);
79
+ noko_xml_document_pin_node((xmlNodePtr)node);
76
80
 
77
- rb_node = Nokogiri_wrap_xml_node(klass, (xmlNodePtr)node);
81
+ rb_node = noko_xml_node_wrap(klass, (xmlNodePtr)node);
78
82
  rb_obj_call_init(rb_node, argc, argv);
79
83
 
80
84
  if (rb_block_given_p()) {
@@ -84,20 +88,16 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
84
88
  return rb_node;
85
89
  }
86
90
 
87
- VALUE cNokogiriXmlAttr;
88
- void init_xml_attr()
91
+ void
92
+ noko_init_xml_attr()
89
93
  {
90
- VALUE nokogiri = rb_define_module("Nokogiri");
91
- VALUE xml = rb_define_module_under(nokogiri, "XML");
92
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
93
-
94
+ assert(cNokogiriXmlNode);
94
95
  /*
95
96
  * Attr represents a Attr node in an xml document.
96
97
  */
97
- VALUE klass = rb_define_class_under(xml, "Attr", node);
98
+ cNokogiriXmlAttr = rb_define_class_under(mNokogiriXml, "Attr", cNokogiriXmlNode);
98
99
 
99
- cNokogiriXmlAttr = klass;
100
+ rb_define_singleton_method(cNokogiriXmlAttr, "new", new, -1);
100
101
 
101
- rb_define_singleton_method(klass, "new", new, -1);
102
- rb_define_method(klass, "value=", set_value, 1);
102
+ rb_define_method(cNokogiriXmlAttr, "value=", set_value, 1);
103
103
  }
@@ -1,4 +1,6 @@
1
- #include <xml_attribute_decl.h>
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlAttributeDecl;
2
4
 
3
5
  /*
4
6
  * call-seq:
@@ -6,7 +8,8 @@
6
8
  *
7
9
  * The attribute_type for this AttributeDecl
8
10
  */
9
- static VALUE attribute_type(VALUE self)
11
+ static VALUE
12
+ attribute_type(VALUE self)
10
13
  {
11
14
  xmlAttributePtr node;
12
15
  Data_Get_Struct(self, xmlAttribute, node);
@@ -19,12 +22,13 @@ static VALUE attribute_type(VALUE self)
19
22
  *
20
23
  * The default value
21
24
  */
22
- static VALUE default_value(VALUE self)
25
+ static VALUE
26
+ default_value(VALUE self)
23
27
  {
24
28
  xmlAttributePtr node;
25
29
  Data_Get_Struct(self, xmlAttribute, node);
26
30
 
27
- if(node->defaultValue) return NOKOGIRI_STR_NEW2(node->defaultValue);
31
+ if (node->defaultValue) { return NOKOGIRI_STR_NEW2(node->defaultValue); }
28
32
  return Qnil;
29
33
  }
30
34
 
@@ -34,7 +38,8 @@ static VALUE default_value(VALUE self)
34
38
  *
35
39
  * An enumeration of possible values
36
40
  */
37
- static VALUE enumeration(VALUE self)
41
+ static VALUE
42
+ enumeration(VALUE self)
38
43
  {
39
44
  xmlAttributePtr node;
40
45
  xmlEnumerationPtr enm;
@@ -45,7 +50,7 @@ static VALUE enumeration(VALUE self)
45
50
  list = rb_ary_new();
46
51
  enm = node->tree;
47
52
 
48
- while(enm) {
53
+ while (enm) {
49
54
  rb_ary_push(list, NOKOGIRI_STR_NEW2(enm->name));
50
55
  enm = enm->next;
51
56
  }
@@ -53,18 +58,13 @@ static VALUE enumeration(VALUE self)
53
58
  return list;
54
59
  }
55
60
 
56
- VALUE cNokogiriXmlAttributeDecl;
57
-
58
- void init_xml_attribute_decl()
61
+ void
62
+ noko_init_xml_attribute_decl()
59
63
  {
60
- VALUE nokogiri = rb_define_module("Nokogiri");
61
- VALUE xml = rb_define_module_under(nokogiri, "XML");
62
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
63
- VALUE klass = rb_define_class_under(xml, "AttributeDecl", node);
64
-
65
- cNokogiriXmlAttributeDecl = klass;
64
+ assert(cNokogiriXmlNode);
65
+ cNokogiriXmlAttributeDecl = rb_define_class_under(mNokogiriXml, "AttributeDecl", cNokogiriXmlNode);
66
66
 
67
- rb_define_method(klass, "attribute_type", attribute_type, 0);
68
- rb_define_method(klass, "default", default_value, 0);
69
- rb_define_method(klass, "enumeration", enumeration, 0);
67
+ rb_define_method(cNokogiriXmlAttributeDecl, "attribute_type", attribute_type, 0);
68
+ rb_define_method(cNokogiriXmlAttributeDecl, "default", default_value, 0);
69
+ rb_define_method(cNokogiriXmlAttributeDecl, "enumeration", enumeration, 0);
70
70
  }
@@ -1,4 +1,6 @@
1
- #include <xml_cdata.h>
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlCData;
2
4
 
3
5
  /*
4
6
  * call-seq:
@@ -9,7 +11,8 @@
9
11
  * If +content+ cannot be implicitly converted to a string, this method will
10
12
  * raise a TypeError exception.
11
13
  */
12
- static VALUE new(int argc, VALUE *argv, VALUE klass)
14
+ static VALUE
15
+ new (int argc, VALUE *argv, VALUE klass)
13
16
  {
14
17
  xmlDocPtr xml_doc;
15
18
  xmlNodePtr node;
@@ -31,32 +34,24 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
31
34
 
32
35
  node = xmlNewCDataBlock(xml_doc->doc, content_str, content_str_len);
33
36
 
34
- nokogiri_root_node(node);
37
+ noko_xml_document_pin_node(node);
35
38
 
36
- rb_node = Nokogiri_wrap_xml_node(klass, node);
39
+ rb_node = noko_xml_node_wrap(klass, node);
37
40
  rb_obj_call_init(rb_node, argc, argv);
38
41
 
39
- if(rb_block_given_p()) { rb_yield(rb_node); }
42
+ if (rb_block_given_p()) { rb_yield(rb_node); }
40
43
 
41
44
  return rb_node;
42
45
  }
43
46
 
44
- VALUE cNokogiriXmlCData;
45
- void init_xml_cdata()
47
+ void
48
+ noko_init_xml_cdata()
46
49
  {
47
- VALUE nokogiri = rb_define_module("Nokogiri");
48
- VALUE xml = rb_define_module_under(nokogiri, "XML");
49
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
50
- VALUE char_data = rb_define_class_under(xml, "CharacterData", node);
51
- VALUE text = rb_define_class_under(xml, "Text", char_data);
52
-
50
+ assert(cNokogiriXmlText);
53
51
  /*
54
52
  * CData represents a CData node in an xml document.
55
53
  */
56
- VALUE klass = rb_define_class_under(xml, "CDATA", text);
57
-
58
-
59
- cNokogiriXmlCData = klass;
54
+ cNokogiriXmlCData = rb_define_class_under(mNokogiriXml, "CDATA", cNokogiriXmlText);
60
55
 
61
- rb_define_singleton_method(klass, "new", new, -1);
56
+ rb_define_singleton_method(cNokogiriXmlCData, "new", new, -1);
62
57
  }
@@ -1,4 +1,6 @@
1
- #include <xml_comment.h>
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlComment;
2
4
 
3
5
  static ID document_id ;
4
6
 
@@ -9,7 +11,8 @@ static ID document_id ;
9
11
  * Create a new Comment element on the +document+ with +content+.
10
12
  * Alternatively, if a +node+ is passed, the +node+'s document is used.
11
13
  */
12
- static VALUE new(int argc, VALUE *argv, VALUE klass)
14
+ static VALUE
15
+ new (int argc, VALUE *argv, VALUE klass)
13
16
  {
14
17
  xmlDocPtr xml_doc;
15
18
  xmlNodePtr node;
@@ -20,50 +23,40 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
20
23
 
21
24
  rb_scan_args(argc, argv, "2*", &document, &content, &rest);
22
25
 
23
- if (rb_obj_is_kind_of(document, cNokogiriXmlNode))
24
- {
26
+ if (rb_obj_is_kind_of(document, cNokogiriXmlNode)) {
25
27
  document = rb_funcall(document, document_id, 0);
26
- }
27
- else if ( !rb_obj_is_kind_of(document, cNokogiriXmlDocument)
28
- && !rb_obj_is_kind_of(document, cNokogiriXmlDocumentFragment))
29
- {
28
+ } else if (!rb_obj_is_kind_of(document, cNokogiriXmlDocument)
29
+ && !rb_obj_is_kind_of(document, cNokogiriXmlDocumentFragment)) {
30
30
  rb_raise(rb_eArgError, "first argument must be a XML::Document or XML::Node");
31
31
  }
32
32
 
33
33
  Data_Get_Struct(document, xmlDoc, xml_doc);
34
34
 
35
35
  node = xmlNewDocComment(
36
- xml_doc,
37
- (const xmlChar *)StringValueCStr(content)
38
- );
36
+ xml_doc,
37
+ (const xmlChar *)StringValueCStr(content)
38
+ );
39
39
 
40
- rb_node = Nokogiri_wrap_xml_node(klass, node);
40
+ rb_node = noko_xml_node_wrap(klass, node);
41
41
  rb_obj_call_init(rb_node, argc, argv);
42
42
 
43
- nokogiri_root_node(node);
43
+ noko_xml_document_pin_node(node);
44
44
 
45
- if(rb_block_given_p()) rb_yield(rb_node);
45
+ if (rb_block_given_p()) { rb_yield(rb_node); }
46
46
 
47
47
  return rb_node;
48
48
  }
49
49
 
50
- VALUE cNokogiriXmlComment;
51
- void init_xml_comment()
50
+ void
51
+ noko_init_xml_comment()
52
52
  {
53
- VALUE nokogiri = rb_define_module("Nokogiri");
54
- VALUE xml = rb_define_module_under(nokogiri, "XML");
55
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
56
- VALUE char_data = rb_define_class_under(xml, "CharacterData", node);
57
-
53
+ assert(cNokogiriXmlCharacterData);
58
54
  /*
59
55
  * Comment represents a comment node in an xml document.
60
56
  */
61
- VALUE klass = rb_define_class_under(xml, "Comment", char_data);
62
-
63
-
64
- cNokogiriXmlComment = klass;
57
+ cNokogiriXmlComment = rb_define_class_under(mNokogiriXml, "Comment", cNokogiriXmlCharacterData);
65
58
 
66
- rb_define_singleton_method(klass, "new", new, -1);
59
+ rb_define_singleton_method(cNokogiriXmlComment, "new", new, -1);
67
60
 
68
61
  document_id = rb_intern("document");
69
62
  }
@@ -1,8 +1,11 @@
1
- #include <xml_document.h>
1
+ #include <nokogiri.h>
2
2
 
3
- static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
3
+ VALUE cNokogiriXmlDocument ;
4
+
5
+ static int
6
+ dealloc_node_i2(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
4
7
  {
5
- switch(node->type) {
8
+ switch (node->type) {
6
9
  case XML_ATTRIBUTE_NODE:
7
10
  xmlFreePropList((xmlAttrPtr)node);
8
11
  break;
@@ -13,41 +16,52 @@ static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
13
16
  xmlFreeDtd((xmlDtdPtr)node);
14
17
  break;
15
18
  default:
16
- if(node->parent == NULL) {
19
+ if (node->parent == NULL) {
17
20
  xmlAddChild((xmlNodePtr)doc, node);
18
21
  }
19
22
  }
20
23
  return ST_CONTINUE;
21
24
  }
22
25
 
23
- static void remove_private(xmlNodePtr node)
26
+ static int
27
+ dealloc_node_i(st_data_t key, st_data_t node, st_data_t doc)
28
+ {
29
+ return dealloc_node_i2((xmlNodePtr)key, (xmlNodePtr)node, (xmlDocPtr)doc);
30
+ }
31
+
32
+ static void
33
+ remove_private(xmlNodePtr node)
24
34
  {
25
35
  xmlNodePtr child;
26
36
 
27
- for (child = node->children; child; child = child->next)
37
+ for (child = node->children; child; child = child->next) {
28
38
  remove_private(child);
39
+ }
29
40
 
30
41
  if ((node->type == XML_ELEMENT_NODE ||
31
42
  node->type == XML_XINCLUDE_START ||
32
43
  node->type == XML_XINCLUDE_END) &&
33
44
  node->properties) {
34
- for (child = (xmlNodePtr)node->properties; child; child = child->next)
45
+ for (child = (xmlNodePtr)node->properties; child; child = child->next) {
35
46
  remove_private(child);
47
+ }
36
48
  }
37
49
 
38
50
  node->_private = NULL;
39
51
  }
40
52
 
41
- static void mark(xmlDocPtr doc)
53
+ static void
54
+ mark(xmlDocPtr doc)
42
55
  {
43
56
  nokogiriTuplePtr tuple = (nokogiriTuplePtr)doc->_private;
44
- if(tuple) {
45
- rb_gc_mark(tuple->doc);
46
- rb_gc_mark(tuple->node_cache);
57
+ if (tuple) {
58
+ rb_gc_mark(tuple->doc);
59
+ rb_gc_mark(tuple->node_cache);
47
60
  }
48
61
  }
49
62
 
50
- static void dealloc(xmlDocPtr doc)
63
+ static void
64
+ dealloc(xmlDocPtr doc)
51
65
  {
52
66
  st_table *node_hash;
53
67
 
@@ -65,23 +79,26 @@ static void dealloc(xmlDocPtr doc)
65
79
  * xmlDeregisterNode callback from accessing VALUE pointers from ruby's GC
66
80
  * free context, which can result in segfaults.
67
81
  */
68
- if (xmlDeregisterNodeDefaultValue)
82
+ if (xmlDeregisterNodeDefaultValue) {
69
83
  remove_private((xmlNodePtr)doc);
84
+ }
70
85
 
71
86
  xmlFreeDoc(doc);
72
87
 
73
88
  NOKOGIRI_DEBUG_END(doc);
74
89
  }
75
90
 
76
- static void recursively_remove_namespaces_from_node(xmlNodePtr node)
91
+ static void
92
+ recursively_remove_namespaces_from_node(xmlNodePtr node)
77
93
  {
78
94
  xmlNodePtr child ;
79
95
  xmlAttrPtr property ;
80
96
 
81
97
  xmlSetNs(node, NULL);
82
98
 
83
- for (child = node->children ; child ; child = child->next)
99
+ for (child = node->children ; child ; child = child->next) {
84
100
  recursively_remove_namespaces_from_node(child);
101
+ }
85
102
 
86
103
  if (((node->type == XML_ELEMENT_NODE) ||
87
104
  (node->type == XML_XINCLUDE_START) ||
@@ -94,7 +111,7 @@ static void recursively_remove_namespaces_from_node(xmlNodePtr node)
94
111
  if (node->type == XML_ELEMENT_NODE && node->properties != NULL) {
95
112
  property = node->properties ;
96
113
  while (property != NULL) {
97
- if (property->ns) property->ns = NULL ;
114
+ if (property->ns) { property->ns = NULL ; }
98
115
  property = property->next ;
99
116
  }
100
117
  }
@@ -106,12 +123,13 @@ static void recursively_remove_namespaces_from_node(xmlNodePtr node)
106
123
  *
107
124
  * Get the url name for this document.
108
125
  */
109
- static VALUE url(VALUE self)
126
+ static VALUE
127
+ url(VALUE self)
110
128
  {
111
129
  xmlDocPtr doc;
112
130
  Data_Get_Struct(self, xmlDoc, doc);
113
131
 
114
- if(doc->URL) return NOKOGIRI_STR_NEW2(doc->URL);
132
+ if (doc->URL) { return NOKOGIRI_STR_NEW2(doc->URL); }
115
133
 
116
134
  return Qnil;
117
135
  }
@@ -122,7 +140,8 @@ static VALUE url(VALUE self)
122
140
  *
123
141
  * Set the root element on this document
124
142
  */
125
- static VALUE set_root(VALUE self, VALUE root)
143
+ static VALUE
144
+ set_root(VALUE self, VALUE root)
126
145
  {
127
146
  xmlDocPtr doc;
128
147
  xmlNodePtr new_root;
@@ -132,12 +151,12 @@ static VALUE set_root(VALUE self, VALUE root)
132
151
 
133
152
  old_root = NULL;
134
153
 
135
- if(NIL_P(root)) {
154
+ if (NIL_P(root)) {
136
155
  old_root = xmlDocGetRootElement(doc);
137
156
 
138
- if(old_root) {
157
+ if (old_root) {
139
158
  xmlUnlinkNode(old_root);
140
- nokogiri_root_node(old_root);
159
+ noko_xml_document_pin_node(old_root);
141
160
  }
142
161
 
143
162
  return root;
@@ -148,7 +167,7 @@ static VALUE set_root(VALUE self, VALUE root)
148
167
 
149
168
  /* If the new root's document is not the same as the current document,
150
169
  * then we need to dup the node in to this document. */
151
- if(new_root->doc != doc) {
170
+ if (new_root->doc != doc) {
152
171
  old_root = xmlDocGetRootElement(doc);
153
172
  if (!(new_root = xmlDocCopyNode(new_root, doc, 1))) {
154
173
  rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
@@ -156,7 +175,7 @@ static VALUE set_root(VALUE self, VALUE root)
156
175
  }
157
176
 
158
177
  xmlDocSetRootElement(doc, new_root);
159
- if(old_root) nokogiri_root_node(old_root);
178
+ if (old_root) { noko_xml_document_pin_node(old_root); }
160
179
  return root;
161
180
  }
162
181
 
@@ -166,7 +185,8 @@ static VALUE set_root(VALUE self, VALUE root)
166
185
  *
167
186
  * Get the root node for this document.
168
187
  */
169
- static VALUE root(VALUE self)
188
+ static VALUE
189
+ root(VALUE self)
170
190
  {
171
191
  xmlDocPtr doc;
172
192
  xmlNodePtr root;
@@ -175,8 +195,8 @@ static VALUE root(VALUE self)
175
195
 
176
196
  root = xmlDocGetRootElement(doc);
177
197
 
178
- if(!root) return Qnil;
179
- return Nokogiri_wrap_xml_node(Qnil, root) ;
198
+ if (!root) { return Qnil; }
199
+ return noko_xml_node_wrap(Qnil, root) ;
180
200
  }
181
201
 
182
202
  /*
@@ -185,13 +205,15 @@ static VALUE root(VALUE self)
185
205
  *
186
206
  * Set the encoding string for this Document
187
207
  */
188
- static VALUE set_encoding(VALUE self, VALUE encoding)
208
+ static VALUE
209
+ set_encoding(VALUE self, VALUE encoding)
189
210
  {
190
211
  xmlDocPtr doc;
191
212
  Data_Get_Struct(self, xmlDoc, doc);
192
213
 
193
- if (doc->encoding)
194
- free((char *)(uintptr_t) doc->encoding); /* avoid gcc cast warning */
214
+ if (doc->encoding) {
215
+ free((char *)(uintptr_t) doc->encoding); /* avoid gcc cast warning */
216
+ }
195
217
 
196
218
  doc->encoding = xmlStrdup((xmlChar *)StringValueCStr(encoding));
197
219
 
@@ -204,12 +226,13 @@ static VALUE set_encoding(VALUE self, VALUE encoding)
204
226
  *
205
227
  * Get the encoding for this Document
206
228
  */
207
- static VALUE encoding(VALUE self)
229
+ static VALUE
230
+ encoding(VALUE self)
208
231
  {
209
232
  xmlDocPtr doc;
210
233
  Data_Get_Struct(self, xmlDoc, doc);
211
234
 
212
- if(!doc->encoding) return Qnil;
235
+ if (!doc->encoding) { return Qnil; }
213
236
  return NOKOGIRI_STR_NEW2(doc->encoding);
214
237
  }
215
238
 
@@ -219,12 +242,13 @@ static VALUE encoding(VALUE self)
219
242
  *
220
243
  * Get the XML version for this Document
221
244
  */
222
- static VALUE version(VALUE self)
245
+ static VALUE
246
+ version(VALUE self)
223
247
  {
224
248
  xmlDocPtr doc;
225
249
  Data_Get_Struct(self, xmlDoc, doc);
226
250
 
227
- if(!doc->version) return Qnil;
251
+ if (!doc->version) { return Qnil; }
228
252
  return NOKOGIRI_STR_NEW2(doc->version);
229
253
  }
230
254
 
@@ -234,14 +258,15 @@ static VALUE version(VALUE self)
234
258
  *
235
259
  * Create a new document from an IO object
236
260
  */
237
- static VALUE read_io( VALUE klass,
238
- VALUE io,
239
- VALUE url,
240
- VALUE encoding,
241
- VALUE options )
261
+ static VALUE
262
+ read_io(VALUE klass,
263
+ VALUE io,
264
+ VALUE url,
265
+ VALUE encoding,
266
+ VALUE options)
242
267
  {
243
- const char * c_url = NIL_P(url) ? NULL : StringValueCStr(url);
244
- const char * c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
268
+ const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
269
+ const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
245
270
  VALUE error_list = rb_ary_new();
246
271
  VALUE document;
247
272
  xmlDocPtr doc;
@@ -250,30 +275,31 @@ static VALUE read_io( VALUE klass,
250
275
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
251
276
 
252
277
  doc = xmlReadIO(
253
- (xmlInputReadCallback)io_read_callback,
254
- (xmlInputCloseCallback)io_close_callback,
255
- (void *)io,
256
- c_url,
257
- c_enc,
258
- (int)NUM2INT(options)
259
- );
278
+ (xmlInputReadCallback)noko_io_read,
279
+ (xmlInputCloseCallback)noko_io_close,
280
+ (void *)io,
281
+ c_url,
282
+ c_enc,
283
+ (int)NUM2INT(options)
284
+ );
260
285
  xmlSetStructuredErrorFunc(NULL, NULL);
261
286
 
262
- if(doc == NULL) {
287
+ if (doc == NULL) {
263
288
  xmlErrorPtr error;
264
289
 
265
290
  xmlFreeDoc(doc);
266
291
 
267
292
  error = xmlGetLastError();
268
- if(error)
293
+ if (error) {
269
294
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
270
- else
295
+ } else {
271
296
  rb_raise(rb_eRuntimeError, "Could not parse document");
297
+ }
272
298
 
273
299
  return Qnil;
274
300
  }
275
301
 
276
- document = Nokogiri_wrap_xml_document(klass, doc);
302
+ document = noko_xml_document_wrap(klass, doc);
277
303
  rb_iv_set(document, "@errors", error_list);
278
304
  return document;
279
305
  }
@@ -284,15 +310,16 @@ static VALUE read_io( VALUE klass,
284
310
  *
285
311
  * Create a new document from a String
286
312
  */
287
- static VALUE read_memory( VALUE klass,
288
- VALUE string,
289
- VALUE url,
290
- VALUE encoding,
291
- VALUE options )
313
+ static VALUE
314
+ read_memory(VALUE klass,
315
+ VALUE string,
316
+ VALUE url,
317
+ VALUE encoding,
318
+ VALUE options)
292
319
  {
293
- const char * c_buffer = StringValuePtr(string);
294
- const char * c_url = NIL_P(url) ? NULL : StringValueCStr(url);
295
- const char * c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
320
+ const char *c_buffer = StringValuePtr(string);
321
+ const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
322
+ const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
296
323
  int len = (int)RSTRING_LEN(string);
297
324
  VALUE error_list = rb_ary_new();
298
325
  VALUE document;
@@ -303,21 +330,22 @@ static VALUE read_memory( VALUE klass,
303
330
  doc = xmlReadMemory(c_buffer, len, c_url, c_enc, (int)NUM2INT(options));
304
331
  xmlSetStructuredErrorFunc(NULL, NULL);
305
332
 
306
- if(doc == NULL) {
333
+ if (doc == NULL) {
307
334
  xmlErrorPtr error;
308
335
 
309
336
  xmlFreeDoc(doc);
310
337
 
311
338
  error = xmlGetLastError();
312
- if(error)
339
+ if (error) {
313
340
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
314
- else
341
+ } else {
315
342
  rb_raise(rb_eRuntimeError, "Could not parse document");
343
+ }
316
344
 
317
345
  return Qnil;
318
346
  }
319
347
 
320
- document = Nokogiri_wrap_xml_document(klass, doc);
348
+ document = noko_xml_document_wrap(klass, doc);
321
349
  rb_iv_set(document, "@errors", error_list);
322
350
  return document;
323
351
  }
@@ -329,26 +357,26 @@ static VALUE read_memory( VALUE klass,
329
357
  * Copy this Document. An optional depth may be passed in, but it defaults
330
358
  * to a deep copy. 0 is a shallow copy, 1 is a deep copy.
331
359
  */
332
- static VALUE duplicate_document(int argc, VALUE *argv, VALUE self)
360
+ static VALUE
361
+ duplicate_document(int argc, VALUE *argv, VALUE self)
333
362
  {
334
363
  xmlDocPtr doc, dup;
335
364
  VALUE copy;
336
365
  VALUE level;
337
- VALUE error_list;
338
366
 
339
- if(rb_scan_args(argc, argv, "01", &level) == 0)
367
+ if (rb_scan_args(argc, argv, "01", &level) == 0) {
340
368
  level = INT2NUM((long)1);
369
+ }
341
370
 
342
371
  Data_Get_Struct(self, xmlDoc, doc);
343
372
 
344
373
  dup = xmlCopyDoc(doc, (int)NUM2INT(level));
345
374
 
346
- if(dup == NULL) return Qnil;
375
+ if (dup == NULL) { return Qnil; }
347
376
 
348
377
  dup->type = doc->type;
349
- copy = Nokogiri_wrap_xml_document(rb_obj_class(self), dup);
350
- error_list = rb_iv_get(self, "@errors");
351
- rb_iv_set(copy, "@errors", error_list);
378
+ copy = noko_xml_document_wrap(rb_obj_class(self), dup);
379
+ rb_iv_set(copy, "@errors", rb_iv_get(self, "@errors"));
352
380
  return copy ;
353
381
  }
354
382
 
@@ -358,18 +386,18 @@ static VALUE duplicate_document(int argc, VALUE *argv, VALUE self)
358
386
  *
359
387
  * Create a new document with +version+ (defaults to "1.0")
360
388
  */
361
- static VALUE new(int argc, VALUE *argv, VALUE klass)
389
+ static VALUE
390
+ new (int argc, VALUE *argv, VALUE klass)
362
391
  {
363
392
  xmlDocPtr doc;
364
393
  VALUE version, rest, rb_doc ;
365
394
 
366
395
  rb_scan_args(argc, argv, "0*", &rest);
367
396
  version = rb_ary_entry(rest, (long)0);
368
- if (NIL_P(version)) version = rb_str_new2("1.0");
397
+ if (NIL_P(version)) { version = rb_str_new2("1.0"); }
369
398
 
370
399
  doc = xmlNewDoc((xmlChar *)StringValueCStr(version));
371
- rb_doc = Nokogiri_wrap_xml_document(klass, doc);
372
- rb_obj_call_init(rb_doc, argc, argv);
400
+ rb_doc = noko_xml_document_wrap_with_init_args(klass, doc, argc, argv);
373
401
  return rb_doc ;
374
402
  }
375
403
 
@@ -410,7 +438,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
410
438
  * please direct your browser to
411
439
  * http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
412
440
  */
413
- VALUE remove_namespaces_bang(VALUE self)
441
+ static VALUE
442
+ remove_namespaces_bang(VALUE self)
414
443
  {
415
444
  xmlDocPtr doc ;
416
445
  Data_Get_Struct(self, xmlDoc, doc);
@@ -430,7 +459,8 @@ VALUE remove_namespaces_bang(VALUE self)
430
459
  * +external_id+, +system_id+, and +content+ set the External ID, System ID,
431
460
  * and content respectively. All of these parameters are optional.
432
461
  */
433
- static VALUE create_entity(int argc, VALUE *argv, VALUE self)
462
+ static VALUE
463
+ create_entity(int argc, VALUE *argv, VALUE self)
434
464
  {
435
465
  VALUE name;
436
466
  VALUE type;
@@ -443,52 +473,50 @@ static VALUE create_entity(int argc, VALUE *argv, VALUE self)
443
473
  Data_Get_Struct(self, xmlDoc, doc);
444
474
 
445
475
  rb_scan_args(argc, argv, "14", &name, &type, &external_id, &system_id,
446
- &content);
476
+ &content);
447
477
 
448
478
  xmlResetLastError();
449
479
  ptr = xmlAddDocEntity(
450
- doc,
451
- (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
452
- (int) (NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
453
- (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
454
- (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
455
- (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
456
- );
457
-
458
- if(NULL == ptr) {
480
+ doc,
481
+ (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
482
+ (int)(NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
483
+ (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
484
+ (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
485
+ (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
486
+ );
487
+
488
+ if (NULL == ptr) {
459
489
  xmlErrorPtr error = xmlGetLastError();
460
- if(error)
490
+ if (error) {
461
491
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
462
- else
492
+ } else {
463
493
  rb_raise(rb_eRuntimeError, "Could not create entity");
494
+ }
464
495
 
465
496
  return Qnil;
466
497
  }
467
498
 
468
- return Nokogiri_wrap_xml_node(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
499
+ return noko_xml_node_wrap(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
469
500
  }
470
501
 
471
- static int block_caller(void * ctx, xmlNodePtr _node, xmlNodePtr _parent)
502
+ static int
503
+ block_caller(void *ctx, xmlNodePtr c_node, xmlNodePtr c_parent_node)
472
504
  {
473
- VALUE block;
474
- VALUE node;
475
- VALUE parent;
505
+ VALUE block = (VALUE)ctx;
506
+ VALUE rb_node;
507
+ VALUE rb_parent_node;
476
508
  VALUE ret;
477
509
 
478
- if(_node->type == XML_NAMESPACE_DECL){
479
- node = Nokogiri_wrap_xml_namespace(_parent->doc, (xmlNsPtr) _node);
480
- }
481
- else{
482
- node = Nokogiri_wrap_xml_node(Qnil, _node);
510
+ if (c_node->type == XML_NAMESPACE_DECL) {
511
+ rb_node = noko_xml_namespace_wrap((xmlNsPtr)c_node, c_parent_node->doc);
512
+ } else {
513
+ rb_node = noko_xml_node_wrap(Qnil, c_node);
483
514
  }
484
- parent = _parent ? Nokogiri_wrap_xml_node(Qnil, _parent) : Qnil;
485
- block = (VALUE)ctx;
515
+ rb_parent_node = c_parent_node ? noko_xml_node_wrap(Qnil, c_parent_node) : Qnil;
486
516
 
487
- ret = rb_funcall(block, rb_intern("call"), 2, node, parent);
517
+ ret = rb_funcall(block, rb_intern("call"), 2, rb_node, rb_parent_node);
488
518
 
489
- if(Qfalse == ret || Qnil == ret) return 0;
490
-
491
- return 1;
519
+ return (Qfalse == ret || Qnil == ret) ? 0 : 1;
492
520
  }
493
521
 
494
522
  /* call-seq:
@@ -501,7 +529,8 @@ static int block_caller(void * ctx, xmlNodePtr _node, xmlNodePtr _parent)
501
529
  * The block must return a non-nil, non-false value if the +obj+ passed in
502
530
  * should be included in the canonicalized document.
503
531
  */
504
- static VALUE canonicalize(int argc, VALUE* argv, VALUE self)
532
+ static VALUE
533
+ rb_xml_document_canonicalize(int argc, VALUE *argv, VALUE self)
505
534
  {
506
535
  VALUE mode;
507
536
  VALUE incl_ns;
@@ -512,7 +541,7 @@ static VALUE canonicalize(int argc, VALUE* argv, VALUE self)
512
541
  xmlDocPtr doc;
513
542
  xmlOutputBufferPtr buf;
514
543
  xmlC14NIsVisibleCallback cb = NULL;
515
- void * ctx = NULL;
544
+ void *ctx = NULL;
516
545
 
517
546
  VALUE rb_cStringIO;
518
547
  VALUE io;
@@ -525,93 +554,126 @@ static VALUE canonicalize(int argc, VALUE* argv, VALUE self)
525
554
  io = rb_class_new_instance(0, 0, rb_cStringIO);
526
555
  buf = xmlAllocOutputBuffer(NULL);
527
556
 
528
- buf->writecallback = (xmlOutputWriteCallback)io_write_callback;
529
- buf->closecallback = (xmlOutputCloseCallback)io_close_callback;
557
+ buf->writecallback = (xmlOutputWriteCallback)noko_io_write;
558
+ buf->closecallback = (xmlOutputCloseCallback)noko_io_close;
530
559
  buf->context = (void *)io;
531
560
 
532
- if(rb_block_given_p()) {
561
+ if (rb_block_given_p()) {
533
562
  cb = block_caller;
534
563
  ctx = (void *)rb_block_proc();
535
564
  }
536
565
 
537
- if(NIL_P(incl_ns)){
566
+ if (NIL_P(incl_ns)) {
538
567
  ns = NULL;
539
- }
540
- else{
568
+ } else {
541
569
  Check_Type(incl_ns, T_ARRAY);
542
570
  ns_len = RARRAY_LEN(incl_ns);
543
- ns = calloc((size_t)ns_len+1, sizeof(xmlChar *));
571
+ ns = calloc((size_t)ns_len + 1, sizeof(xmlChar *));
544
572
  for (i = 0 ; i < ns_len ; i++) {
545
573
  VALUE entry = rb_ary_entry(incl_ns, i);
546
- ns[i] = (xmlChar*)StringValueCStr(entry);
574
+ ns[i] = (xmlChar *)StringValueCStr(entry);
547
575
  }
548
576
  }
549
577
 
550
578
 
551
579
  xmlC14NExecute(doc, cb, ctx,
552
- (int) (NIL_P(mode) ? 0 : NUM2INT(mode)),
553
- ns,
554
- (int) RTEST(with_comments),
555
- buf);
580
+ (int)(NIL_P(mode) ? 0 : NUM2INT(mode)),
581
+ ns,
582
+ (int) RTEST(with_comments),
583
+ buf);
556
584
 
557
585
  xmlOutputBufferClose(buf);
558
586
 
559
587
  return rb_funcall(io, rb_intern("string"), 0);
560
588
  }
561
589
 
562
- VALUE cNokogiriXmlDocument ;
563
- void init_xml_document()
590
+ VALUE
591
+ noko_xml_document_wrap_with_init_args(VALUE klass, xmlDocPtr c_document, int argc, VALUE *argv)
564
592
  {
565
- VALUE nokogiri = rb_define_module("Nokogiri");
566
- VALUE xml = rb_define_module_under(nokogiri, "XML");
567
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
593
+ VALUE rb_document;
594
+ nokogiriTuplePtr tuple;
568
595
 
569
- /*
570
- * Nokogiri::XML::Document wraps an xml document.
571
- */
572
- VALUE klass = rb_define_class_under(xml, "Document", node);
573
-
574
- cNokogiriXmlDocument = klass;
575
-
576
- rb_define_singleton_method(klass, "read_memory", read_memory, 4);
577
- rb_define_singleton_method(klass, "read_io", read_io, 4);
578
- rb_define_singleton_method(klass, "new", new, -1);
579
-
580
- rb_define_method(klass, "root", root, 0);
581
- rb_define_method(klass, "root=", set_root, 1);
582
- rb_define_method(klass, "encoding", encoding, 0);
583
- rb_define_method(klass, "encoding=", set_encoding, 1);
584
- rb_define_method(klass, "version", version, 0);
585
- rb_define_method(klass, "canonicalize", canonicalize, -1);
586
- rb_define_method(klass, "dup", duplicate_document, -1);
587
- rb_define_method(klass, "url", url, 0);
588
- rb_define_method(klass, "create_entity", create_entity, -1);
589
- rb_define_method(klass, "remove_namespaces!", remove_namespaces_bang, 0);
596
+ if (!klass) {
597
+ klass = cNokogiriXmlDocument;
598
+ }
599
+
600
+ rb_document = Data_Wrap_Struct(klass, mark, dealloc, c_document);
601
+
602
+ tuple = (nokogiriTuplePtr)malloc(sizeof(nokogiriTuple));
603
+ tuple->doc = rb_document;
604
+ tuple->unlinkedNodes = st_init_numtable_with_size(128);
605
+ tuple->node_cache = rb_ary_new();
606
+
607
+ c_document->_private = tuple ;
608
+
609
+ rb_iv_set(rb_document, "@decorators", Qnil);
610
+ rb_iv_set(rb_document, "@errors", Qnil);
611
+ rb_iv_set(rb_document, "@node_cache", tuple->node_cache);
612
+
613
+ rb_obj_call_init(rb_document, argc, argv);
614
+
615
+ return rb_document ;
590
616
  }
591
617
 
592
618
 
593
- /* this takes klass as a param because it's used for HtmlDocument, too. */
594
- VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
619
+ /* deprecated. use noko_xml_document_wrap() instead. */
620
+ VALUE
621
+ Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
595
622
  {
596
- nokogiriTuplePtr tuple = (nokogiriTuplePtr)malloc(sizeof(nokogiriTuple));
623
+ /* TODO: deprecate this method in v2.0 */
624
+ return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL);
625
+ }
597
626
 
598
- VALUE rb_doc = Data_Wrap_Struct(
599
- klass ? klass : cNokogiriXmlDocument,
600
- mark,
601
- dealloc,
602
- doc
603
- );
627
+ VALUE
628
+ noko_xml_document_wrap(VALUE klass, xmlDocPtr doc)
629
+ {
630
+ return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL);
631
+ }
604
632
 
605
- VALUE cache = rb_ary_new();
606
- rb_iv_set(rb_doc, "@decorators", Qnil);
607
- rb_iv_set(rb_doc, "@node_cache", cache);
608
633
 
609
- tuple->doc = rb_doc;
610
- tuple->unlinkedNodes = st_init_numtable_with_size(128);
611
- tuple->node_cache = cache;
612
- doc->_private = tuple ;
634
+ void
635
+ noko_xml_document_pin_node(xmlNodePtr node)
636
+ {
637
+ xmlDocPtr doc;
638
+ nokogiriTuplePtr tuple;
613
639
 
614
- rb_obj_call_init(rb_doc, 0, NULL);
640
+ doc = node->doc;
641
+ tuple = (nokogiriTuplePtr)doc->_private;
642
+ st_insert(tuple->unlinkedNodes, (st_data_t)node, (st_data_t)node);
643
+ }
615
644
 
616
- return rb_doc ;
645
+
646
+ void
647
+ noko_xml_document_pin_namespace(xmlNsPtr ns, xmlDocPtr doc)
648
+ {
649
+ nokogiriTuplePtr tuple;
650
+
651
+ tuple = (nokogiriTuplePtr)doc->_private;
652
+ st_insert(tuple->unlinkedNodes, (st_data_t)ns, (st_data_t)ns);
653
+ }
654
+
655
+
656
+ void
657
+ noko_init_xml_document()
658
+ {
659
+ assert(cNokogiriXmlNode);
660
+ /*
661
+ * Nokogiri::XML::Document wraps an xml document.
662
+ */
663
+ cNokogiriXmlDocument = rb_define_class_under(mNokogiriXml, "Document", cNokogiriXmlNode);
664
+
665
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_memory", read_memory, 4);
666
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_io", read_io, 4);
667
+ rb_define_singleton_method(cNokogiriXmlDocument, "new", new, -1);
668
+
669
+ rb_define_method(cNokogiriXmlDocument, "root", root, 0);
670
+ rb_define_method(cNokogiriXmlDocument, "root=", set_root, 1);
671
+ rb_define_method(cNokogiriXmlDocument, "encoding", encoding, 0);
672
+ rb_define_method(cNokogiriXmlDocument, "encoding=", set_encoding, 1);
673
+ rb_define_method(cNokogiriXmlDocument, "version", version, 0);
674
+ rb_define_method(cNokogiriXmlDocument, "canonicalize", rb_xml_document_canonicalize, -1);
675
+ rb_define_method(cNokogiriXmlDocument, "dup", duplicate_document, -1);
676
+ rb_define_method(cNokogiriXmlDocument, "url", url, 0);
677
+ rb_define_method(cNokogiriXmlDocument, "create_entity", create_entity, -1);
678
+ rb_define_method(cNokogiriXmlDocument, "remove_namespaces!", remove_namespaces_bang, 0);
617
679
  }