nokogiri 1.11.0-x86-linux → 1.11.5-x86-linux
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.
- checksums.yaml +4 -4
- data/LICENSE-DEPENDENCIES.md +12 -12
- data/LICENSE.md +1 -1
- data/README.md +21 -16
- data/dependencies.yml +12 -12
- data/ext/nokogiri/depend +34 -474
- data/ext/nokogiri/extconf.rb +253 -183
- data/ext/nokogiri/html_document.c +10 -15
- data/ext/nokogiri/html_element_description.c +84 -71
- data/ext/nokogiri/html_entity_lookup.c +21 -16
- data/ext/nokogiri/html_sax_parser_context.c +67 -64
- data/ext/nokogiri/html_sax_push_parser.c +42 -34
- data/ext/nokogiri/include/libxml2/libxml/c14n.h +6 -4
- data/ext/nokogiri/include/libxml2/libxml/parser.h +9 -7
- data/ext/nokogiri/include/libxml2/libxml/tree.h +3 -3
- data/ext/nokogiri/include/libxml2/libxml/xmlIO.h +2 -0
- data/ext/nokogiri/include/libxml2/libxml/xmlexports.h +39 -115
- data/ext/nokogiri/include/libxml2/libxml/xmlschemas.h +1 -1
- data/ext/nokogiri/include/libxml2/libxml/xmlversion.h +6 -6
- data/ext/nokogiri/include/libxml2/libxml/xpath.h +1 -3
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +190 -60
- data/ext/nokogiri/nokogiri.h +158 -75
- data/ext/nokogiri/test_global_handlers.c +40 -0
- data/ext/nokogiri/xml_attr.c +15 -15
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +13 -18
- data/ext/nokogiri/xml_comment.c +19 -26
- data/ext/nokogiri/xml_document.c +246 -188
- data/ext/nokogiri/xml_document_fragment.c +13 -15
- data/ext/nokogiri/xml_dtd.c +54 -48
- data/ext/nokogiri/xml_element_content.c +30 -27
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +17 -11
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +56 -49
- data/ext/nokogiri/xml_node.c +371 -320
- data/ext/nokogiri/xml_node_set.c +168 -156
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +191 -157
- data/ext/nokogiri/xml_relax_ng.c +29 -23
- data/ext/nokogiri/xml_sax_parser.c +117 -112
- data/ext/nokogiri/xml_sax_parser_context.c +101 -84
- data/ext/nokogiri/xml_sax_push_parser.c +36 -27
- data/ext/nokogiri/xml_schema.c +48 -42
- data/ext/nokogiri/xml_syntax_error.c +42 -21
- data/ext/nokogiri/xml_text.c +13 -17
- data/ext/nokogiri/xml_xpath_context.c +134 -127
- data/ext/nokogiri/xslt_stylesheet.c +157 -157
- data/lib/nokogiri.rb +1 -22
- data/lib/nokogiri/2.5/nokogiri.so +0 -0
- data/lib/nokogiri/2.6/nokogiri.so +0 -0
- data/lib/nokogiri/2.7/nokogiri.so +0 -0
- data/lib/nokogiri/3.0/nokogiri.so +0 -0
- data/lib/nokogiri/css/parser.rb +1 -1
- data/lib/nokogiri/extension.rb +26 -0
- data/lib/nokogiri/html/document_fragment.rb +15 -15
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/version/info.rb +32 -8
- data/lib/nokogiri/xml/document.rb +74 -28
- data/lib/nokogiri/xml/node.rb +39 -42
- data/lib/nokogiri/xml/reader.rb +2 -9
- data/lib/nokogiri/xml/xpath.rb +1 -3
- data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
- metadata +11 -43
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_attr.h +0 -9
- data/ext/nokogiri/xml_attribute_decl.h +0 -9
- data/ext/nokogiri/xml_cdata.h +0 -9
- data/ext/nokogiri/xml_comment.h +0 -9
- data/ext/nokogiri/xml_document.h +0 -23
- data/ext/nokogiri/xml_document_fragment.h +0 -10
- data/ext/nokogiri/xml_dtd.h +0 -10
- data/ext/nokogiri/xml_element_content.h +0 -10
- data/ext/nokogiri/xml_element_decl.h +0 -9
- data/ext/nokogiri/xml_encoding_handler.h +0 -8
- data/ext/nokogiri/xml_entity_decl.h +0 -10
- data/ext/nokogiri/xml_entity_reference.h +0 -9
- data/ext/nokogiri/xml_io.c +0 -63
- data/ext/nokogiri/xml_io.h +0 -11
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
- data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
- data/ext/nokogiri/xml_namespace.h +0 -14
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -12
- data/ext/nokogiri/xml_processing_instruction.h +0 -9
- data/ext/nokogiri/xml_reader.h +0 -10
- data/ext/nokogiri/xml_relax_ng.h +0 -9
- data/ext/nokogiri/xml_sax_parser.h +0 -39
- data/ext/nokogiri/xml_sax_parser_context.h +0 -10
- data/ext/nokogiri/xml_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_schema.h +0 -9
- data/ext/nokogiri/xml_syntax_error.h +0 -13
- data/ext/nokogiri/xml_text.h +0 -9
- data/ext/nokogiri/xml_xpath_context.h +0 -10
- data/ext/nokogiri/xslt_stylesheet.h +0 -14
data/ext/nokogiri/xml_node_set.c
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
#include <
|
2
|
-
#include <xml_namespace.h>
|
3
|
-
#include <libxml/xpathInternals.h>
|
1
|
+
#include <nokogiri.h>
|
4
2
|
|
5
|
-
|
6
|
-
static void xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val);
|
3
|
+
VALUE cNokogiriXmlNodeSet ;
|
7
4
|
|
5
|
+
static ID decorate ;
|
8
6
|
|
9
|
-
static void
|
7
|
+
static void
|
8
|
+
Check_Node_Set_Node_Type(VALUE node)
|
10
9
|
{
|
11
10
|
if (!(rb_obj_is_kind_of(node, cNokogiriXmlNode) ||
|
12
11
|
rb_obj_is_kind_of(node, cNokogiriXmlNamespace))) {
|
@@ -15,34 +14,94 @@ static void Check_Node_Set_Node_Type(VALUE node)
|
|
15
14
|
}
|
16
15
|
|
17
16
|
|
18
|
-
static
|
17
|
+
static
|
18
|
+
VALUE
|
19
|
+
ruby_object_get(xmlNodePtr c_node)
|
20
|
+
{
|
21
|
+
/* see xmlElementType in libxml2 tree.h */
|
22
|
+
switch (c_node->type) {
|
23
|
+
case XML_NAMESPACE_DECL:
|
24
|
+
/* _private is later in the namespace struct */
|
25
|
+
return (VALUE)(((xmlNsPtr)c_node)->_private);
|
26
|
+
|
27
|
+
case XML_DOCUMENT_NODE:
|
28
|
+
case XML_HTML_DOCUMENT_NODE:
|
29
|
+
/* in documents we use _private to store a tuple */
|
30
|
+
if (DOC_RUBY_OBJECT_TEST(((xmlDocPtr)c_node))) {
|
31
|
+
return DOC_RUBY_OBJECT((xmlDocPtr)c_node);
|
32
|
+
}
|
33
|
+
return (VALUE)NULL;
|
34
|
+
|
35
|
+
default:
|
36
|
+
return (VALUE)(c_node->_private);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
static void
|
42
|
+
mark(xmlNodeSetPtr node_set)
|
43
|
+
{
|
44
|
+
VALUE rb_node;
|
45
|
+
int jnode;
|
46
|
+
|
47
|
+
for (jnode = 0; jnode < node_set->nodeNr; jnode++) {
|
48
|
+
rb_node = ruby_object_get(node_set->nodeTab[jnode]);
|
49
|
+
if (rb_node) {
|
50
|
+
rb_gc_mark(rb_node);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
static void
|
56
|
+
xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val)
|
57
|
+
{
|
58
|
+
/*
|
59
|
+
* For reasons outlined in xml_namespace.c, here we reproduce xmlXPathNodeSetDel() except for the
|
60
|
+
* offending call to xmlXPathNodeSetFreeNs().
|
61
|
+
*/
|
62
|
+
int i;
|
63
|
+
|
64
|
+
if (cur == NULL) { return; }
|
65
|
+
if (val == NULL) { return; }
|
66
|
+
|
67
|
+
/*
|
68
|
+
* find node in nodeTab
|
69
|
+
*/
|
70
|
+
for (i = 0; i < cur->nodeNr; i++)
|
71
|
+
if (cur->nodeTab[i] == val) { break; }
|
72
|
+
|
73
|
+
if (i >= cur->nodeNr) { /* not found */
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
cur->nodeNr--;
|
77
|
+
for (; i < cur->nodeNr; i++) {
|
78
|
+
cur->nodeTab[i] = cur->nodeTab[i + 1];
|
79
|
+
}
|
80
|
+
cur->nodeTab[cur->nodeNr] = NULL;
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
static void
|
85
|
+
deallocate(xmlNodeSetPtr node_set)
|
19
86
|
{
|
20
87
|
/*
|
21
|
-
*
|
22
|
-
*
|
23
|
-
* xmlXPathFreeNodeSet() frees those xmlNs structs that are in the
|
24
|
-
* NodeSet.
|
25
|
-
*
|
26
|
-
* this is bad if someone is still trying to use the Namespace object wrapped
|
27
|
-
* around the xmlNs, so we need to avoid that.
|
28
|
-
*
|
29
|
-
* here we reproduce xmlXPathFreeNodeSet() without the xmlNs logic.
|
30
|
-
*
|
31
|
-
* this doesn't cause a leak because Namespace objects that are in an XPath
|
32
|
-
* query NodeSet are given their own lifecycle in
|
33
|
-
* Nokogiri_wrap_xml_namespace().
|
88
|
+
* For reasons outlined in xml_namespace.c, here we reproduce xmlXPathFreeNodeSet() except for the
|
89
|
+
* offending call to xmlXPathNodeSetFreeNs().
|
34
90
|
*/
|
35
91
|
NOKOGIRI_DEBUG_START(node_set) ;
|
36
|
-
if (node_set->nodeTab != NULL)
|
92
|
+
if (node_set->nodeTab != NULL) {
|
37
93
|
xmlFree(node_set->nodeTab);
|
94
|
+
}
|
38
95
|
|
39
96
|
xmlFree(node_set);
|
40
97
|
NOKOGIRI_DEBUG_END(node_set) ;
|
41
98
|
}
|
42
99
|
|
43
|
-
|
100
|
+
|
101
|
+
static VALUE
|
102
|
+
allocate(VALUE klass)
|
44
103
|
{
|
45
|
-
return
|
104
|
+
return noko_xml_node_set_wrap(xmlXPathNodeSetCreate(NULL), Qnil);
|
46
105
|
}
|
47
106
|
|
48
107
|
|
@@ -53,7 +112,8 @@ static VALUE allocate(VALUE klass)
|
|
53
112
|
* Duplicate this NodeSet. Note that the Nodes contained in the NodeSet are not
|
54
113
|
* duplicated (similar to how Array and other Enumerable classes work).
|
55
114
|
*/
|
56
|
-
static VALUE
|
115
|
+
static VALUE
|
116
|
+
duplicate(VALUE self)
|
57
117
|
{
|
58
118
|
xmlNodeSetPtr node_set;
|
59
119
|
xmlNodeSetPtr dupl;
|
@@ -62,7 +122,7 @@ static VALUE duplicate(VALUE self)
|
|
62
122
|
|
63
123
|
dupl = xmlXPathNodeSetMerge(NULL, node_set);
|
64
124
|
|
65
|
-
return
|
125
|
+
return noko_xml_node_set_wrap(dupl, rb_iv_get(self, "@document"));
|
66
126
|
}
|
67
127
|
|
68
128
|
/*
|
@@ -71,7 +131,8 @@ static VALUE duplicate(VALUE self)
|
|
71
131
|
*
|
72
132
|
* Get the length of the node set
|
73
133
|
*/
|
74
|
-
static VALUE
|
134
|
+
static VALUE
|
135
|
+
length(VALUE self)
|
75
136
|
{
|
76
137
|
xmlNodeSetPtr node_set;
|
77
138
|
|
@@ -86,7 +147,8 @@ static VALUE length(VALUE self)
|
|
86
147
|
*
|
87
148
|
* Append +node+ to the NodeSet.
|
88
149
|
*/
|
89
|
-
static VALUE
|
150
|
+
static VALUE
|
151
|
+
push(VALUE self, VALUE rb_node)
|
90
152
|
{
|
91
153
|
xmlNodeSetPtr node_set;
|
92
154
|
xmlNodePtr node;
|
@@ -109,7 +171,7 @@ static VALUE push(VALUE self, VALUE rb_node)
|
|
109
171
|
* if found, otherwise returns nil.
|
110
172
|
*/
|
111
173
|
static VALUE
|
112
|
-
delete(VALUE self, VALUE rb_node)
|
174
|
+
delete (VALUE self, VALUE rb_node)
|
113
175
|
{
|
114
176
|
xmlNodeSetPtr node_set;
|
115
177
|
xmlNodePtr node;
|
@@ -133,19 +195,21 @@ delete(VALUE self, VALUE rb_node)
|
|
133
195
|
*
|
134
196
|
* Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets.
|
135
197
|
*/
|
136
|
-
static VALUE
|
198
|
+
static VALUE
|
199
|
+
intersection(VALUE self, VALUE rb_other)
|
137
200
|
{
|
138
201
|
xmlNodeSetPtr node_set, other ;
|
139
202
|
xmlNodeSetPtr intersection;
|
140
203
|
|
141
|
-
if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
|
204
|
+
if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
|
142
205
|
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
206
|
+
}
|
143
207
|
|
144
208
|
Data_Get_Struct(self, xmlNodeSet, node_set);
|
145
209
|
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
146
210
|
|
147
211
|
intersection = xmlXPathIntersection(node_set, other);
|
148
|
-
return
|
212
|
+
return noko_xml_node_set_wrap(intersection, rb_iv_get(self, "@document"));
|
149
213
|
}
|
150
214
|
|
151
215
|
|
@@ -155,7 +219,8 @@ static VALUE intersection(VALUE self, VALUE rb_other)
|
|
155
219
|
*
|
156
220
|
* Returns true if any member of node set equals +node+.
|
157
221
|
*/
|
158
|
-
static VALUE
|
222
|
+
static VALUE
|
223
|
+
include_eh(VALUE self, VALUE rb_node)
|
159
224
|
{
|
160
225
|
xmlNodeSetPtr node_set;
|
161
226
|
xmlNodePtr node;
|
@@ -176,21 +241,23 @@ static VALUE include_eh(VALUE self, VALUE rb_node)
|
|
176
241
|
* Returns a new set built by merging the set and the elements of the given
|
177
242
|
* set.
|
178
243
|
*/
|
179
|
-
static VALUE
|
244
|
+
static VALUE
|
245
|
+
rb_xml_node_set_union(VALUE rb_node_set, VALUE rb_other)
|
180
246
|
{
|
181
|
-
xmlNodeSetPtr
|
182
|
-
xmlNodeSetPtr
|
247
|
+
xmlNodeSetPtr c_node_set, c_other;
|
248
|
+
xmlNodeSetPtr c_new_node_set;
|
183
249
|
|
184
|
-
if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
|
250
|
+
if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
|
185
251
|
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
252
|
+
}
|
186
253
|
|
187
|
-
Data_Get_Struct(
|
188
|
-
Data_Get_Struct(rb_other, xmlNodeSet,
|
254
|
+
Data_Get_Struct(rb_node_set, xmlNodeSet, c_node_set);
|
255
|
+
Data_Get_Struct(rb_other, xmlNodeSet, c_other);
|
189
256
|
|
190
|
-
|
191
|
-
|
257
|
+
c_new_node_set = xmlXPathNodeSetMerge(NULL, c_node_set);
|
258
|
+
c_new_node_set = xmlXPathNodeSetMerge(c_new_node_set, c_other);
|
192
259
|
|
193
|
-
return
|
260
|
+
return noko_xml_node_set_wrap(c_new_node_set, rb_iv_get(rb_node_set, "@document"));
|
194
261
|
}
|
195
262
|
|
196
263
|
/*
|
@@ -200,14 +267,16 @@ static VALUE set_union(VALUE self, VALUE rb_other)
|
|
200
267
|
* Difference - returns a new NodeSet that is a copy of this NodeSet, removing
|
201
268
|
* each item that also appears in +node_set+
|
202
269
|
*/
|
203
|
-
static VALUE
|
270
|
+
static VALUE
|
271
|
+
minus(VALUE self, VALUE rb_other)
|
204
272
|
{
|
205
273
|
xmlNodeSetPtr node_set, other;
|
206
274
|
xmlNodeSetPtr new;
|
207
275
|
int j ;
|
208
276
|
|
209
|
-
if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
|
277
|
+
if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) {
|
210
278
|
rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
|
279
|
+
}
|
211
280
|
|
212
281
|
Data_Get_Struct(self, xmlNodeSet, node_set);
|
213
282
|
Data_Get_Struct(rb_other, xmlNodeSet, other);
|
@@ -217,11 +286,12 @@ static VALUE minus(VALUE self, VALUE rb_other)
|
|
217
286
|
xpath_node_set_del(new, other->nodeTab[j]);
|
218
287
|
}
|
219
288
|
|
220
|
-
return
|
289
|
+
return noko_xml_node_set_wrap(new, rb_iv_get(self, "@document"));
|
221
290
|
}
|
222
291
|
|
223
292
|
|
224
|
-
static VALUE
|
293
|
+
static VALUE
|
294
|
+
index_at(VALUE self, long offset)
|
225
295
|
{
|
226
296
|
xmlNodeSetPtr node_set;
|
227
297
|
|
@@ -233,10 +303,11 @@ static VALUE index_at(VALUE self, long offset)
|
|
233
303
|
|
234
304
|
if (offset < 0) { offset += node_set->nodeNr ; }
|
235
305
|
|
236
|
-
return
|
306
|
+
return noko_xml_node_wrap_node_set_result(node_set->nodeTab[offset], self);
|
237
307
|
}
|
238
308
|
|
239
|
-
static VALUE
|
309
|
+
static VALUE
|
310
|
+
subseq(VALUE self, long beg, long len)
|
240
311
|
{
|
241
312
|
long j;
|
242
313
|
xmlNodeSetPtr node_set;
|
@@ -244,18 +315,18 @@ static VALUE subseq(VALUE self, long beg, long len)
|
|
244
315
|
|
245
316
|
Data_Get_Struct(self, xmlNodeSet, node_set);
|
246
317
|
|
247
|
-
if (beg > node_set->nodeNr) return Qnil ;
|
248
|
-
if (beg < 0 || len < 0) return Qnil ;
|
318
|
+
if (beg > node_set->nodeNr) { return Qnil ; }
|
319
|
+
if (beg < 0 || len < 0) { return Qnil ; }
|
249
320
|
|
250
321
|
if ((beg + len) > node_set->nodeNr) {
|
251
322
|
len = node_set->nodeNr - beg ;
|
252
323
|
}
|
253
324
|
|
254
325
|
new_set = xmlXPathNodeSetCreate(NULL);
|
255
|
-
for (j = beg ; j < beg+len ; ++j) {
|
326
|
+
for (j = beg ; j < beg + len ; ++j) {
|
256
327
|
xmlXPathNodeSetAddUnique(new_set, node_set->nodeTab[j]);
|
257
328
|
}
|
258
|
-
return
|
329
|
+
return noko_xml_node_set_wrap(new_set, rb_iv_get(self, "@document"));
|
259
330
|
}
|
260
331
|
|
261
332
|
/*
|
@@ -273,7 +344,8 @@ static VALUE subseq(VALUE self, long beg, long len)
|
|
273
344
|
* count backward from the end of the +node_set+ (-1 is the last node). Returns
|
274
345
|
* nil if the +index+ (or +start+) are out of range.
|
275
346
|
*/
|
276
|
-
static VALUE
|
347
|
+
static VALUE
|
348
|
+
slice(int argc, VALUE *argv, VALUE self)
|
277
349
|
{
|
278
350
|
VALUE arg ;
|
279
351
|
long beg, len ;
|
@@ -319,7 +391,8 @@ static VALUE slice(int argc, VALUE *argv, VALUE self)
|
|
319
391
|
*
|
320
392
|
* Return this list as an Array
|
321
393
|
*/
|
322
|
-
static VALUE
|
394
|
+
static VALUE
|
395
|
+
to_array(VALUE self)
|
323
396
|
{
|
324
397
|
xmlNodeSetPtr node_set ;
|
325
398
|
VALUE list;
|
@@ -328,9 +401,9 @@ static VALUE to_array(VALUE self)
|
|
328
401
|
Data_Get_Struct(self, xmlNodeSet, node_set);
|
329
402
|
|
330
403
|
list = rb_ary_new2(node_set->nodeNr);
|
331
|
-
for(i = 0; i < node_set->nodeNr; i++) {
|
332
|
-
VALUE elt =
|
333
|
-
rb_ary_push(
|
404
|
+
for (i = 0; i < node_set->nodeNr; i++) {
|
405
|
+
VALUE elt = noko_xml_node_wrap_node_set_result(node_set->nodeTab[i], self);
|
406
|
+
rb_ary_push(list, elt);
|
334
407
|
}
|
335
408
|
|
336
409
|
return list;
|
@@ -342,7 +415,8 @@ static VALUE to_array(VALUE self)
|
|
342
415
|
*
|
343
416
|
* Unlink this NodeSet and all Node objects it contains from their current context.
|
344
417
|
*/
|
345
|
-
static VALUE
|
418
|
+
static VALUE
|
419
|
+
unlink_nodeset(VALUE self)
|
346
420
|
{
|
347
421
|
xmlNodeSetPtr node_set;
|
348
422
|
int j, nodeNr ;
|
@@ -354,7 +428,7 @@ static VALUE unlink_nodeset(VALUE self)
|
|
354
428
|
if (! NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
|
355
429
|
VALUE node ;
|
356
430
|
xmlNodePtr node_ptr;
|
357
|
-
node =
|
431
|
+
node = noko_xml_node_wrap(Qnil, node_set->nodeTab[j]);
|
358
432
|
rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
|
359
433
|
Data_Get_Struct(node, xmlNode, node_ptr);
|
360
434
|
node_set->nodeTab[j] = node_ptr ;
|
@@ -364,123 +438,61 @@ static VALUE unlink_nodeset(VALUE self)
|
|
364
438
|
}
|
365
439
|
|
366
440
|
|
367
|
-
|
368
|
-
|
369
|
-
/*
|
370
|
-
* as mentioned in deallocate() above, xmlNs structs returned in an XPath
|
371
|
-
* NodeSet are duplicates, and we don't clean them up at deallocate() time.
|
372
|
-
*
|
373
|
-
* as a result, we need to make sure the Ruby manages this memory. we do this
|
374
|
-
* by forcing the creation of a Ruby object wrapped around the xmlNs.
|
375
|
-
*
|
376
|
-
* we also have to make sure that the NodeSet has a reference to the
|
377
|
-
* Namespace object, otherwise GC will kick in and the Namespace won't be
|
378
|
-
* marked.
|
379
|
-
*
|
380
|
-
* we *could* do this safely with *all* the nodes in the NodeSet, but we only
|
381
|
-
* *need* to do it for xmlNs structs, and so you get the code we have here.
|
382
|
-
*/
|
383
|
-
int j ;
|
384
|
-
xmlNodeSetPtr node_set ;
|
385
|
-
VALUE namespace_cache ;
|
386
|
-
|
387
|
-
Data_Get_Struct(self, xmlNodeSet, node_set);
|
388
|
-
|
389
|
-
namespace_cache = rb_iv_get(self, "@namespace_cache");
|
390
|
-
|
391
|
-
for (j = 0 ; j < node_set->nodeNr ; j++) {
|
392
|
-
if (NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
|
393
|
-
rb_ary_push(namespace_cache, Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[j], self));
|
394
|
-
}
|
395
|
-
}
|
396
|
-
}
|
397
|
-
|
398
|
-
|
399
|
-
VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set, VALUE document)
|
441
|
+
VALUE
|
442
|
+
noko_xml_node_set_wrap(xmlNodeSetPtr c_node_set, VALUE document)
|
400
443
|
{
|
401
|
-
|
444
|
+
int j;
|
445
|
+
VALUE rb_node_set ;
|
402
446
|
|
403
|
-
if (
|
404
|
-
|
447
|
+
if (c_node_set == NULL) {
|
448
|
+
c_node_set = xmlXPathNodeSetCreate(NULL);
|
405
449
|
}
|
406
450
|
|
407
|
-
|
451
|
+
rb_node_set = Data_Wrap_Struct(cNokogiriXmlNodeSet, mark, deallocate, c_node_set);
|
408
452
|
|
409
453
|
if (!NIL_P(document)) {
|
410
|
-
rb_iv_set(
|
411
|
-
rb_funcall(document, decorate, 1,
|
454
|
+
rb_iv_set(rb_node_set, "@document", document);
|
455
|
+
rb_funcall(document, decorate, 1, rb_node_set);
|
412
456
|
}
|
413
457
|
|
414
|
-
|
415
|
-
|
458
|
+
/* make sure we create ruby objects for all the results, so they'll be marked during the GC mark phase */
|
459
|
+
for (j = 0 ; j < c_node_set->nodeNr ; j++) {
|
460
|
+
noko_xml_node_wrap_node_set_result(c_node_set->nodeTab[j], rb_node_set);
|
461
|
+
}
|
416
462
|
|
417
|
-
return
|
463
|
+
return rb_node_set ;
|
418
464
|
}
|
419
465
|
|
420
|
-
VALUE
|
466
|
+
VALUE
|
467
|
+
noko_xml_node_wrap_node_set_result(xmlNodePtr node, VALUE node_set)
|
421
468
|
{
|
422
|
-
xmlDocPtr document ;
|
423
|
-
|
424
469
|
if (NOKOGIRI_NAMESPACE_EH(node)) {
|
425
|
-
|
426
|
-
return Nokogiri_wrap_xml_namespace(document, (xmlNsPtr)node);
|
470
|
+
return noko_xml_namespace_wrap_xpath_copy((xmlNsPtr)node);
|
427
471
|
} else {
|
428
|
-
return
|
429
|
-
}
|
430
|
-
}
|
431
|
-
|
432
|
-
|
433
|
-
static void xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val)
|
434
|
-
{
|
435
|
-
/*
|
436
|
-
* as mentioned a few times above, we do not want to free xmlNs structs
|
437
|
-
* outside of the Namespace lifecycle.
|
438
|
-
*
|
439
|
-
* xmlXPathNodeSetDel() frees xmlNs structs, and so here we reproduce that
|
440
|
-
* function with the xmlNs logic.
|
441
|
-
*/
|
442
|
-
int i;
|
443
|
-
|
444
|
-
if (cur == NULL) return;
|
445
|
-
if (val == NULL) return;
|
446
|
-
|
447
|
-
/*
|
448
|
-
* find node in nodeTab
|
449
|
-
*/
|
450
|
-
for (i = 0;i < cur->nodeNr;i++)
|
451
|
-
if (cur->nodeTab[i] == val) break;
|
452
|
-
|
453
|
-
if (i >= cur->nodeNr) { /* not found */
|
454
|
-
return;
|
472
|
+
return noko_xml_node_wrap(Qnil, node);
|
455
473
|
}
|
456
|
-
cur->nodeNr--;
|
457
|
-
for (;i < cur->nodeNr;i++)
|
458
|
-
cur->nodeTab[i] = cur->nodeTab[i + 1];
|
459
|
-
cur->nodeTab[cur->nodeNr] = NULL;
|
460
474
|
}
|
461
475
|
|
462
476
|
|
463
|
-
|
464
|
-
|
477
|
+
void
|
478
|
+
noko_init_xml_node_set(void)
|
465
479
|
{
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
rb_define_method(
|
473
|
-
rb_define_method(
|
474
|
-
rb_define_method(
|
475
|
-
rb_define_method(
|
476
|
-
rb_define_method(
|
477
|
-
rb_define_method(
|
478
|
-
rb_define_method(
|
479
|
-
rb_define_method(
|
480
|
-
rb_define_method(
|
481
|
-
rb_define_method(
|
482
|
-
rb_define_method(klass, "&", intersection, 1);
|
483
|
-
rb_define_method(klass, "include?", include_eh, 1);
|
480
|
+
cNokogiriXmlNodeSet = rb_define_class_under(mNokogiriXml, "NodeSet", rb_cObject);
|
481
|
+
|
482
|
+
rb_define_alloc_func(cNokogiriXmlNodeSet, allocate);
|
483
|
+
|
484
|
+
rb_define_method(cNokogiriXmlNodeSet, "length", length, 0);
|
485
|
+
rb_define_method(cNokogiriXmlNodeSet, "[]", slice, -1);
|
486
|
+
rb_define_method(cNokogiriXmlNodeSet, "slice", slice, -1);
|
487
|
+
rb_define_method(cNokogiriXmlNodeSet, "push", push, 1);
|
488
|
+
rb_define_method(cNokogiriXmlNodeSet, "|", rb_xml_node_set_union, 1);
|
489
|
+
rb_define_method(cNokogiriXmlNodeSet, "-", minus, 1);
|
490
|
+
rb_define_method(cNokogiriXmlNodeSet, "unlink", unlink_nodeset, 0);
|
491
|
+
rb_define_method(cNokogiriXmlNodeSet, "to_a", to_array, 0);
|
492
|
+
rb_define_method(cNokogiriXmlNodeSet, "dup", duplicate, 0);
|
493
|
+
rb_define_method(cNokogiriXmlNodeSet, "delete", delete, 1);
|
494
|
+
rb_define_method(cNokogiriXmlNodeSet, "&", intersection, 1);
|
495
|
+
rb_define_method(cNokogiriXmlNodeSet, "include?", include_eh, 1);
|
484
496
|
|
485
497
|
decorate = rb_intern("decorate");
|
486
498
|
}
|