nokogiri 1.10.10 → 1.13.9

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 (220) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/LICENSE-DEPENDENCIES.md +1173 -884
  4. data/LICENSE.md +1 -1
  5. data/README.md +178 -96
  6. data/bin/nokogiri +63 -50
  7. data/dependencies.yml +13 -64
  8. data/ext/nokogiri/depend +38 -358
  9. data/ext/nokogiri/extconf.rb +761 -424
  10. data/ext/nokogiri/gumbo.c +584 -0
  11. data/ext/nokogiri/html4_document.c +166 -0
  12. data/ext/nokogiri/html4_element_description.c +294 -0
  13. data/ext/nokogiri/html4_entity_lookup.c +37 -0
  14. data/ext/nokogiri/html4_sax_parser_context.c +119 -0
  15. data/ext/nokogiri/html4_sax_push_parser.c +95 -0
  16. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  17. data/ext/nokogiri/nokogiri.c +228 -91
  18. data/ext/nokogiri/nokogiri.h +199 -88
  19. data/ext/nokogiri/test_global_handlers.c +40 -0
  20. data/ext/nokogiri/xml_attr.c +17 -17
  21. data/ext/nokogiri/xml_attribute_decl.c +21 -21
  22. data/ext/nokogiri/xml_cdata.c +14 -19
  23. data/ext/nokogiri/xml_comment.c +19 -26
  24. data/ext/nokogiri/xml_document.c +296 -220
  25. data/ext/nokogiri/xml_document_fragment.c +12 -16
  26. data/ext/nokogiri/xml_dtd.c +64 -58
  27. data/ext/nokogiri/xml_element_content.c +31 -26
  28. data/ext/nokogiri/xml_element_decl.c +25 -25
  29. data/ext/nokogiri/xml_encoding_handler.c +43 -18
  30. data/ext/nokogiri/xml_entity_decl.c +37 -35
  31. data/ext/nokogiri/xml_entity_reference.c +16 -18
  32. data/ext/nokogiri/xml_namespace.c +98 -53
  33. data/ext/nokogiri/xml_node.c +1065 -653
  34. data/ext/nokogiri/xml_node_set.c +178 -166
  35. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  36. data/ext/nokogiri/xml_reader.c +277 -175
  37. data/ext/nokogiri/xml_relax_ng.c +52 -28
  38. data/ext/nokogiri/xml_sax_parser.c +112 -112
  39. data/ext/nokogiri/xml_sax_parser_context.c +112 -86
  40. data/ext/nokogiri/xml_sax_push_parser.c +36 -27
  41. data/ext/nokogiri/xml_schema.c +98 -48
  42. data/ext/nokogiri/xml_syntax_error.c +42 -21
  43. data/ext/nokogiri/xml_text.c +14 -18
  44. data/ext/nokogiri/xml_xpath_context.c +226 -115
  45. data/ext/nokogiri/xslt_stylesheet.c +265 -173
  46. data/gumbo-parser/CHANGES.md +63 -0
  47. data/gumbo-parser/Makefile +101 -0
  48. data/gumbo-parser/THANKS +27 -0
  49. data/gumbo-parser/src/Makefile +34 -0
  50. data/gumbo-parser/src/README.md +41 -0
  51. data/gumbo-parser/src/ascii.c +75 -0
  52. data/gumbo-parser/src/ascii.h +115 -0
  53. data/gumbo-parser/src/attribute.c +42 -0
  54. data/gumbo-parser/src/attribute.h +17 -0
  55. data/gumbo-parser/src/char_ref.c +22225 -0
  56. data/gumbo-parser/src/char_ref.h +29 -0
  57. data/gumbo-parser/src/char_ref.rl +2154 -0
  58. data/gumbo-parser/src/error.c +626 -0
  59. data/gumbo-parser/src/error.h +148 -0
  60. data/gumbo-parser/src/foreign_attrs.c +104 -0
  61. data/gumbo-parser/src/foreign_attrs.gperf +27 -0
  62. data/gumbo-parser/src/gumbo.h +943 -0
  63. data/gumbo-parser/src/insertion_mode.h +33 -0
  64. data/gumbo-parser/src/macros.h +91 -0
  65. data/gumbo-parser/src/parser.c +4875 -0
  66. data/gumbo-parser/src/parser.h +41 -0
  67. data/gumbo-parser/src/replacement.h +33 -0
  68. data/gumbo-parser/src/string_buffer.c +103 -0
  69. data/gumbo-parser/src/string_buffer.h +68 -0
  70. data/gumbo-parser/src/string_piece.c +48 -0
  71. data/gumbo-parser/src/svg_attrs.c +174 -0
  72. data/gumbo-parser/src/svg_attrs.gperf +77 -0
  73. data/gumbo-parser/src/svg_tags.c +137 -0
  74. data/gumbo-parser/src/svg_tags.gperf +55 -0
  75. data/gumbo-parser/src/tag.c +222 -0
  76. data/gumbo-parser/src/tag_lookup.c +382 -0
  77. data/gumbo-parser/src/tag_lookup.gperf +169 -0
  78. data/gumbo-parser/src/tag_lookup.h +13 -0
  79. data/gumbo-parser/src/token_buffer.c +79 -0
  80. data/gumbo-parser/src/token_buffer.h +71 -0
  81. data/gumbo-parser/src/token_type.h +17 -0
  82. data/gumbo-parser/src/tokenizer.c +3463 -0
  83. data/gumbo-parser/src/tokenizer.h +112 -0
  84. data/gumbo-parser/src/tokenizer_states.h +339 -0
  85. data/gumbo-parser/src/utf8.c +245 -0
  86. data/gumbo-parser/src/utf8.h +164 -0
  87. data/gumbo-parser/src/util.c +68 -0
  88. data/gumbo-parser/src/util.h +30 -0
  89. data/gumbo-parser/src/vector.c +111 -0
  90. data/gumbo-parser/src/vector.h +45 -0
  91. data/lib/nokogiri/class_resolver.rb +67 -0
  92. data/lib/nokogiri/css/node.rb +10 -8
  93. data/lib/nokogiri/css/parser.rb +397 -377
  94. data/lib/nokogiri/css/parser.y +250 -245
  95. data/lib/nokogiri/css/parser_extras.rb +54 -49
  96. data/lib/nokogiri/css/syntax_error.rb +3 -1
  97. data/lib/nokogiri/css/tokenizer.rb +5 -3
  98. data/lib/nokogiri/css/tokenizer.rex +3 -2
  99. data/lib/nokogiri/css/xpath_visitor.rb +218 -91
  100. data/lib/nokogiri/css.rb +50 -17
  101. data/lib/nokogiri/decorators/slop.rb +9 -7
  102. data/lib/nokogiri/extension.rb +31 -0
  103. data/lib/nokogiri/gumbo.rb +15 -0
  104. data/lib/nokogiri/html.rb +38 -27
  105. data/lib/nokogiri/{html → html4}/builder.rb +4 -2
  106. data/lib/nokogiri/{html → html4}/document.rb +103 -105
  107. data/lib/nokogiri/html4/document_fragment.rb +54 -0
  108. data/lib/nokogiri/{html → html4}/element_description.rb +3 -1
  109. data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
  110. data/lib/nokogiri/{html → html4}/entity_lookup.rb +4 -2
  111. data/lib/nokogiri/{html → html4}/sax/parser.rb +17 -16
  112. data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
  113. data/lib/nokogiri/{html → html4}/sax/push_parser.rb +12 -11
  114. data/lib/nokogiri/html4.rb +46 -0
  115. data/lib/nokogiri/html5/document.rb +91 -0
  116. data/lib/nokogiri/html5/document_fragment.rb +83 -0
  117. data/lib/nokogiri/html5/node.rb +100 -0
  118. data/lib/nokogiri/html5.rb +478 -0
  119. data/lib/nokogiri/jruby/dependencies.rb +21 -0
  120. data/lib/nokogiri/syntax_error.rb +2 -0
  121. data/lib/nokogiri/version/constant.rb +6 -0
  122. data/lib/nokogiri/version/info.rb +222 -0
  123. data/lib/nokogiri/version.rb +3 -108
  124. data/lib/nokogiri/xml/attr.rb +6 -3
  125. data/lib/nokogiri/xml/attribute_decl.rb +3 -1
  126. data/lib/nokogiri/xml/builder.rb +74 -33
  127. data/lib/nokogiri/xml/cdata.rb +3 -1
  128. data/lib/nokogiri/xml/character_data.rb +2 -0
  129. data/lib/nokogiri/xml/document.rb +224 -86
  130. data/lib/nokogiri/xml/document_fragment.rb +46 -44
  131. data/lib/nokogiri/xml/dtd.rb +4 -2
  132. data/lib/nokogiri/xml/element_content.rb +2 -0
  133. data/lib/nokogiri/xml/element_decl.rb +3 -1
  134. data/lib/nokogiri/xml/entity_decl.rb +4 -2
  135. data/lib/nokogiri/xml/entity_reference.rb +2 -0
  136. data/lib/nokogiri/xml/namespace.rb +3 -0
  137. data/lib/nokogiri/xml/node/save_options.rb +10 -5
  138. data/lib/nokogiri/xml/node.rb +884 -378
  139. data/lib/nokogiri/xml/node_set.rb +51 -54
  140. data/lib/nokogiri/xml/notation.rb +13 -0
  141. data/lib/nokogiri/xml/parse_options.rb +22 -8
  142. data/lib/nokogiri/xml/pp/character_data.rb +9 -6
  143. data/lib/nokogiri/xml/pp/node.rb +25 -26
  144. data/lib/nokogiri/xml/pp.rb +4 -2
  145. data/lib/nokogiri/xml/processing_instruction.rb +3 -1
  146. data/lib/nokogiri/xml/reader.rb +21 -28
  147. data/lib/nokogiri/xml/relax_ng.rb +8 -2
  148. data/lib/nokogiri/xml/sax/document.rb +45 -49
  149. data/lib/nokogiri/xml/sax/parser.rb +38 -34
  150. data/lib/nokogiri/xml/sax/parser_context.rb +8 -3
  151. data/lib/nokogiri/xml/sax/push_parser.rb +6 -5
  152. data/lib/nokogiri/xml/sax.rb +6 -4
  153. data/lib/nokogiri/xml/schema.rb +19 -9
  154. data/lib/nokogiri/xml/searchable.rb +112 -72
  155. data/lib/nokogiri/xml/syntax_error.rb +6 -4
  156. data/lib/nokogiri/xml/text.rb +2 -0
  157. data/lib/nokogiri/xml/xpath/syntax_error.rb +4 -2
  158. data/lib/nokogiri/xml/xpath.rb +15 -4
  159. data/lib/nokogiri/xml/xpath_context.rb +3 -3
  160. data/lib/nokogiri/xml.rb +38 -37
  161. data/lib/nokogiri/xslt/stylesheet.rb +3 -1
  162. data/lib/nokogiri/xslt.rb +29 -20
  163. data/lib/nokogiri.rb +49 -65
  164. data/lib/xsd/xmlparser/nokogiri.rb +26 -24
  165. data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
  166. data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
  167. data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
  168. data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
  169. data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
  170. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +3037 -0
  171. data/ports/archives/libxml2-2.10.3.tar.xz +0 -0
  172. data/ports/archives/libxslt-1.1.37.tar.xz +0 -0
  173. metadata +189 -142
  174. data/ext/nokogiri/html_document.c +0 -170
  175. data/ext/nokogiri/html_document.h +0 -10
  176. data/ext/nokogiri/html_element_description.c +0 -279
  177. data/ext/nokogiri/html_element_description.h +0 -10
  178. data/ext/nokogiri/html_entity_lookup.c +0 -32
  179. data/ext/nokogiri/html_entity_lookup.h +0 -8
  180. data/ext/nokogiri/html_sax_parser_context.c +0 -116
  181. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  182. data/ext/nokogiri/html_sax_push_parser.c +0 -87
  183. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  184. data/ext/nokogiri/xml_attr.h +0 -9
  185. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  186. data/ext/nokogiri/xml_cdata.h +0 -9
  187. data/ext/nokogiri/xml_comment.h +0 -9
  188. data/ext/nokogiri/xml_document.h +0 -23
  189. data/ext/nokogiri/xml_document_fragment.h +0 -10
  190. data/ext/nokogiri/xml_dtd.h +0 -10
  191. data/ext/nokogiri/xml_element_content.h +0 -10
  192. data/ext/nokogiri/xml_element_decl.h +0 -9
  193. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  194. data/ext/nokogiri/xml_entity_decl.h +0 -10
  195. data/ext/nokogiri/xml_entity_reference.h +0 -9
  196. data/ext/nokogiri/xml_io.c +0 -61
  197. data/ext/nokogiri/xml_io.h +0 -11
  198. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  199. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  200. data/ext/nokogiri/xml_namespace.h +0 -14
  201. data/ext/nokogiri/xml_node.h +0 -13
  202. data/ext/nokogiri/xml_node_set.h +0 -12
  203. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  204. data/ext/nokogiri/xml_reader.h +0 -10
  205. data/ext/nokogiri/xml_relax_ng.h +0 -9
  206. data/ext/nokogiri/xml_sax_parser.h +0 -39
  207. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  208. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  209. data/ext/nokogiri/xml_schema.h +0 -9
  210. data/ext/nokogiri/xml_syntax_error.h +0 -13
  211. data/ext/nokogiri/xml_text.h +0 -9
  212. data/ext/nokogiri/xml_xpath_context.h +0 -10
  213. data/ext/nokogiri/xslt_stylesheet.h +0 -14
  214. data/lib/nokogiri/html/document_fragment.rb +0 -49
  215. data/lib/nokogiri/html/element_description_defaults.rb +0 -671
  216. data/lib/nokogiri/html/sax/parser_context.rb +0 -16
  217. data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
  218. data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
  219. data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
  220. data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
