nokogiri 1.19.4-java → 1.19.5-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE-DEPENDENCIES.md +29 -0
- data/ext/java/nokogiri/XmlNode.java +69 -38
- data/ext/java/nokogiri/XmlReader.java +4 -1
- data/ext/java/nokogiri/XmlSchema.java +5 -74
- data/ext/java/nokogiri/XmlXpathContext.java +5 -15
- data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +5 -7
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +68 -0
- data/ext/java/nokogiri/internals/NokogiriXPathContext.java +37 -0
- data/ext/nokogiri/extconf.rb +1 -0
- data/ext/nokogiri/gumbo.c +83 -6
- data/ext/nokogiri/html4_document.c +10 -3
- data/ext/nokogiri/libxml2_polyfill.c +12 -0
- data/ext/nokogiri/nokogiri.c +84 -2
- data/ext/nokogiri/xml_document.c +42 -16
- data/ext/nokogiri/xml_node.c +73 -38
- data/ext/nokogiri/xml_node_set.c +9 -9
- data/ext/nokogiri/xml_reader.c +198 -107
- data/ext/nokogiri/xml_sax_parser.c +3 -3
- data/ext/nokogiri/xml_sax_parser_context.c +38 -7
- data/ext/nokogiri/xml_sax_push_parser.c +12 -0
- data/ext/nokogiri/xml_xpath_context.c +124 -26
- data/ext/nokogiri/xslt_stylesheet.c +123 -27
- data/lib/nokogiri/css/parser.rb +35 -18
- data/lib/nokogiri/css/parser.y +35 -17
- data/lib/nokogiri/css/xpath_visitor.rb +71 -28
- data/lib/nokogiri/html5/document.rb +9 -0
- data/lib/nokogiri/html5/document_fragment.rb +16 -1
- data/lib/nokogiri/html5/node.rb +1 -1
- data/lib/nokogiri/html5.rb +16 -0
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/xml/attr.rb +2 -0
- data/lib/nokogiri/xml/attribute_decl.rb +2 -1
- data/lib/nokogiri/xml/builder.rb +24 -32
- data/lib/nokogiri/xml/document.rb +1 -0
- data/lib/nokogiri/xml/dtd.rb +2 -1
- data/lib/nokogiri/xml/element_decl.rb +2 -1
- data/lib/nokogiri/xml/entity_decl.rb +2 -1
- data/lib/nokogiri/xml/node.rb +8 -6
- metadata +3 -2
data/ext/nokogiri/xml_reader.c
CHANGED
|
@@ -2,29 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
VALUE cNokogiriXmlReader;
|
|
4
4
|
|
|
5
|
+
typedef struct {
|
|
6
|
+
xmlTextReaderPtr reader;
|
|
7
|
+
VALUE rb_source;
|
|
8
|
+
} nokogiriXmlReaderTuple;
|
|
9
|
+
|
|
10
|
+
static void
|
|
11
|
+
_noko_xml_reader_mark(void *data)
|
|
12
|
+
{
|
|
13
|
+
nokogiriXmlReaderTuple *tuple = data;
|
|
14
|
+
/* Pin the source because libxml2 retains its IO handle or string buffer. */
|
|
15
|
+
rb_gc_mark(tuple->rb_source);
|
|
16
|
+
}
|
|
17
|
+
|
|
5
18
|
static void
|
|
6
19
|
xml_reader_deallocate(void *data)
|
|
7
20
|
{
|
|
21
|
+
nokogiriXmlReaderTuple *tuple = data;
|
|
8
22
|
// free the document separately because we _may_ have triggered preservation by calling
|
|
9
23
|
// xmlTextReaderCurrentDoc during a read_more.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
xmlFreeTextReader(reader);
|
|
24
|
+
xmlDocPtr doc = xmlTextReaderCurrentDoc(tuple->reader);
|
|
25
|
+
xmlFreeTextReader(tuple->reader);
|
|
13
26
|
if (doc) {
|
|
14
27
|
xmlFreeDoc(doc);
|
|
15
28
|
}
|
|
29
|
+
ruby_xfree(tuple);
|
|
16
30
|
}
|
|
17
31
|
|
|
18
32
|
static const rb_data_type_t xml_text_reader_type = {
|
|
19
33
|
.wrap_struct_name = "xmlTextReader",
|
|
20
34
|
.function = {
|
|
35
|
+
.dmark = _noko_xml_reader_mark,
|
|
21
36
|
.dfree = xml_reader_deallocate,
|
|
22
37
|
},
|
|
23
38
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
|
24
39
|
};
|
|
25
40
|
|
|
41
|
+
static xmlTextReaderPtr
|
|
42
|
+
_noko_xml_reader_unwrap(VALUE rb_reader)
|
|
43
|
+
{
|
|
44
|
+
nokogiriXmlReaderTuple *tuple;
|
|
45
|
+
TypedData_Get_Struct(rb_reader, nokogiriXmlReaderTuple, &xml_text_reader_type, tuple);
|
|
46
|
+
return tuple->reader;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static VALUE
|
|
50
|
+
_noko_xml_reader_wrap(VALUE klass, xmlTextReaderPtr c_reader, VALUE rb_source)
|
|
51
|
+
{
|
|
52
|
+
nokogiriXmlReaderTuple *tuple;
|
|
53
|
+
VALUE rb_reader = TypedData_Make_Struct(klass, nokogiriXmlReaderTuple, &xml_text_reader_type, tuple);
|
|
54
|
+
|
|
55
|
+
tuple->reader = c_reader;
|
|
56
|
+
RB_OBJ_WRITE(rb_reader, &tuple->rb_source, rb_source);
|
|
57
|
+
|
|
58
|
+
return rb_reader;
|
|
59
|
+
}
|
|
60
|
+
|
|
26
61
|
static int
|
|
27
|
-
has_attributes(xmlTextReaderPtr
|
|
62
|
+
has_attributes(xmlTextReaderPtr c_reader)
|
|
28
63
|
{
|
|
29
64
|
/*
|
|
30
65
|
* this implementation of xmlTextReaderHasAttributes explicitly includes
|
|
@@ -32,7 +67,7 @@ has_attributes(xmlTextReaderPtr reader)
|
|
|
32
67
|
* namespaces.
|
|
33
68
|
*/
|
|
34
69
|
xmlNodePtr node ;
|
|
35
|
-
node = xmlTextReaderCurrentNode(
|
|
70
|
+
node = xmlTextReaderCurrentNode(c_reader);
|
|
36
71
|
if (node == NULL) {
|
|
37
72
|
return (0);
|
|
38
73
|
}
|
|
@@ -79,13 +114,13 @@ Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
|
|
|
79
114
|
* Was an attribute generated from the default value in the DTD or schema?
|
|
80
115
|
*/
|
|
81
116
|
static VALUE
|
|
82
|
-
default_eh(VALUE
|
|
117
|
+
default_eh(VALUE rb_reader)
|
|
83
118
|
{
|
|
84
|
-
xmlTextReaderPtr
|
|
119
|
+
xmlTextReaderPtr c_reader;
|
|
85
120
|
int eh;
|
|
86
121
|
|
|
87
|
-
|
|
88
|
-
eh = xmlTextReaderIsDefault(
|
|
122
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
123
|
+
eh = xmlTextReaderIsDefault(c_reader);
|
|
89
124
|
if (eh == 0) { return Qfalse; }
|
|
90
125
|
if (eh == 1) { return Qtrue; }
|
|
91
126
|
|
|
@@ -99,13 +134,13 @@ default_eh(VALUE self)
|
|
|
99
134
|
* Does this node have a text value?
|
|
100
135
|
*/
|
|
101
136
|
static VALUE
|
|
102
|
-
value_eh(VALUE
|
|
137
|
+
value_eh(VALUE rb_reader)
|
|
103
138
|
{
|
|
104
|
-
xmlTextReaderPtr
|
|
139
|
+
xmlTextReaderPtr c_reader;
|
|
105
140
|
int eh;
|
|
106
141
|
|
|
107
|
-
|
|
108
|
-
eh = xmlTextReaderHasValue(
|
|
142
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
143
|
+
eh = xmlTextReaderHasValue(c_reader);
|
|
109
144
|
if (eh == 0) { return Qfalse; }
|
|
110
145
|
if (eh == 1) { return Qtrue; }
|
|
111
146
|
|
|
@@ -119,13 +154,13 @@ value_eh(VALUE self)
|
|
|
119
154
|
* Does this node have attributes?
|
|
120
155
|
*/
|
|
121
156
|
static VALUE
|
|
122
|
-
attributes_eh(VALUE
|
|
157
|
+
attributes_eh(VALUE rb_reader)
|
|
123
158
|
{
|
|
124
|
-
xmlTextReaderPtr
|
|
159
|
+
xmlTextReaderPtr c_reader;
|
|
125
160
|
int eh;
|
|
126
161
|
|
|
127
|
-
|
|
128
|
-
eh = has_attributes(
|
|
162
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
163
|
+
eh = has_attributes(c_reader);
|
|
129
164
|
if (eh == 0) { return Qfalse; }
|
|
130
165
|
if (eh == 1) { return Qtrue; }
|
|
131
166
|
|
|
@@ -145,18 +180,24 @@ rb_xml_reader_namespaces(VALUE rb_reader)
|
|
|
145
180
|
xmlTextReaderPtr c_reader;
|
|
146
181
|
xmlNodePtr c_node;
|
|
147
182
|
VALUE rb_errors;
|
|
183
|
+
libxmlStructuredErrorHandlerState handler_state;
|
|
148
184
|
|
|
149
|
-
|
|
185
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
150
186
|
|
|
151
187
|
if (! has_attributes(c_reader)) {
|
|
152
188
|
return rb_namespaces ;
|
|
153
189
|
}
|
|
154
190
|
|
|
155
191
|
rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
|
192
|
+
noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
|
|
156
193
|
|
|
157
|
-
|
|
194
|
+
noko_io_read_reset_exception();
|
|
158
195
|
c_node = xmlTextReaderExpand(c_reader);
|
|
159
|
-
|
|
196
|
+
VALUE rb_io_read_exception = noko_io_read_take_exception();
|
|
197
|
+
|
|
198
|
+
noko__structured_error_func_restore(&handler_state);
|
|
199
|
+
|
|
200
|
+
if (!NIL_P(rb_io_read_exception)) { noko_io_read_raise_exception(rb_io_read_exception); }
|
|
160
201
|
|
|
161
202
|
if (c_node == NULL) {
|
|
162
203
|
if (RARRAY_LEN(rb_errors) > 0) {
|
|
@@ -187,18 +228,24 @@ rb_xml_reader_attribute_hash(VALUE rb_reader)
|
|
|
187
228
|
xmlNodePtr c_node;
|
|
188
229
|
xmlAttrPtr c_property;
|
|
189
230
|
VALUE rb_errors;
|
|
231
|
+
libxmlStructuredErrorHandlerState handler_state;
|
|
190
232
|
|
|
191
|
-
|
|
233
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
192
234
|
|
|
193
235
|
if (!has_attributes(c_reader)) {
|
|
194
236
|
return rb_attributes;
|
|
195
237
|
}
|
|
196
238
|
|
|
197
239
|
rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
|
240
|
+
noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
|
|
198
241
|
|
|
199
|
-
|
|
242
|
+
noko_io_read_reset_exception();
|
|
200
243
|
c_node = xmlTextReaderExpand(c_reader);
|
|
201
|
-
|
|
244
|
+
VALUE rb_io_read_exception = noko_io_read_take_exception();
|
|
245
|
+
|
|
246
|
+
noko__structured_error_func_restore(&handler_state);
|
|
247
|
+
|
|
248
|
+
if (!NIL_P(rb_io_read_exception)) { noko_io_read_raise_exception(rb_io_read_exception); }
|
|
202
249
|
|
|
203
250
|
if (c_node == NULL) {
|
|
204
251
|
if (RARRAY_LEN(rb_errors) > 0) {
|
|
@@ -235,19 +282,19 @@ rb_xml_reader_attribute_hash(VALUE rb_reader)
|
|
|
235
282
|
* Get the value of attribute at +index+
|
|
236
283
|
*/
|
|
237
284
|
static VALUE
|
|
238
|
-
attribute_at(VALUE
|
|
285
|
+
attribute_at(VALUE rb_reader, VALUE index)
|
|
239
286
|
{
|
|
240
|
-
xmlTextReaderPtr
|
|
287
|
+
xmlTextReaderPtr c_reader;
|
|
241
288
|
xmlChar *value;
|
|
242
289
|
VALUE rb_value;
|
|
243
290
|
|
|
244
|
-
|
|
291
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
245
292
|
|
|
246
293
|
if (NIL_P(index)) { return Qnil; }
|
|
247
294
|
index = rb_Integer(index);
|
|
248
295
|
|
|
249
296
|
value = xmlTextReaderGetAttributeNo(
|
|
250
|
-
|
|
297
|
+
c_reader,
|
|
251
298
|
(int)NUM2INT(index)
|
|
252
299
|
);
|
|
253
300
|
if (value == NULL) { return Qnil; }
|
|
@@ -264,18 +311,18 @@ attribute_at(VALUE self, VALUE index)
|
|
|
264
311
|
* Get the value of attribute named +name+
|
|
265
312
|
*/
|
|
266
313
|
static VALUE
|
|
267
|
-
reader_attribute(VALUE
|
|
314
|
+
reader_attribute(VALUE rb_reader, VALUE name)
|
|
268
315
|
{
|
|
269
|
-
xmlTextReaderPtr
|
|
316
|
+
xmlTextReaderPtr c_reader;
|
|
270
317
|
xmlChar *value ;
|
|
271
318
|
VALUE rb_value;
|
|
272
319
|
|
|
273
|
-
|
|
320
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
274
321
|
|
|
275
322
|
if (NIL_P(name)) { return Qnil; }
|
|
276
323
|
name = StringValue(name) ;
|
|
277
324
|
|
|
278
|
-
value = xmlTextReaderGetAttribute(
|
|
325
|
+
value = xmlTextReaderGetAttribute(c_reader, (xmlChar *)StringValueCStr(name));
|
|
279
326
|
if (value == NULL) { return Qnil; }
|
|
280
327
|
|
|
281
328
|
rb_value = NOKOGIRI_STR_NEW2(value);
|
|
@@ -290,13 +337,13 @@ reader_attribute(VALUE self, VALUE name)
|
|
|
290
337
|
* Get the number of attributes for the current node
|
|
291
338
|
*/
|
|
292
339
|
static VALUE
|
|
293
|
-
attribute_count(VALUE
|
|
340
|
+
attribute_count(VALUE rb_reader)
|
|
294
341
|
{
|
|
295
|
-
xmlTextReaderPtr
|
|
342
|
+
xmlTextReaderPtr c_reader;
|
|
296
343
|
int count;
|
|
297
344
|
|
|
298
|
-
|
|
299
|
-
count = xmlTextReaderAttributeCount(
|
|
345
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
346
|
+
count = xmlTextReaderAttributeCount(c_reader);
|
|
300
347
|
if (count == -1) { return Qnil; }
|
|
301
348
|
|
|
302
349
|
return INT2NUM(count);
|
|
@@ -309,13 +356,13 @@ attribute_count(VALUE self)
|
|
|
309
356
|
* Get the depth of the node
|
|
310
357
|
*/
|
|
311
358
|
static VALUE
|
|
312
|
-
depth(VALUE
|
|
359
|
+
depth(VALUE rb_reader)
|
|
313
360
|
{
|
|
314
|
-
xmlTextReaderPtr
|
|
361
|
+
xmlTextReaderPtr c_reader;
|
|
315
362
|
int depth;
|
|
316
363
|
|
|
317
|
-
|
|
318
|
-
depth = xmlTextReaderDepth(
|
|
364
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
365
|
+
depth = xmlTextReaderDepth(c_reader);
|
|
319
366
|
if (depth == -1) { return Qnil; }
|
|
320
367
|
|
|
321
368
|
return INT2NUM(depth);
|
|
@@ -328,13 +375,13 @@ depth(VALUE self)
|
|
|
328
375
|
* Get the XML version of the document being read
|
|
329
376
|
*/
|
|
330
377
|
static VALUE
|
|
331
|
-
xml_version(VALUE
|
|
378
|
+
xml_version(VALUE rb_reader)
|
|
332
379
|
{
|
|
333
|
-
xmlTextReaderPtr
|
|
380
|
+
xmlTextReaderPtr c_reader;
|
|
334
381
|
const char *version;
|
|
335
382
|
|
|
336
|
-
|
|
337
|
-
version = (const char *)xmlTextReaderConstXmlVersion(
|
|
383
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
384
|
+
version = (const char *)xmlTextReaderConstXmlVersion(c_reader);
|
|
338
385
|
if (version == NULL) { return Qnil; }
|
|
339
386
|
|
|
340
387
|
return NOKOGIRI_STR_NEW2(version);
|
|
@@ -347,13 +394,13 @@ xml_version(VALUE self)
|
|
|
347
394
|
* Get the xml:lang scope within which the node resides.
|
|
348
395
|
*/
|
|
349
396
|
static VALUE
|
|
350
|
-
lang(VALUE
|
|
397
|
+
lang(VALUE rb_reader)
|
|
351
398
|
{
|
|
352
|
-
xmlTextReaderPtr
|
|
399
|
+
xmlTextReaderPtr c_reader;
|
|
353
400
|
const char *lang;
|
|
354
401
|
|
|
355
|
-
|
|
356
|
-
lang = (const char *)xmlTextReaderConstXmlLang(
|
|
402
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
403
|
+
lang = (const char *)xmlTextReaderConstXmlLang(c_reader);
|
|
357
404
|
if (lang == NULL) { return Qnil; }
|
|
358
405
|
|
|
359
406
|
return NOKOGIRI_STR_NEW2(lang);
|
|
@@ -366,13 +413,13 @@ lang(VALUE self)
|
|
|
366
413
|
* Get the text value of the node if present. Returns a utf-8 encoded string.
|
|
367
414
|
*/
|
|
368
415
|
static VALUE
|
|
369
|
-
value(VALUE
|
|
416
|
+
value(VALUE rb_reader)
|
|
370
417
|
{
|
|
371
|
-
xmlTextReaderPtr
|
|
418
|
+
xmlTextReaderPtr c_reader;
|
|
372
419
|
const char *value;
|
|
373
420
|
|
|
374
|
-
|
|
375
|
-
value = (const char *)xmlTextReaderConstValue(
|
|
421
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
422
|
+
value = (const char *)xmlTextReaderConstValue(c_reader);
|
|
376
423
|
if (value == NULL) { return Qnil; }
|
|
377
424
|
|
|
378
425
|
return NOKOGIRI_STR_NEW2(value);
|
|
@@ -385,13 +432,13 @@ value(VALUE self)
|
|
|
385
432
|
* Get the shorthand reference to the namespace associated with the node.
|
|
386
433
|
*/
|
|
387
434
|
static VALUE
|
|
388
|
-
prefix(VALUE
|
|
435
|
+
prefix(VALUE rb_reader)
|
|
389
436
|
{
|
|
390
|
-
xmlTextReaderPtr
|
|
437
|
+
xmlTextReaderPtr c_reader;
|
|
391
438
|
const char *prefix;
|
|
392
439
|
|
|
393
|
-
|
|
394
|
-
prefix = (const char *)xmlTextReaderConstPrefix(
|
|
440
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
441
|
+
prefix = (const char *)xmlTextReaderConstPrefix(c_reader);
|
|
395
442
|
if (prefix == NULL) { return Qnil; }
|
|
396
443
|
|
|
397
444
|
return NOKOGIRI_STR_NEW2(prefix);
|
|
@@ -404,13 +451,13 @@ prefix(VALUE self)
|
|
|
404
451
|
* Get the URI defining the namespace associated with the node
|
|
405
452
|
*/
|
|
406
453
|
static VALUE
|
|
407
|
-
namespace_uri(VALUE
|
|
454
|
+
namespace_uri(VALUE rb_reader)
|
|
408
455
|
{
|
|
409
|
-
xmlTextReaderPtr
|
|
456
|
+
xmlTextReaderPtr c_reader;
|
|
410
457
|
const char *uri;
|
|
411
458
|
|
|
412
|
-
|
|
413
|
-
uri = (const char *)xmlTextReaderConstNamespaceUri(
|
|
459
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
460
|
+
uri = (const char *)xmlTextReaderConstNamespaceUri(c_reader);
|
|
414
461
|
if (uri == NULL) { return Qnil; }
|
|
415
462
|
|
|
416
463
|
return NOKOGIRI_STR_NEW2(uri);
|
|
@@ -423,13 +470,13 @@ namespace_uri(VALUE self)
|
|
|
423
470
|
* Get the local name of the node
|
|
424
471
|
*/
|
|
425
472
|
static VALUE
|
|
426
|
-
local_name(VALUE
|
|
473
|
+
local_name(VALUE rb_reader)
|
|
427
474
|
{
|
|
428
|
-
xmlTextReaderPtr
|
|
475
|
+
xmlTextReaderPtr c_reader;
|
|
429
476
|
const char *name;
|
|
430
477
|
|
|
431
|
-
|
|
432
|
-
name = (const char *)xmlTextReaderConstLocalName(
|
|
478
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
479
|
+
name = (const char *)xmlTextReaderConstLocalName(c_reader);
|
|
433
480
|
if (name == NULL) { return Qnil; }
|
|
434
481
|
|
|
435
482
|
return NOKOGIRI_STR_NEW2(name);
|
|
@@ -442,13 +489,13 @@ local_name(VALUE self)
|
|
|
442
489
|
* Get the name of the node. Returns a utf-8 encoded string.
|
|
443
490
|
*/
|
|
444
491
|
static VALUE
|
|
445
|
-
name(VALUE
|
|
492
|
+
name(VALUE rb_reader)
|
|
446
493
|
{
|
|
447
|
-
xmlTextReaderPtr
|
|
494
|
+
xmlTextReaderPtr c_reader;
|
|
448
495
|
const char *name;
|
|
449
496
|
|
|
450
|
-
|
|
451
|
-
name = (const char *)xmlTextReaderConstName(
|
|
497
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
498
|
+
name = (const char *)xmlTextReaderConstName(c_reader);
|
|
452
499
|
if (name == NULL) { return Qnil; }
|
|
453
500
|
|
|
454
501
|
return NOKOGIRI_STR_NEW2(name);
|
|
@@ -467,7 +514,7 @@ rb_xml_reader_base_uri(VALUE rb_reader)
|
|
|
467
514
|
xmlTextReaderPtr c_reader;
|
|
468
515
|
xmlChar *c_base_uri;
|
|
469
516
|
|
|
470
|
-
|
|
517
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
471
518
|
|
|
472
519
|
c_base_uri = xmlTextReaderBaseUri(c_reader);
|
|
473
520
|
if (c_base_uri == NULL) {
|
|
@@ -487,11 +534,11 @@ rb_xml_reader_base_uri(VALUE rb_reader)
|
|
|
487
534
|
* Get the state of the reader
|
|
488
535
|
*/
|
|
489
536
|
static VALUE
|
|
490
|
-
state(VALUE
|
|
537
|
+
state(VALUE rb_reader)
|
|
491
538
|
{
|
|
492
|
-
xmlTextReaderPtr
|
|
493
|
-
|
|
494
|
-
return INT2NUM(xmlTextReaderReadState(
|
|
539
|
+
xmlTextReaderPtr c_reader;
|
|
540
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
541
|
+
return INT2NUM(xmlTextReaderReadState(c_reader));
|
|
495
542
|
}
|
|
496
543
|
|
|
497
544
|
/*
|
|
@@ -501,11 +548,11 @@ state(VALUE self)
|
|
|
501
548
|
* Get the type of readers current node
|
|
502
549
|
*/
|
|
503
550
|
static VALUE
|
|
504
|
-
node_type(VALUE
|
|
551
|
+
node_type(VALUE rb_reader)
|
|
505
552
|
{
|
|
506
|
-
xmlTextReaderPtr
|
|
507
|
-
|
|
508
|
-
return INT2NUM(xmlTextReaderNodeType(
|
|
553
|
+
xmlTextReaderPtr c_reader;
|
|
554
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
555
|
+
return INT2NUM(xmlTextReaderNodeType(c_reader));
|
|
509
556
|
}
|
|
510
557
|
|
|
511
558
|
/*
|
|
@@ -520,15 +567,19 @@ read_more(VALUE rb_reader)
|
|
|
520
567
|
xmlTextReaderPtr c_reader;
|
|
521
568
|
libxmlStructuredErrorHandlerState handler_state;
|
|
522
569
|
|
|
523
|
-
|
|
570
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
524
571
|
|
|
525
572
|
VALUE rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
|
526
573
|
noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
|
|
527
574
|
|
|
575
|
+
noko_io_read_reset_exception();
|
|
528
576
|
int status = xmlTextReaderRead(c_reader);
|
|
577
|
+
VALUE rb_io_read_exception = noko_io_read_take_exception();
|
|
529
578
|
|
|
530
579
|
noko__structured_error_func_restore(&handler_state);
|
|
531
580
|
|
|
581
|
+
if (!NIL_P(rb_io_read_exception)) { noko_io_read_raise_exception(rb_io_read_exception); }
|
|
582
|
+
|
|
532
583
|
xmlDocPtr c_document = xmlTextReaderCurrentDoc(c_reader);
|
|
533
584
|
if (c_document && c_document->encoding == NULL) {
|
|
534
585
|
VALUE constructor_encoding = rb_iv_get(rb_reader, "@encoding");
|
|
@@ -560,15 +611,28 @@ read_more(VALUE rb_reader)
|
|
|
560
611
|
* Returns a utf-8 encoded string.
|
|
561
612
|
*/
|
|
562
613
|
static VALUE
|
|
563
|
-
inner_xml(VALUE
|
|
614
|
+
inner_xml(VALUE rb_reader)
|
|
564
615
|
{
|
|
565
|
-
xmlTextReaderPtr
|
|
616
|
+
xmlTextReaderPtr c_reader;
|
|
566
617
|
xmlChar *value;
|
|
567
618
|
VALUE str;
|
|
619
|
+
libxmlStructuredErrorHandlerState handler_state;
|
|
620
|
+
|
|
621
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
622
|
+
|
|
623
|
+
VALUE rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
|
624
|
+
noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
|
|
568
625
|
|
|
569
|
-
|
|
626
|
+
noko_io_read_reset_exception();
|
|
627
|
+
value = xmlTextReaderReadInnerXml(c_reader);
|
|
628
|
+
VALUE rb_io_read_exception = noko_io_read_take_exception();
|
|
570
629
|
|
|
571
|
-
|
|
630
|
+
noko__structured_error_func_restore(&handler_state);
|
|
631
|
+
|
|
632
|
+
if (!NIL_P(rb_io_read_exception)) {
|
|
633
|
+
xmlFree(value);
|
|
634
|
+
noko_io_read_raise_exception(rb_io_read_exception);
|
|
635
|
+
}
|
|
572
636
|
|
|
573
637
|
str = Qnil;
|
|
574
638
|
if (value) {
|
|
@@ -587,20 +651,37 @@ inner_xml(VALUE self)
|
|
|
587
651
|
* Returns a utf-8 encoded string.
|
|
588
652
|
*/
|
|
589
653
|
static VALUE
|
|
590
|
-
outer_xml(VALUE
|
|
654
|
+
outer_xml(VALUE rb_reader)
|
|
591
655
|
{
|
|
592
|
-
xmlTextReaderPtr
|
|
593
|
-
|
|
594
|
-
VALUE str = Qnil;
|
|
656
|
+
xmlTextReaderPtr c_reader;
|
|
657
|
+
libxmlStructuredErrorHandlerState handler_state;
|
|
595
658
|
|
|
596
|
-
|
|
659
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
597
660
|
|
|
598
|
-
|
|
661
|
+
VALUE rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0);
|
|
662
|
+
noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
|
|
599
663
|
|
|
600
|
-
|
|
601
|
-
|
|
664
|
+
noko_io_read_reset_exception();
|
|
665
|
+
xmlChar *value = xmlTextReaderReadOuterXml(c_reader);
|
|
666
|
+
VALUE rb_io_read_exception = noko_io_read_take_exception();
|
|
667
|
+
|
|
668
|
+
noko__structured_error_func_restore(&handler_state);
|
|
669
|
+
|
|
670
|
+
if (!NIL_P(rb_io_read_exception)) {
|
|
602
671
|
xmlFree(value);
|
|
672
|
+
noko_io_read_raise_exception(rb_io_read_exception);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if (value == NULL) {
|
|
676
|
+
VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors);
|
|
677
|
+
if (RB_TEST(exception)) {
|
|
678
|
+
rb_exc_raise(exception);
|
|
679
|
+
}
|
|
680
|
+
return Qnil;
|
|
603
681
|
}
|
|
682
|
+
|
|
683
|
+
VALUE str = NOKOGIRI_STR_NEW2((char *)value);
|
|
684
|
+
xmlFree(value);
|
|
604
685
|
return str;
|
|
605
686
|
}
|
|
606
687
|
|
|
@@ -616,7 +697,7 @@ from_memory(int argc, VALUE *argv, VALUE klass)
|
|
|
616
697
|
/* TODO: deprecate this method, since Reader.new can handle both memory and IO. It can then
|
|
617
698
|
* become private. */
|
|
618
699
|
VALUE rb_buffer, rb_url, encoding, rb_options;
|
|
619
|
-
xmlTextReaderPtr
|
|
700
|
+
xmlTextReaderPtr c_reader;
|
|
620
701
|
const char *c_url = NULL;
|
|
621
702
|
const char *c_encoding = NULL;
|
|
622
703
|
int c_options = 0;
|
|
@@ -629,20 +710,23 @@ from_memory(int argc, VALUE *argv, VALUE klass)
|
|
|
629
710
|
if (RTEST(encoding)) { c_encoding = StringValueCStr(encoding); }
|
|
630
711
|
if (RTEST(rb_options)) { c_options = (int)NUM2INT(rb_options); }
|
|
631
712
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
713
|
+
/* libxml2 < 2.11 reads the buffer without copying it, so hand it a copy the caller cannot change. */
|
|
714
|
+
VALUE rb_frozen_buffer = rb_str_new_frozen(StringValue(rb_buffer));
|
|
715
|
+
|
|
716
|
+
c_reader = xmlReaderForMemory(
|
|
717
|
+
RSTRING_PTR(rb_frozen_buffer),
|
|
718
|
+
(int)RSTRING_LEN(rb_frozen_buffer),
|
|
635
719
|
c_url,
|
|
636
720
|
c_encoding,
|
|
637
721
|
c_options
|
|
638
722
|
);
|
|
639
723
|
|
|
640
|
-
if (
|
|
641
|
-
xmlFreeTextReader(
|
|
724
|
+
if (c_reader == NULL) {
|
|
725
|
+
xmlFreeTextReader(c_reader);
|
|
642
726
|
rb_raise(rb_eRuntimeError, "couldn't create a parser");
|
|
643
727
|
}
|
|
644
728
|
|
|
645
|
-
rb_reader =
|
|
729
|
+
rb_reader = _noko_xml_reader_wrap(klass, c_reader, rb_frozen_buffer);
|
|
646
730
|
args[0] = rb_buffer;
|
|
647
731
|
args[1] = rb_url;
|
|
648
732
|
args[2] = encoding;
|
|
@@ -663,7 +747,7 @@ from_io(int argc, VALUE *argv, VALUE klass)
|
|
|
663
747
|
/* TODO: deprecate this method, since Reader.new can handle both memory and IO. It can then
|
|
664
748
|
* become private. */
|
|
665
749
|
VALUE rb_io, rb_url, encoding, rb_options;
|
|
666
|
-
xmlTextReaderPtr
|
|
750
|
+
xmlTextReaderPtr c_reader;
|
|
667
751
|
const char *c_url = NULL;
|
|
668
752
|
const char *c_encoding = NULL;
|
|
669
753
|
int c_options = 0;
|
|
@@ -676,21 +760,28 @@ from_io(int argc, VALUE *argv, VALUE klass)
|
|
|
676
760
|
if (RTEST(encoding)) { c_encoding = StringValueCStr(encoding); }
|
|
677
761
|
if (RTEST(rb_options)) { c_options = (int)NUM2INT(rb_options); }
|
|
678
762
|
|
|
679
|
-
|
|
680
|
-
|
|
763
|
+
noko_io_read_reset_exception();
|
|
764
|
+
c_reader = xmlReaderForIO(
|
|
765
|
+
(xmlInputReadCallback)noko_io_read_protected,
|
|
681
766
|
(xmlInputCloseCallback)noko_io_close,
|
|
682
767
|
(void *)rb_io,
|
|
683
768
|
c_url,
|
|
684
769
|
c_encoding,
|
|
685
770
|
c_options
|
|
686
771
|
);
|
|
772
|
+
VALUE rb_io_read_exception = noko_io_read_take_exception();
|
|
773
|
+
|
|
774
|
+
if (!NIL_P(rb_io_read_exception)) {
|
|
775
|
+
xmlFreeTextReader(c_reader);
|
|
776
|
+
noko_io_read_raise_exception(rb_io_read_exception);
|
|
777
|
+
}
|
|
687
778
|
|
|
688
|
-
if (
|
|
689
|
-
xmlFreeTextReader(
|
|
779
|
+
if (c_reader == NULL) {
|
|
780
|
+
xmlFreeTextReader(c_reader);
|
|
690
781
|
rb_raise(rb_eRuntimeError, "couldn't create a parser");
|
|
691
782
|
}
|
|
692
783
|
|
|
693
|
-
rb_reader =
|
|
784
|
+
rb_reader = _noko_xml_reader_wrap(klass, c_reader, rb_io);
|
|
694
785
|
args[0] = rb_io;
|
|
695
786
|
args[1] = rb_url;
|
|
696
787
|
args[2] = encoding;
|
|
@@ -706,13 +797,13 @@ from_io(int argc, VALUE *argv, VALUE klass)
|
|
|
706
797
|
* Returns true if the current node is empty, otherwise false.
|
|
707
798
|
*/
|
|
708
799
|
static VALUE
|
|
709
|
-
empty_element_p(VALUE
|
|
800
|
+
empty_element_p(VALUE rb_reader)
|
|
710
801
|
{
|
|
711
|
-
xmlTextReaderPtr
|
|
802
|
+
xmlTextReaderPtr c_reader;
|
|
712
803
|
|
|
713
|
-
|
|
804
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
714
805
|
|
|
715
|
-
if (xmlTextReaderIsEmptyElement(
|
|
806
|
+
if (xmlTextReaderIsEmptyElement(c_reader)) {
|
|
716
807
|
return Qtrue;
|
|
717
808
|
}
|
|
718
809
|
|
|
@@ -726,7 +817,7 @@ rb_xml_reader_encoding(VALUE rb_reader)
|
|
|
726
817
|
const char *parser_encoding;
|
|
727
818
|
VALUE constructor_encoding;
|
|
728
819
|
|
|
729
|
-
|
|
820
|
+
c_reader = _noko_xml_reader_unwrap(rb_reader);
|
|
730
821
|
parser_encoding = (const char *)xmlTextReaderConstEncoding(c_reader);
|
|
731
822
|
if (parser_encoding) {
|
|
732
823
|
return NOKOGIRI_STR_NEW2(parser_encoding);
|
|
@@ -121,7 +121,7 @@ noko_xml_sax_parser_end_element_callback(void *ctx, const xmlChar *name)
|
|
|
121
121
|
static VALUE
|
|
122
122
|
xml_sax_parser_marshal_attributes(int attributes_len, const xmlChar **c_attributes)
|
|
123
123
|
{
|
|
124
|
-
VALUE rb_array = rb_ary_new2((
|
|
124
|
+
VALUE rb_array = rb_ary_new2((rb_len_t)attributes_len);
|
|
125
125
|
VALUE cNokogiriXmlSaxParserAttribute;
|
|
126
126
|
|
|
127
127
|
cNokogiriXmlSaxParserAttribute = rb_const_get_at(cNokogiriXmlSaxParser, rb_intern("Attribute"));
|
|
@@ -165,13 +165,13 @@ noko_xml_sax_parser_start_element_ns_callback(
|
|
|
165
165
|
|
|
166
166
|
VALUE attribute_ary = xml_sax_parser_marshal_attributes(nb_attributes, attributes);
|
|
167
167
|
|
|
168
|
-
VALUE ns_list = rb_ary_new2((
|
|
168
|
+
VALUE ns_list = rb_ary_new2((rb_len_t)nb_namespaces);
|
|
169
169
|
|
|
170
170
|
if (namespaces) {
|
|
171
171
|
int i;
|
|
172
172
|
for (i = 0; i < nb_namespaces * 2; i += 2) {
|
|
173
173
|
rb_ary_push(ns_list,
|
|
174
|
-
rb_ary_new3((
|
|
174
|
+
rb_ary_new3((rb_len_t)2,
|
|
175
175
|
RBSTR_OR_QNIL(namespaces[i + 0]),
|
|
176
176
|
RBSTR_OR_QNIL(namespaces[i + 1])
|
|
177
177
|
)
|