@@ -1,44 +1,67 @@
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) {
6
- case XML_ATTRIBUTE_NODE:
7
- xmlFreePropList((xmlAttrPtr)node);
8
- break;
9
- case XML_NAMESPACE_DECL:
10
- xmlFreeNs((xmlNsPtr)node);
11
- break;
12
- case XML_DTD_NODE:
13
- xmlFreeDtd((xmlDtdPtr)node);
14
- break;
15
- default:
16
- if(node->parent == NULL) {
17
- xmlAddChild((xmlNodePtr)doc, node);
18
- }
8
+ switch (node->type) {
9
+ case XML_ATTRIBUTE_NODE:
10
+ xmlFreePropList((xmlAttrPtr)node);
11
+ break;
12
+ case XML_NAMESPACE_DECL:
13
+ xmlFreeNs((xmlNsPtr)node);
14
+ break;
15
+ case XML_DTD_NODE:
16
+ xmlFreeDtd((xmlDtdPtr)node);
17
+ break;
18
+ default:
19
+ if (node->parent == NULL) {
20
+ xmlAddChild((xmlNodePtr)doc, node);
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 dealloc(xmlDocPtr doc)
53
+ static void
54
+ mark(xmlDocPtr doc)
55
+ {
56
+ nokogiriTuplePtr tuple = (nokogiriTuplePtr)doc->_private;
57
+ if (tuple) {
58
+ rb_gc_mark(tuple->doc);
59
+ rb_gc_mark(tuple->node_cache);
60
+ }
61
+ }
62
+
63
+ static void
64
+ dealloc(xmlDocPtr doc)
42
65
  {
43
66
  st_table *node_hash;
44
67
 
@@ -56,36 +79,43 @@ static void dealloc(xmlDocPtr doc)
56
79
  * xmlDeregisterNode callback from accessing VALUE pointers from ruby's GC
57
80
  * free context, which can result in segfaults.
58
81
  */
59
- if (xmlDeregisterNodeDefaultValue)
82
+ if (xmlDeregisterNodeDefaultValue) {
60
83
  remove_private((xmlNodePtr)doc);
84
+ }
61
85
 
62
86
  xmlFreeDoc(doc);
63
87
 
64
88
  NOKOGIRI_DEBUG_END(doc);
65
89
  }
66
90
 
67
- static void recursively_remove_namespaces_from_node(xmlNodePtr node)
91
+ static void
92
+ recursively_remove_namespaces_from_node(xmlNodePtr node)
68
93
  {
69
94
  xmlNodePtr child ;
70
95
  xmlAttrPtr property ;
71
96
 
72
97
  xmlSetNs(node, NULL);
73
98
 
74
- for (child = node->children ; child ; child = child->next)
99
+ for (child = node->children ; child ; child = child->next) {
75
100
  recursively_remove_namespaces_from_node(child);
101
+ }
76
102
 
77
103
  if (((node->type == XML_ELEMENT_NODE) ||
78
104
  (node->type == XML_XINCLUDE_START) ||
79
105
  (node->type == XML_XINCLUDE_END)) &&
80
106
  node->nsDef) {
81
- xmlFreeNsList(node->nsDef);
107
+ xmlNsPtr curr = node->nsDef;
108
+ while (curr) {
109
+ noko_xml_document_pin_namespace(curr, node->doc);
110
+ curr = curr->next;
111
+ }
82
112
  node->nsDef = NULL;
83
113
  }
84
114
 
85
115
  if (node->type == XML_ELEMENT_NODE && node->properties != NULL) {
86
116
  property = node->properties ;
87
117
  while (property != NULL) {
88
- if (property->ns) property->ns = NULL ;
118
+ if (property->ns) { property->ns = NULL ; }
89
119
  property = property->next ;
90
120
  }
91
121
  }
@@ -97,12 +127,13 @@ static void recursively_remove_namespaces_from_node(xmlNodePtr node)
97
127
  *
98
128
  * Get the url name for this document.
99
129
  */
100
- static VALUE url(VALUE self)
130
+ static VALUE
131
+ url(VALUE self)
101
132
  {
102
133
  xmlDocPtr doc;
103
134
  Data_Get_Struct(self, xmlDoc, doc);
104
135
 
105
- if(doc->URL) return NOKOGIRI_STR_NEW2(doc->URL);
136
+ if (doc->URL) { return NOKOGIRI_STR_NEW2(doc->URL); }
106
137
 
107
138
  return Qnil;
108
139
  }
@@ -113,42 +144,42 @@ static VALUE url(VALUE self)
113
144
  *
114
145
  * Set the root element on this document
115
146
  */
116
- static VALUE set_root(VALUE self, VALUE root)
147
+ static VALUE
148
+ rb_xml_document_root_set(VALUE self, VALUE rb_new_root)
117
149
  {
118
- xmlDocPtr doc;
119
- xmlNodePtr new_root;
120
- xmlNodePtr old_root;
150
+ xmlDocPtr c_document;
151
+ xmlNodePtr c_new_root = NULL, c_current_root;
121
152
 
122
- Data_Get_Struct(self, xmlDoc, doc);
153
+ Data_Get_Struct(self, xmlDoc, c_document);
123
154
 
124
- old_root = NULL;
125
-
126
- if(NIL_P(root)) {
127
- old_root = xmlDocGetRootElement(doc);
128
-
129
- if(old_root) {
130
- xmlUnlinkNode(old_root);
131
- nokogiri_root_node(old_root);
132
- }
133
-
134
- return root;
155
+ c_current_root = xmlDocGetRootElement(c_document);
156
+ if (c_current_root) {
157
+ xmlUnlinkNode(c_current_root);
158
+ noko_xml_document_pin_node(c_current_root);
135
159
  }
136
160
 
137
- Data_Get_Struct(root, xmlNode, new_root);
161
+ if (!NIL_P(rb_new_root)) {
162
+ if (!rb_obj_is_kind_of(rb_new_root, cNokogiriXmlNode)) {
163
+ rb_raise(rb_eArgError,
164
+ "expected Nokogiri::XML::Node but received %"PRIsVALUE,
165
+ rb_obj_class(rb_new_root));
166
+ }
138
167
 
168
+ Noko_Node_Get_Struct(rb_new_root, xmlNode, c_new_root);
139
169
 
140
- /* If the new root's document is not the same as the current document,
141
- * then we need to dup the node in to this document. */
142
- if(new_root->doc != doc) {
143
- old_root = xmlDocGetRootElement(doc);
144
- if (!(new_root = xmlDocCopyNode(new_root, doc, 1))) {
145
- rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
170
+ /* If the new root's document is not the same as the current document,
171
+ * then we need to dup the node in to this document. */
172
+ if (c_new_root->doc != c_document) {
173
+ c_new_root = xmlDocCopyNode(c_new_root, c_document, 1);
174
+ if (!c_new_root) {
175
+ rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
176
+ }
146
177
  }
147
178
  }
148
179
 
149
- xmlDocSetRootElement(doc, new_root);
150
- if(old_root) nokogiri_root_node(old_root);
151
- return root;
180
+ xmlDocSetRootElement(c_document, c_new_root);
181
+
182
+ return rb_new_root;
152
183
  }
153
184
 
154
185
  /*
@@ -157,17 +188,20 @@ static VALUE set_root(VALUE self, VALUE root)
157
188
  *
158
189
  * Get the root node for this document.
159
190
  */
160
- static VALUE root(VALUE self)
191
+ static VALUE
192
+ rb_xml_document_root(VALUE self)
161
193
  {
162
- xmlDocPtr doc;
163
- xmlNodePtr root;
194
+ xmlDocPtr c_document;
195
+ xmlNodePtr c_root;
164
196
 
165
- Data_Get_Struct(self, xmlDoc, doc);
197
+ Data_Get_Struct(self, xmlDoc, c_document);
166
198
 
167
- root = xmlDocGetRootElement(doc);
199
+ c_root = xmlDocGetRootElement(c_document);
200
+ if (!c_root) {
201
+ return Qnil;
202
+ }
168
203
 
169
- if(!root) return Qnil;
170
- return Nokogiri_wrap_xml_node(Qnil, root) ;
204
+ return noko_xml_node_wrap(Qnil, c_root) ;
171
205
  }
172
206
 
173
207
  /*
@@ -176,13 +210,15 @@ static VALUE root(VALUE self)
176
210
  *
177
211
  * Set the encoding string for this Document
178
212
  */
179
- static VALUE set_encoding(VALUE self, VALUE encoding)
213
+ static VALUE
214
+ set_encoding(VALUE self, VALUE encoding)
180
215
  {
181
216
  xmlDocPtr doc;
182
217
  Data_Get_Struct(self, xmlDoc, doc);
183
218
 
184
- if (doc->encoding)
185
- free((char *)(uintptr_t) doc->encoding); /* avoid gcc cast warning */
219
+ if (doc->encoding) {
220
+ xmlFree(DISCARD_CONST_QUAL_XMLCHAR(doc->encoding));
221
+ }
186
222
 
187
223
  doc->encoding = xmlStrdup((xmlChar *)StringValueCStr(encoding));
188
224
 
@@ -195,12 +231,13 @@ static VALUE set_encoding(VALUE self, VALUE encoding)
195
231
  *
196
232
  * Get the encoding for this Document
197
233
  */
198
- static VALUE encoding(VALUE self)
234
+ static VALUE
235
+ encoding(VALUE self)
199
236
  {
200
237
  xmlDocPtr doc;
201
238
  Data_Get_Struct(self, xmlDoc, doc);
202
239
 
203
- if(!doc->encoding) return Qnil;
240
+ if (!doc->encoding) { return Qnil; }
204
241
  return NOKOGIRI_STR_NEW2(doc->encoding);
205
242
  }
206
243
 
@@ -210,12 +247,13 @@ static VALUE encoding(VALUE self)
210
247
  *
211
248
  * Get the XML version for this Document
212
249
  */
213
- static VALUE version(VALUE self)
250
+ static VALUE
251
+ version(VALUE self)
214
252
  {
215
253
  xmlDocPtr doc;
216
254
  Data_Get_Struct(self, xmlDoc, doc);
217
255
 
218
- if(!doc->version) return Qnil;
256
+ if (!doc->version) { return Qnil; }
219
257
  return NOKOGIRI_STR_NEW2(doc->version);
220
258
  }
221
259
 
@@ -225,14 +263,15 @@ static VALUE version(VALUE self)
225
263
  *
226
264
  * Create a new document from an IO object
227
265
  */
228
- static VALUE read_io( VALUE klass,
229
- VALUE io,
230
- VALUE url,
231
- VALUE encoding,
232
- VALUE options )
266
+ static VALUE
267
+ read_io(VALUE klass,
268
+ VALUE io,
269
+ VALUE url,
270
+ VALUE encoding,
271
+ VALUE options)
233
272
  {
234
- const char * c_url = NIL_P(url) ? NULL : StringValueCStr(url);
235
- const char * c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
273
+ const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
274
+ const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
236
275
  VALUE error_list = rb_ary_new();
237
276
  VALUE document;
238
277
  xmlDocPtr doc;
@@ -241,30 +280,31 @@ static VALUE read_io( VALUE klass,
241
280
  xmlSetStructuredErrorFunc((void *)error_list, Nokogiri_error_array_pusher);
242
281
 
243
282
  doc = xmlReadIO(
244
- (xmlInputReadCallback)io_read_callback,
245
- (xmlInputCloseCallback)io_close_callback,
246
- (void *)io,
247
- c_url,
248
- c_enc,
249
- (int)NUM2INT(options)
250
- );
283
+ (xmlInputReadCallback)noko_io_read,
284
+ (xmlInputCloseCallback)noko_io_close,
285
+ (void *)io,
286
+ c_url,
287
+ c_enc,
288
+ (int)NUM2INT(options)
289
+ );
251
290
  xmlSetStructuredErrorFunc(NULL, NULL);
252
291
 
253
- if(doc == NULL) {
292
+ if (doc == NULL) {
254
293
  xmlErrorPtr error;
255
294
 
256
295
  xmlFreeDoc(doc);
257
296
 
258
297
  error = xmlGetLastError();
259
- if(error)
298
+ if (error) {
260
299
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
261
- else
300
+ } else {
262
301
  rb_raise(rb_eRuntimeError, "Could not parse document");
302
+ }
263
303
 
264
304
  return Qnil;
265
305
  }
266
306
 
267
- document = Nokogiri_wrap_xml_document(klass, doc);
307
+ document = noko_xml_document_wrap(klass, doc);
268
308
  rb_iv_set(document, "@errors", error_list);
269
309
  return document;
270
310
  }
@@ -275,15 +315,16 @@ static VALUE read_io( VALUE klass,
275
315
  *
276
316
  * Create a new document from a String
277
317
  */
278
- static VALUE read_memory( VALUE klass,
279
- VALUE string,
280
- VALUE url,
281
- VALUE encoding,
282
- VALUE options )
318
+ static VALUE
319
+ read_memory(VALUE klass,
320
+ VALUE string,
321
+ VALUE url,
322
+ VALUE encoding,
323
+ VALUE options)
283
324
  {
284
- const char * c_buffer = StringValuePtr(string);
285
- const char * c_url = NIL_P(url) ? NULL : StringValueCStr(url);
286
- const char * c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
325
+ const char *c_buffer = StringValuePtr(string);
326
+ const char *c_url = NIL_P(url) ? NULL : StringValueCStr(url);
327
+ const char *c_enc = NIL_P(encoding) ? NULL : StringValueCStr(encoding);
287
328
  int len = (int)RSTRING_LEN(string);
288
329
  VALUE error_list = rb_ary_new();
289
330
  VALUE document;
@@ -294,21 +335,22 @@ static VALUE read_memory( VALUE klass,
294
335
  doc = xmlReadMemory(c_buffer, len, c_url, c_enc, (int)NUM2INT(options));
295
336
  xmlSetStructuredErrorFunc(NULL, NULL);
296
337
 
297
- if(doc == NULL) {
338
+ if (doc == NULL) {
298
339
  xmlErrorPtr error;
299
340
 
300
341
  xmlFreeDoc(doc);
301
342
 
302
343
  error = xmlGetLastError();
303
- if(error)
344
+ if (error) {
304
345
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
305
- else
346
+ } else {
306
347
  rb_raise(rb_eRuntimeError, "Could not parse document");
348
+ }
307
349
 
308
350
  return Qnil;
309
351
  }
310
352
 
311
- document = Nokogiri_wrap_xml_document(klass, doc);
353
+ document = noko_xml_document_wrap(klass, doc);
312
354
  rb_iv_set(document, "@errors", error_list);
313
355
  return document;
314
356
  }
@@ -320,26 +362,26 @@ static VALUE read_memory( VALUE klass,
320
362
  * Copy this Document. An optional depth may be passed in, but it defaults
321
363
  * to a deep copy. 0 is a shallow copy, 1 is a deep copy.
322
364
  */
323
- static VALUE duplicate_document(int argc, VALUE *argv, VALUE self)
365
+ static VALUE
366
+ duplicate_document(int argc, VALUE *argv, VALUE self)
324
367
  {
325
368
  xmlDocPtr doc, dup;
326
369
  VALUE copy;
327
370
  VALUE level;
328
- VALUE error_list;
329
371
 
330
- if(rb_scan_args(argc, argv, "01", &level) == 0)
372
+ if (rb_scan_args(argc, argv, "01", &level) == 0) {
331
373
  level = INT2NUM((long)1);
374
+ }
332
375
 
333
376
  Data_Get_Struct(self, xmlDoc, doc);
334
377
 
335
378
  dup = xmlCopyDoc(doc, (int)NUM2INT(level));
336
379
 
337
- if(dup == NULL) return Qnil;
380
+ if (dup == NULL) { return Qnil; }
338
381
 
339
382
  dup->type = doc->type;
340
- copy = Nokogiri_wrap_xml_document(rb_obj_class(self), dup);
341
- error_list = rb_iv_get(self, "@errors");
342
- rb_iv_set(copy, "@errors", error_list);
383
+ copy = noko_xml_document_wrap(rb_obj_class(self), dup);
384
+ rb_iv_set(copy, "@errors", rb_iv_get(self, "@errors"));
343
385
  return copy ;
344
386
  }
345
387
 
@@ -349,18 +391,18 @@ static VALUE duplicate_document(int argc, VALUE *argv, VALUE self)
349
391
  *
350
392
  * Create a new document with +version+ (defaults to "1.0")
351
393
  */
352
- static VALUE new(int argc, VALUE *argv, VALUE klass)
394
+ static VALUE
395
+ new (int argc, VALUE *argv, VALUE klass)
353
396
  {
354
397
  xmlDocPtr doc;
355
398
  VALUE version, rest, rb_doc ;
356
399
 
357
400
  rb_scan_args(argc, argv, "0*", &rest);
358
401
  version = rb_ary_entry(rest, (long)0);
359
- if (NIL_P(version)) version = rb_str_new2("1.0");
402
+ if (NIL_P(version)) { version = rb_str_new2("1.0"); }
360
403
 
361
404
  doc = xmlNewDoc((xmlChar *)StringValueCStr(version));
362
- rb_doc = Nokogiri_wrap_xml_document(klass, doc);
363
- rb_obj_call_init(rb_doc, argc, argv);
405
+ rb_doc = noko_xml_document_wrap_with_init_args(klass, doc, argc, argv);
364
406
  return rb_doc ;
365
407
  }
366
408
 
@@ -401,7 +443,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
401
443
  * please direct your browser to
402
444
  * http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
403
445
  */
404
- VALUE remove_namespaces_bang(VALUE self)
446
+ static VALUE
447
+ remove_namespaces_bang(VALUE self)
405
448
  {
406
449
  xmlDocPtr doc ;
407
450
  Data_Get_Struct(self, xmlDoc, doc);
@@ -421,7 +464,8 @@ VALUE remove_namespaces_bang(VALUE self)
421
464
  * +external_id+, +system_id+, and +content+ set the External ID, System ID,
422
465
  * and content respectively. All of these parameters are optional.
423
466
  */
424
- static VALUE create_entity(int argc, VALUE *argv, VALUE self)
467
+ static VALUE
468
+ create_entity(int argc, VALUE *argv, VALUE self)
425
469
  {
426
470
  VALUE name;
427
471
  VALUE type;
@@ -434,52 +478,50 @@ static VALUE create_entity(int argc, VALUE *argv, VALUE self)
434
478
  Data_Get_Struct(self, xmlDoc, doc);
435
479
 
436
480
  rb_scan_args(argc, argv, "14", &name, &type, &external_id, &system_id,
437
- &content);
481
+ &content);
438
482
 
439
483
  xmlResetLastError();
440
484
  ptr = xmlAddDocEntity(
441
- doc,
442
- (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
443
- (int) (NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
444
- (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
445
- (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
446
- (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
447
- );
448
-
449
- if(NULL == ptr) {
485
+ doc,
486
+ (xmlChar *)(NIL_P(name) ? NULL : StringValueCStr(name)),
487
+ (int)(NIL_P(type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(type)),
488
+ (xmlChar *)(NIL_P(external_id) ? NULL : StringValueCStr(external_id)),
489
+ (xmlChar *)(NIL_P(system_id) ? NULL : StringValueCStr(system_id)),
490
+ (xmlChar *)(NIL_P(content) ? NULL : StringValueCStr(content))
491
+ );
492
+
493
+ if (NULL == ptr) {
450
494
  xmlErrorPtr error = xmlGetLastError();
451
- if(error)
495
+ if (error) {
452
496
  rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
453
- else
497
+ } else {
454
498
  rb_raise(rb_eRuntimeError, "Could not create entity");
499
+ }
455
500
 
456
501
  return Qnil;
457
502
  }
458
503
 
459
- return Nokogiri_wrap_xml_node(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
504
+ return noko_xml_node_wrap(cNokogiriXmlEntityDecl, (xmlNodePtr)ptr);
460
505
  }
461
506
 
462
- static int block_caller(void * ctx, xmlNodePtr _node, xmlNodePtr _parent)
507
+ static int
508
+ block_caller(void *ctx, xmlNodePtr c_node, xmlNodePtr c_parent_node)
463
509
  {
464
- VALUE block;
465
- VALUE node;
466
- VALUE parent;
510
+ VALUE block = (VALUE)ctx;
511
+ VALUE rb_node;
512
+ VALUE rb_parent_node;
467
513
  VALUE ret;
468
514
 
469
- if(_node->type == XML_NAMESPACE_DECL){
470
- node = Nokogiri_wrap_xml_namespace(_parent->doc, (xmlNsPtr) _node);
471
- }
472
- else{
473
- node = Nokogiri_wrap_xml_node(Qnil, _node);
515
+ if (c_node->type == XML_NAMESPACE_DECL) {
516
+ rb_node = noko_xml_namespace_wrap((xmlNsPtr)c_node, c_parent_node->doc);
517
+ } else {
518
+ rb_node = noko_xml_node_wrap(Qnil, c_node);
474
519
  }
475
- parent = _parent ? Nokogiri_wrap_xml_node(Qnil, _parent) : Qnil;
476
- block = (VALUE)ctx;
520
+ rb_parent_node = c_parent_node ? noko_xml_node_wrap(Qnil, c_parent_node) : Qnil;
477
521
 
478
- ret = rb_funcall(block, rb_intern("call"), 2, node, parent);
522
+ ret = rb_funcall(block, rb_intern("call"), 2, rb_node, rb_parent_node);
479
523
 
480
- if(Qfalse == ret || Qnil == ret) return 0;
481
-
482
- return 1;
524
+ return (Qfalse == ret || Qnil == ret) ? 0 : 1;
483
525
  }
484
526
 
485
527
  /* call-seq:
@@ -492,117 +534,151 @@ static int block_caller(void * ctx, xmlNodePtr _node, xmlNodePtr _parent)
492
534
  * The block must return a non-nil, non-false value if the +obj+ passed in
493
535
  * should be included in the canonicalized document.
494
536
  */
495
- static VALUE canonicalize(int argc, VALUE* argv, VALUE self)
537
+ static VALUE
538
+ rb_xml_document_canonicalize(int argc, VALUE *argv, VALUE self)
496
539
  {
497
- VALUE mode;
498
- VALUE incl_ns;
499
- VALUE with_comments;
500
- xmlChar **ns;
501
- long ns_len, i;
540
+ VALUE rb_mode;
541
+ VALUE rb_namespaces;
542
+ VALUE rb_comments_p;
543
+ xmlChar **c_namespaces;
502
544
 
503
- xmlDocPtr doc;
504
- xmlOutputBufferPtr buf;
505
- xmlC14NIsVisibleCallback cb = NULL;
506
- void * ctx = NULL;
545
+ xmlDocPtr c_doc;
546
+ xmlOutputBufferPtr c_obuf;
547
+ xmlC14NIsVisibleCallback c_callback_wrapper = NULL;
548
+ void *rb_callback = NULL;
507
549
 
508
550
  VALUE rb_cStringIO;
509
- VALUE io;
551
+ VALUE rb_io;
510
552
 
511
- rb_scan_args(argc, argv, "03", &mode, &incl_ns, &with_comments);
553
+ rb_scan_args(argc, argv, "03", &rb_mode, &rb_namespaces, &rb_comments_p);
554
+ if (!NIL_P(rb_mode)) { Check_Type(rb_mode, T_FIXNUM); }
555
+ if (!NIL_P(rb_namespaces)) { Check_Type(rb_namespaces, T_ARRAY); }
512
556
 
513
- Data_Get_Struct(self, xmlDoc, doc);
557
+ Data_Get_Struct(self, xmlDoc, c_doc);
514
558
 
515
559
  rb_cStringIO = rb_const_get_at(rb_cObject, rb_intern("StringIO"));
516
- io = rb_class_new_instance(0, 0, rb_cStringIO);
517
- buf = xmlAllocOutputBuffer(NULL);
560
+ rb_io = rb_class_new_instance(0, 0, rb_cStringIO);
561
+ c_obuf = xmlAllocOutputBuffer(NULL);
518
562
 
519
- buf->writecallback = (xmlOutputWriteCallback)io_write_callback;
520
- buf->closecallback = (xmlOutputCloseCallback)io_close_callback;
521
- buf->context = (void *)io;
563
+ c_obuf->writecallback = (xmlOutputWriteCallback)noko_io_write;
564
+ c_obuf->closecallback = (xmlOutputCloseCallback)noko_io_close;
565
+ c_obuf->context = (void *)rb_io;
522
566
 
523
- if(rb_block_given_p()) {
524
- cb = block_caller;
525
- ctx = (void *)rb_block_proc();
567
+ if (rb_block_given_p()) {
568
+ c_callback_wrapper = block_caller;
569
+ rb_callback = (void *)rb_block_proc();
526
570
  }
527
571
 
528
- if(NIL_P(incl_ns)){
529
- ns = NULL;
530
- }
531
- else{
532
- Check_Type(incl_ns, T_ARRAY);
533
- ns_len = RARRAY_LEN(incl_ns);
534
- ns = calloc((size_t)ns_len+1, sizeof(xmlChar *));
535
- for (i = 0 ; i < ns_len ; i++) {
536
- VALUE entry = rb_ary_entry(incl_ns, i);
537
- ns[i] = (xmlChar*)StringValueCStr(entry);
572
+ if (NIL_P(rb_namespaces)) {
573
+ c_namespaces = NULL;
574
+ } else {
575
+ long ns_len = RARRAY_LEN(rb_namespaces);
576
+ c_namespaces = calloc((size_t)ns_len + 1, sizeof(xmlChar *));
577
+ for (int j = 0 ; j < ns_len ; j++) {
578
+ VALUE entry = rb_ary_entry(rb_namespaces, j);
579
+ c_namespaces[j] = (xmlChar *)StringValueCStr(entry);
538
580
  }
539
581
  }
540
582
 
583
+ xmlC14NExecute(c_doc, c_callback_wrapper, rb_callback,
584
+ (int)(NIL_P(rb_mode) ? 0 : NUM2INT(rb_mode)),
585
+ c_namespaces,
586
+ (int)RTEST(rb_comments_p),
587
+ c_obuf);
541
588
 
542
- xmlC14NExecute(doc, cb, ctx,
543
- (int) (NIL_P(mode) ? 0 : NUM2INT(mode)),
544
- ns,
545
- (int) RTEST(with_comments),
546
- buf);
589
+ free(c_namespaces);
590
+ xmlOutputBufferClose(c_obuf);
547
591
 
548
- xmlOutputBufferClose(buf);
592
+ return rb_funcall(rb_io, rb_intern("string"), 0);
593
+ }
594
+
595
+ VALUE
596
+ noko_xml_document_wrap_with_init_args(VALUE klass, xmlDocPtr c_document, int argc, VALUE *argv)
597
+ {
598
+ VALUE rb_document;
599
+ nokogiriTuplePtr tuple;
600
+
601
+ if (!klass) {
602
+ klass = cNokogiriXmlDocument;
603
+ }
549
604
 
550
- return rb_funcall(io, rb_intern("string"), 0);
605
+ rb_document = Data_Wrap_Struct(klass, mark, dealloc, c_document);
606
+
607
+ tuple = (nokogiriTuplePtr)malloc(sizeof(nokogiriTuple));
608
+ tuple->doc = rb_document;
609
+ tuple->unlinkedNodes = st_init_numtable_with_size(128);
610
+ tuple->node_cache = rb_ary_new();
611
+
612
+ c_document->_private = tuple ;
613
+
614
+ rb_iv_set(rb_document, "@decorators", Qnil);
615
+ rb_iv_set(rb_document, "@errors", Qnil);
616
+ rb_iv_set(rb_document, "@node_cache", tuple->node_cache);
617
+
618
+ rb_obj_call_init(rb_document, argc, argv);
619
+
620
+ return rb_document ;
551
621
  }
552
622
 
553
- VALUE cNokogiriXmlDocument ;
554
- void init_xml_document()
623
+
624
+ /* deprecated. use noko_xml_document_wrap() instead. */
625
+ VALUE
626
+ Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
555
627
  {
556
- VALUE nokogiri = rb_define_module("Nokogiri");
557
- VALUE xml = rb_define_module_under(nokogiri, "XML");
558
- VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
628
+ /* TODO: deprecate this method in v2.0 */
629
+ return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL);
630
+ }
559
631
 
560
- /*
561
- * Nokogiri::XML::Document wraps an xml document.
562
- */
563
- VALUE klass = rb_define_class_under(xml, "Document", node);
564
-
565
- cNokogiriXmlDocument = klass;
566
-
567
- rb_define_singleton_method(klass, "read_memory", read_memory, 4);
568
- rb_define_singleton_method(klass, "read_io", read_io, 4);
569
- rb_define_singleton_method(klass, "new", new, -1);
570
-
571
- rb_define_method(klass, "root", root, 0);
572
- rb_define_method(klass, "root=", set_root, 1);
573
- rb_define_method(klass, "encoding", encoding, 0);
574
- rb_define_method(klass, "encoding=", set_encoding, 1);
575
- rb_define_method(klass, "version", version, 0);
576
- rb_define_method(klass, "canonicalize", canonicalize, -1);
577
- rb_define_method(klass, "dup", duplicate_document, -1);
578
- rb_define_method(klass, "url", url, 0);
579
- rb_define_method(klass, "create_entity", create_entity, -1);
580
- rb_define_method(klass, "remove_namespaces!", remove_namespaces_bang, 0);
632
+ VALUE
633
+ noko_xml_document_wrap(VALUE klass, xmlDocPtr doc)
634
+ {
635
+ return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL);
581
636
  }
582
637
 
583
638
 
584
- /* this takes klass as a param because it's used for HtmlDocument, too. */
585
- VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
639
+ void
640
+ noko_xml_document_pin_node(xmlNodePtr node)
586
641
  {
587
- nokogiriTuplePtr tuple = (nokogiriTuplePtr)malloc(sizeof(nokogiriTuple));
642
+ xmlDocPtr doc;
643
+ nokogiriTuplePtr tuple;
588
644
 
589
- VALUE rb_doc = Data_Wrap_Struct(
590
- klass ? klass : cNokogiriXmlDocument,
591
- 0,
592
- dealloc,
593
- doc
594
- );
645
+ doc = node->doc;
646
+ tuple = (nokogiriTuplePtr)doc->_private;
647
+ st_insert(tuple->unlinkedNodes, (st_data_t)node, (st_data_t)node);
648
+ }
595
649
 
596
- VALUE cache = rb_ary_new();
597
- rb_iv_set(rb_doc, "@decorators", Qnil);
598
- rb_iv_set(rb_doc, "@node_cache", cache);
599
650
 
600
- tuple->doc = rb_doc;
601
- tuple->unlinkedNodes = st_init_numtable_with_size(128);
602
- tuple->node_cache = cache;
603
- doc->_private = tuple ;
651
+ void
652
+ noko_xml_document_pin_namespace(xmlNsPtr ns, xmlDocPtr doc)
653
+ {
654
+ nokogiriTuplePtr tuple;
655
+
656
+ tuple = (nokogiriTuplePtr)doc->_private;
657
+ st_insert(tuple->unlinkedNodes, (st_data_t)ns, (st_data_t)ns);
658
+ }
604
659
 
605
- rb_obj_call_init(rb_doc, 0, NULL);
606
660
 
607
- return rb_doc ;
661
+ void
662
+ noko_init_xml_document()
663
+ {
664
+ assert(cNokogiriXmlNode);
665
+ /*
666
+ * Nokogiri::XML::Document wraps an xml document.
667
+ */
668
+ cNokogiriXmlDocument = rb_define_class_under(mNokogiriXml, "Document", cNokogiriXmlNode);
669
+
670
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_memory", read_memory, 4);
671
+ rb_define_singleton_method(cNokogiriXmlDocument, "read_io", read_io, 4);
672
+ rb_define_singleton_method(cNokogiriXmlDocument, "new", new, -1);
673
+
674
+ rb_define_method(cNokogiriXmlDocument, "root", rb_xml_document_root, 0);
675
+ rb_define_method(cNokogiriXmlDocument, "root=", rb_xml_document_root_set, 1);
676
+ rb_define_method(cNokogiriXmlDocument, "encoding", encoding, 0);
677
+ rb_define_method(cNokogiriXmlDocument, "encoding=", set_encoding, 1);
678
+ rb_define_method(cNokogiriXmlDocument, "version", version, 0);
679
+ rb_define_method(cNokogiriXmlDocument, "canonicalize", rb_xml_document_canonicalize, -1);
680
+ rb_define_method(cNokogiriXmlDocument, "dup", duplicate_document, -1);
681
+ rb_define_method(cNokogiriXmlDocument, "url", url, 0);
682
+ rb_define_method(cNokogiriXmlDocument, "create_entity", create_entity, -1);
683
+ rb_define_method(cNokogiriXmlDocument, "remove_namespaces!", remove_namespaces_bang, 0);
608
684
  }