nokogiri 1.11.1-java → 1.11.6-java
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/java/nokogiri/EncodingHandler.java +76 -89
- data/ext/java/nokogiri/HtmlDocument.java +135 -144
- data/ext/java/nokogiri/HtmlElementDescription.java +102 -117
- data/ext/java/nokogiri/HtmlEntityLookup.java +33 -60
- data/ext/java/nokogiri/HtmlSaxParserContext.java +218 -222
- data/ext/java/nokogiri/HtmlSaxPushParser.java +162 -169
- data/ext/java/nokogiri/NokogiriService.java +595 -556
- data/ext/java/nokogiri/XmlAttr.java +118 -126
- data/ext/java/nokogiri/XmlAttributeDecl.java +95 -106
- data/ext/java/nokogiri/XmlCdata.java +35 -58
- data/ext/java/nokogiri/XmlComment.java +46 -67
- data/ext/java/nokogiri/XmlDocument.java +645 -572
- data/ext/java/nokogiri/XmlDocumentFragment.java +125 -137
- data/ext/java/nokogiri/XmlDtd.java +448 -414
- data/ext/java/nokogiri/XmlElement.java +23 -48
- data/ext/java/nokogiri/XmlElementContent.java +343 -316
- data/ext/java/nokogiri/XmlElementDecl.java +124 -125
- data/ext/java/nokogiri/XmlEntityDecl.java +119 -127
- data/ext/java/nokogiri/XmlEntityReference.java +49 -72
- data/ext/java/nokogiri/XmlNamespace.java +175 -175
- data/ext/java/nokogiri/XmlNode.java +1843 -1620
- data/ext/java/nokogiri/XmlNodeSet.java +361 -331
- data/ext/java/nokogiri/XmlProcessingInstruction.java +47 -69
- data/ext/java/nokogiri/XmlReader.java +513 -450
- data/ext/java/nokogiri/XmlRelaxng.java +85 -104
- data/ext/java/nokogiri/XmlSaxParserContext.java +328 -315
- data/ext/java/nokogiri/XmlSaxPushParser.java +227 -220
- data/ext/java/nokogiri/XmlSchema.java +328 -295
- data/ext/java/nokogiri/XmlSyntaxError.java +113 -115
- data/ext/java/nokogiri/XmlText.java +55 -76
- data/ext/java/nokogiri/XmlXpathContext.java +240 -238
- data/ext/java/nokogiri/XsltStylesheet.java +280 -269
- data/ext/java/nokogiri/internals/ClosedStreamException.java +5 -2
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +201 -202
- data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +17 -10
- data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +43 -16
- data/ext/java/nokogiri/internals/NokogiriDomParser.java +63 -80
- data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +107 -88
- data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +27 -52
- data/ext/java/nokogiri/internals/NokogiriHandler.java +316 -286
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +736 -652
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +184 -173
- data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +81 -98
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +64 -79
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +84 -99
- data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +48 -65
- data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +116 -131
- data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -56
- data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +23 -46
- data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +55 -72
- data/ext/java/nokogiri/internals/ParserContext.java +206 -211
- data/ext/java/nokogiri/internals/ReaderNode.java +478 -403
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +822 -739
- data/ext/java/nokogiri/internals/SchemaErrorHandler.java +31 -54
- data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +129 -123
- data/ext/java/nokogiri/internals/XmlDeclHandler.java +3 -34
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +206 -207
- data/ext/java/nokogiri/internals/XmlSaxParser.java +22 -47
- data/ext/java/nokogiri/internals/c14n/AttrCompare.java +71 -68
- data/ext/java/nokogiri/internals/c14n/C14nHelper.java +137 -118
- data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +27 -21
- data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +74 -61
- data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +230 -205
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +572 -547
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +17 -10
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +17 -10
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +323 -302
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +232 -219
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +22 -15
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +23 -16
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +23 -16
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +22 -15
- data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +575 -545
- data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +141 -120
- data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +39 -38
- data/ext/java/nokogiri/internals/c14n/Constants.java +13 -10
- data/ext/java/nokogiri/internals/c14n/ElementProxy.java +279 -247
- data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +66 -53
- data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +44 -37
- data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +135 -120
- data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +59 -48
- data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +384 -334
- data/ext/java/nokogiri/internals/c14n/NodeFilter.java +25 -24
- data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +151 -140
- data/ext/java/nokogiri/internals/c14n/XMLUtils.java +456 -423
- data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1466 -1500
- data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +626 -574
- 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 +66 -65
- data/ext/nokogiri/html_sax_push_parser.c +29 -27
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +190 -63
- data/ext/nokogiri/test_global_handlers.c +3 -4
- 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 +385 -326
- 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 +100 -85
- data/ext/nokogiri/xml_sax_push_parser.c +34 -27
- data/ext/nokogiri/xml_schema.c +48 -42
- data/ext/nokogiri/xml_syntax_error.c +21 -23
- 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/css/parser.rb +1 -1
- data/lib/nokogiri/extension.rb +26 -0
- data/lib/nokogiri/html/document_fragment.rb +15 -15
- data/lib/nokogiri/nokogiri.jar +0 -0
- 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 +7 -8
- data/ext/nokogiri/xml_io.c +0 -63
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
@@ -1,4 +1,6 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
|
+
|
3
|
+
VALUE cNokogiriXmlProcessingInstruction;
|
2
4
|
|
3
5
|
/*
|
4
6
|
* call-seq:
|
@@ -7,7 +9,8 @@
|
|
7
9
|
* Create a new ProcessingInstruction element on the +document+ with +name+
|
8
10
|
* and +content+
|
9
11
|
*/
|
10
|
-
static VALUE
|
12
|
+
static VALUE
|
13
|
+
new (int argc, VALUE *argv, VALUE klass)
|
11
14
|
{
|
12
15
|
xmlDocPtr xml_doc;
|
13
16
|
xmlNodePtr node;
|
@@ -22,35 +25,30 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
|
|
22
25
|
Data_Get_Struct(document, xmlDoc, xml_doc);
|
23
26
|
|
24
27
|
node = xmlNewDocPI(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
xml_doc,
|
29
|
+
(const xmlChar *)StringValueCStr(name),
|
30
|
+
(const xmlChar *)StringValueCStr(content)
|
31
|
+
);
|
29
32
|
|
30
|
-
|
33
|
+
noko_xml_document_pin_node(node);
|
31
34
|
|
32
|
-
rb_node =
|
35
|
+
rb_node = noko_xml_node_wrap(klass, node);
|
33
36
|
rb_obj_call_init(rb_node, argc, argv);
|
34
37
|
|
35
|
-
if(rb_block_given_p()) rb_yield(rb_node);
|
38
|
+
if (rb_block_given_p()) { rb_yield(rb_node); }
|
36
39
|
|
37
40
|
return rb_node;
|
38
41
|
}
|
39
42
|
|
40
|
-
|
41
|
-
|
43
|
+
void
|
44
|
+
noko_init_xml_processing_instruction()
|
42
45
|
{
|
43
|
-
|
44
|
-
VALUE xml = rb_define_module_under(nokogiri, "XML");
|
45
|
-
VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
|
46
|
-
|
46
|
+
assert(cNokogiriXmlNode);
|
47
47
|
/*
|
48
48
|
* ProcessingInstruction represents a ProcessingInstruction node in an xml
|
49
49
|
* document.
|
50
50
|
*/
|
51
|
-
|
52
|
-
|
53
|
-
cNokogiriXmlProcessingInstruction = klass;
|
51
|
+
cNokogiriXmlProcessingInstruction = rb_define_class_under(mNokogiriXml, "ProcessingInstruction", cNokogiriXmlNode);
|
54
52
|
|
55
|
-
rb_define_singleton_method(
|
53
|
+
rb_define_singleton_method(cNokogiriXmlProcessingInstruction, "new", new, -1);
|
56
54
|
}
|
data/ext/nokogiri/xml_reader.c
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
#include <
|
1
|
+
#include <nokogiri.h>
|
2
2
|
|
3
|
-
|
3
|
+
VALUE cNokogiriXmlReader;
|
4
|
+
|
5
|
+
static void
|
6
|
+
dealloc(xmlTextReaderPtr reader)
|
4
7
|
{
|
5
8
|
NOKOGIRI_DEBUG_START(reader);
|
6
9
|
xmlFreeTextReader(reader);
|
7
10
|
NOKOGIRI_DEBUG_END(reader);
|
8
11
|
}
|
9
12
|
|
10
|
-
static int
|
13
|
+
static int
|
14
|
+
has_attributes(xmlTextReaderPtr reader)
|
11
15
|
{
|
12
16
|
/*
|
13
17
|
* this implementation of xmlTextReaderHasAttributes explicitly includes
|
@@ -16,21 +20,24 @@ static int has_attributes(xmlTextReaderPtr reader)
|
|
16
20
|
*/
|
17
21
|
xmlNodePtr node ;
|
18
22
|
node = xmlTextReaderCurrentNode(reader);
|
19
|
-
if (node == NULL)
|
20
|
-
return(0);
|
23
|
+
if (node == NULL) {
|
24
|
+
return (0);
|
25
|
+
}
|
21
26
|
|
22
27
|
if ((node->type == XML_ELEMENT_NODE) &&
|
23
|
-
((node->properties != NULL) || (node->nsDef != NULL)))
|
24
|
-
return(1);
|
25
|
-
|
28
|
+
((node->properties != NULL) || (node->nsDef != NULL))) {
|
29
|
+
return (1);
|
30
|
+
}
|
31
|
+
return (0);
|
26
32
|
}
|
27
33
|
|
28
|
-
static void
|
34
|
+
static void
|
35
|
+
Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
|
29
36
|
{
|
30
37
|
xmlNsPtr ns;
|
31
38
|
VALUE key;
|
32
39
|
|
33
|
-
if (node->type != XML_ELEMENT_NODE) return ;
|
40
|
+
if (node->type != XML_ELEMENT_NODE) { return ; }
|
34
41
|
|
35
42
|
ns = node->nsDef;
|
36
43
|
while (ns != NULL) {
|
@@ -38,14 +45,14 @@ static void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
|
|
38
45
|
key = rb_enc_str_new_cstr(XMLNS_PREFIX, rb_utf8_encoding());
|
39
46
|
if (ns->prefix) {
|
40
47
|
rb_str_cat_cstr(key, ":");
|
41
|
-
rb_str_cat_cstr(key, (const char*)ns->prefix);
|
48
|
+
rb_str_cat_cstr(key, (const char *)ns->prefix);
|
42
49
|
}
|
43
50
|
|
44
51
|
key = rb_str_conv_enc(key, rb_utf8_encoding(), rb_default_internal_encoding());
|
45
52
|
rb_hash_aset(attr_hash,
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
key,
|
54
|
+
(ns->href ? NOKOGIRI_STR_NEW2(ns->href) : Qnil)
|
55
|
+
);
|
49
56
|
ns = ns->next ;
|
50
57
|
}
|
51
58
|
}
|
@@ -57,15 +64,16 @@ static void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
|
|
57
64
|
*
|
58
65
|
* Was an attribute generated from the default value in the DTD or schema?
|
59
66
|
*/
|
60
|
-
static VALUE
|
67
|
+
static VALUE
|
68
|
+
default_eh(VALUE self)
|
61
69
|
{
|
62
70
|
xmlTextReaderPtr reader;
|
63
71
|
int eh;
|
64
72
|
|
65
73
|
Data_Get_Struct(self, xmlTextReader, reader);
|
66
74
|
eh = xmlTextReaderIsDefault(reader);
|
67
|
-
if(eh == 0) return Qfalse;
|
68
|
-
if(eh == 1) return Qtrue;
|
75
|
+
if (eh == 0) { return Qfalse; }
|
76
|
+
if (eh == 1) { return Qtrue; }
|
69
77
|
|
70
78
|
return Qnil;
|
71
79
|
}
|
@@ -76,15 +84,16 @@ static VALUE default_eh(VALUE self)
|
|
76
84
|
*
|
77
85
|
* Does this node have a text value?
|
78
86
|
*/
|
79
|
-
static VALUE
|
87
|
+
static VALUE
|
88
|
+
value_eh(VALUE self)
|
80
89
|
{
|
81
90
|
xmlTextReaderPtr reader;
|
82
91
|
int eh;
|
83
92
|
|
84
93
|
Data_Get_Struct(self, xmlTextReader, reader);
|
85
94
|
eh = xmlTextReaderHasValue(reader);
|
86
|
-
if(eh == 0) return Qfalse;
|
87
|
-
if(eh == 1) return Qtrue;
|
95
|
+
if (eh == 0) { return Qfalse; }
|
96
|
+
if (eh == 1) { return Qtrue; }
|
88
97
|
|
89
98
|
return Qnil;
|
90
99
|
}
|
@@ -95,15 +104,16 @@ static VALUE value_eh(VALUE self)
|
|
95
104
|
*
|
96
105
|
* Does this node have attributes?
|
97
106
|
*/
|
98
|
-
static VALUE
|
107
|
+
static VALUE
|
108
|
+
attributes_eh(VALUE self)
|
99
109
|
{
|
100
110
|
xmlTextReaderPtr reader;
|
101
111
|
int eh;
|
102
112
|
|
103
113
|
Data_Get_Struct(self, xmlTextReader, reader);
|
104
114
|
eh = has_attributes(reader);
|
105
|
-
if(eh == 0) return Qfalse;
|
106
|
-
if(eh == 1) return Qtrue;
|
115
|
+
if (eh == 0) { return Qfalse; }
|
116
|
+
if (eh == 1) { return Qtrue; }
|
107
117
|
|
108
118
|
return Qnil;
|
109
119
|
}
|
@@ -114,7 +124,8 @@ static VALUE attributes_eh(VALUE self)
|
|
114
124
|
*
|
115
125
|
* Get a hash of namespaces for this Node
|
116
126
|
*/
|
117
|
-
static VALUE
|
127
|
+
static VALUE
|
128
|
+
namespaces(VALUE self)
|
118
129
|
{
|
119
130
|
xmlTextReaderPtr reader;
|
120
131
|
xmlNodePtr ptr;
|
@@ -124,11 +135,12 @@ static VALUE namespaces(VALUE self)
|
|
124
135
|
|
125
136
|
attr = rb_hash_new() ;
|
126
137
|
|
127
|
-
if (! has_attributes(reader))
|
138
|
+
if (! has_attributes(reader)) {
|
128
139
|
return attr ;
|
140
|
+
}
|
129
141
|
|
130
142
|
ptr = xmlTextReaderExpand(reader);
|
131
|
-
if(ptr == NULL) return Qnil;
|
143
|
+
if (ptr == NULL) { return Qnil; }
|
132
144
|
|
133
145
|
Nokogiri_xml_node_namespaces(ptr, attr);
|
134
146
|
|
@@ -136,30 +148,37 @@ static VALUE namespaces(VALUE self)
|
|
136
148
|
}
|
137
149
|
|
138
150
|
/*
|
139
|
-
*
|
140
|
-
*
|
141
|
-
*
|
142
|
-
* Get a list of attributes for this Node
|
151
|
+
* @overload attribute_nodes()
|
152
|
+
* Get the attributes of the current node as an Array of Attr
|
153
|
+
* @return [Array<Nokogiri::XML::Attr>]
|
143
154
|
*/
|
144
|
-
static VALUE
|
155
|
+
static VALUE
|
156
|
+
rb_xml_reader_attribute_nodes(VALUE rb_reader)
|
145
157
|
{
|
146
|
-
xmlTextReaderPtr
|
147
|
-
xmlNodePtr
|
148
|
-
VALUE
|
158
|
+
xmlTextReaderPtr c_reader;
|
159
|
+
xmlNodePtr c_node;
|
160
|
+
VALUE attr_nodes;
|
161
|
+
int j;
|
149
162
|
|
150
|
-
Data_Get_Struct(
|
163
|
+
Data_Get_Struct(rb_reader, xmlTextReader, c_reader);
|
151
164
|
|
152
|
-
|
165
|
+
if (! has_attributes(c_reader)) {
|
166
|
+
return rb_ary_new() ;
|
167
|
+
}
|
153
168
|
|
154
|
-
|
155
|
-
|
169
|
+
c_node = xmlTextReaderExpand(c_reader);
|
170
|
+
if (c_node == NULL) {
|
171
|
+
return Qnil;
|
172
|
+
}
|
156
173
|
|
157
|
-
|
158
|
-
if(ptr == NULL) return Qnil;
|
174
|
+
attr_nodes = noko_xml_node_attrs(c_node);
|
159
175
|
|
160
|
-
|
176
|
+
/* ensure that the Reader won't be GCed as long as a node is referenced */
|
177
|
+
for (j = 0 ; j < RARRAY_LEN(attr_nodes) ; j++) {
|
178
|
+
rb_iv_set(rb_ary_entry(attr_nodes, j), "@reader", rb_reader);
|
179
|
+
}
|
161
180
|
|
162
|
-
return
|
181
|
+
return attr_nodes;
|
163
182
|
}
|
164
183
|
|
165
184
|
/*
|
@@ -168,7 +187,8 @@ static VALUE attribute_nodes(VALUE self)
|
|
168
187
|
*
|
169
188
|
* Get the value of attribute at +index+
|
170
189
|
*/
|
171
|
-
static VALUE
|
190
|
+
static VALUE
|
191
|
+
attribute_at(VALUE self, VALUE index)
|
172
192
|
{
|
173
193
|
xmlTextReaderPtr reader;
|
174
194
|
xmlChar *value;
|
@@ -176,14 +196,14 @@ static VALUE attribute_at(VALUE self, VALUE index)
|
|
176
196
|
|
177
197
|
Data_Get_Struct(self, xmlTextReader, reader);
|
178
198
|
|
179
|
-
if(NIL_P(index)) return Qnil;
|
199
|
+
if (NIL_P(index)) { return Qnil; }
|
180
200
|
index = rb_Integer(index);
|
181
201
|
|
182
202
|
value = xmlTextReaderGetAttributeNo(
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
if(value == NULL) return Qnil;
|
203
|
+
reader,
|
204
|
+
(int)NUM2INT(index)
|
205
|
+
);
|
206
|
+
if (value == NULL) { return Qnil; }
|
187
207
|
|
188
208
|
rb_value = NOKOGIRI_STR_NEW2(value);
|
189
209
|
xmlFree(value);
|
@@ -196,7 +216,8 @@ static VALUE attribute_at(VALUE self, VALUE index)
|
|
196
216
|
*
|
197
217
|
* Get the value of attribute named +name+
|
198
218
|
*/
|
199
|
-
static VALUE
|
219
|
+
static VALUE
|
220
|
+
reader_attribute(VALUE self, VALUE name)
|
200
221
|
{
|
201
222
|
xmlTextReaderPtr reader;
|
202
223
|
xmlChar *value ;
|
@@ -204,11 +225,11 @@ static VALUE reader_attribute(VALUE self, VALUE name)
|
|
204
225
|
|
205
226
|
Data_Get_Struct(self, xmlTextReader, reader);
|
206
227
|
|
207
|
-
if(NIL_P(name)) return Qnil;
|
228
|
+
if (NIL_P(name)) { return Qnil; }
|
208
229
|
name = StringValue(name) ;
|
209
230
|
|
210
|
-
value = xmlTextReaderGetAttribute(reader, (xmlChar*)StringValueCStr(name));
|
211
|
-
if(value == NULL) return Qnil;
|
231
|
+
value = xmlTextReaderGetAttribute(reader, (xmlChar *)StringValueCStr(name));
|
232
|
+
if (value == NULL) { return Qnil; }
|
212
233
|
|
213
234
|
rb_value = NOKOGIRI_STR_NEW2(value);
|
214
235
|
xmlFree(value);
|
@@ -221,14 +242,15 @@ static VALUE reader_attribute(VALUE self, VALUE name)
|
|
221
242
|
*
|
222
243
|
* Get the number of attributes for the current node
|
223
244
|
*/
|
224
|
-
static VALUE
|
245
|
+
static VALUE
|
246
|
+
attribute_count(VALUE self)
|
225
247
|
{
|
226
248
|
xmlTextReaderPtr reader;
|
227
249
|
int count;
|
228
250
|
|
229
251
|
Data_Get_Struct(self, xmlTextReader, reader);
|
230
252
|
count = xmlTextReaderAttributeCount(reader);
|
231
|
-
if(count == -1) return Qnil;
|
253
|
+
if (count == -1) { return Qnil; }
|
232
254
|
|
233
255
|
return INT2NUM((long)count);
|
234
256
|
}
|
@@ -239,14 +261,15 @@ static VALUE attribute_count(VALUE self)
|
|
239
261
|
*
|
240
262
|
* Get the depth of the node
|
241
263
|
*/
|
242
|
-
static VALUE
|
264
|
+
static VALUE
|
265
|
+
depth(VALUE self)
|
243
266
|
{
|
244
267
|
xmlTextReaderPtr reader;
|
245
268
|
int depth;
|
246
269
|
|
247
270
|
Data_Get_Struct(self, xmlTextReader, reader);
|
248
271
|
depth = xmlTextReaderDepth(reader);
|
249
|
-
if(depth == -1) return Qnil;
|
272
|
+
if (depth == -1) { return Qnil; }
|
250
273
|
|
251
274
|
return INT2NUM((long)depth);
|
252
275
|
}
|
@@ -257,14 +280,15 @@ static VALUE depth(VALUE self)
|
|
257
280
|
*
|
258
281
|
* Get the XML version of the document being read
|
259
282
|
*/
|
260
|
-
static VALUE
|
283
|
+
static VALUE
|
284
|
+
xml_version(VALUE self)
|
261
285
|
{
|
262
286
|
xmlTextReaderPtr reader;
|
263
287
|
const char *version;
|
264
288
|
|
265
289
|
Data_Get_Struct(self, xmlTextReader, reader);
|
266
290
|
version = (const char *)xmlTextReaderConstXmlVersion(reader);
|
267
|
-
if(version == NULL) return Qnil;
|
291
|
+
if (version == NULL) { return Qnil; }
|
268
292
|
|
269
293
|
return NOKOGIRI_STR_NEW2(version);
|
270
294
|
}
|
@@ -275,14 +299,15 @@ static VALUE xml_version(VALUE self)
|
|
275
299
|
*
|
276
300
|
* Get the xml:lang scope within which the node resides.
|
277
301
|
*/
|
278
|
-
static VALUE
|
302
|
+
static VALUE
|
303
|
+
lang(VALUE self)
|
279
304
|
{
|
280
305
|
xmlTextReaderPtr reader;
|
281
306
|
const char *lang;
|
282
307
|
|
283
308
|
Data_Get_Struct(self, xmlTextReader, reader);
|
284
309
|
lang = (const char *)xmlTextReaderConstXmlLang(reader);
|
285
|
-
if(lang == NULL) return Qnil;
|
310
|
+
if (lang == NULL) { return Qnil; }
|
286
311
|
|
287
312
|
return NOKOGIRI_STR_NEW2(lang);
|
288
313
|
}
|
@@ -293,14 +318,15 @@ static VALUE lang(VALUE self)
|
|
293
318
|
*
|
294
319
|
* Get the text value of the node if present. Returns a utf-8 encoded string.
|
295
320
|
*/
|
296
|
-
static VALUE
|
321
|
+
static VALUE
|
322
|
+
value(VALUE self)
|
297
323
|
{
|
298
324
|
xmlTextReaderPtr reader;
|
299
325
|
const char *value;
|
300
326
|
|
301
327
|
Data_Get_Struct(self, xmlTextReader, reader);
|
302
328
|
value = (const char *)xmlTextReaderConstValue(reader);
|
303
|
-
if(value == NULL) return Qnil;
|
329
|
+
if (value == NULL) { return Qnil; }
|
304
330
|
|
305
331
|
return NOKOGIRI_STR_NEW2(value);
|
306
332
|
}
|
@@ -311,14 +337,15 @@ static VALUE value(VALUE self)
|
|
311
337
|
*
|
312
338
|
* Get the shorthand reference to the namespace associated with the node.
|
313
339
|
*/
|
314
|
-
static VALUE
|
340
|
+
static VALUE
|
341
|
+
prefix(VALUE self)
|
315
342
|
{
|
316
343
|
xmlTextReaderPtr reader;
|
317
344
|
const char *prefix;
|
318
345
|
|
319
346
|
Data_Get_Struct(self, xmlTextReader, reader);
|
320
347
|
prefix = (const char *)xmlTextReaderConstPrefix(reader);
|
321
|
-
if(prefix == NULL) return Qnil;
|
348
|
+
if (prefix == NULL) { return Qnil; }
|
322
349
|
|
323
350
|
return NOKOGIRI_STR_NEW2(prefix);
|
324
351
|
}
|
@@ -329,14 +356,15 @@ static VALUE prefix(VALUE self)
|
|
329
356
|
*
|
330
357
|
* Get the URI defining the namespace associated with the node
|
331
358
|
*/
|
332
|
-
static VALUE
|
359
|
+
static VALUE
|
360
|
+
namespace_uri(VALUE self)
|
333
361
|
{
|
334
362
|
xmlTextReaderPtr reader;
|
335
363
|
const char *uri;
|
336
364
|
|
337
365
|
Data_Get_Struct(self, xmlTextReader, reader);
|
338
366
|
uri = (const char *)xmlTextReaderConstNamespaceUri(reader);
|
339
|
-
if(uri == NULL) return Qnil;
|
367
|
+
if (uri == NULL) { return Qnil; }
|
340
368
|
|
341
369
|
return NOKOGIRI_STR_NEW2(uri);
|
342
370
|
}
|
@@ -347,14 +375,15 @@ static VALUE namespace_uri(VALUE self)
|
|
347
375
|
*
|
348
376
|
* Get the local name of the node
|
349
377
|
*/
|
350
|
-
static VALUE
|
378
|
+
static VALUE
|
379
|
+
local_name(VALUE self)
|
351
380
|
{
|
352
381
|
xmlTextReaderPtr reader;
|
353
382
|
const char *name;
|
354
383
|
|
355
384
|
Data_Get_Struct(self, xmlTextReader, reader);
|
356
385
|
name = (const char *)xmlTextReaderConstLocalName(reader);
|
357
|
-
if(name == NULL) return Qnil;
|
386
|
+
if (name == NULL) { return Qnil; }
|
358
387
|
|
359
388
|
return NOKOGIRI_STR_NEW2(name);
|
360
389
|
}
|
@@ -365,14 +394,15 @@ static VALUE local_name(VALUE self)
|
|
365
394
|
*
|
366
395
|
* Get the name of the node. Returns a utf-8 encoded string.
|
367
396
|
*/
|
368
|
-
static VALUE
|
397
|
+
static VALUE
|
398
|
+
name(VALUE self)
|
369
399
|
{
|
370
400
|
xmlTextReaderPtr reader;
|
371
401
|
const char *name;
|
372
402
|
|
373
403
|
Data_Get_Struct(self, xmlTextReader, reader);
|
374
404
|
name = (const char *)xmlTextReaderConstName(reader);
|
375
|
-
if(name == NULL) return Qnil;
|
405
|
+
if (name == NULL) { return Qnil; }
|
376
406
|
|
377
407
|
return NOKOGIRI_STR_NEW2(name);
|
378
408
|
}
|
@@ -383,14 +413,15 @@ static VALUE name(VALUE self)
|
|
383
413
|
*
|
384
414
|
* Get the xml:base of the node
|
385
415
|
*/
|
386
|
-
static VALUE
|
416
|
+
static VALUE
|
417
|
+
base_uri(VALUE self)
|
387
418
|
{
|
388
419
|
xmlTextReaderPtr reader;
|
389
|
-
const char *
|
420
|
+
const char *base_uri;
|
390
421
|
|
391
422
|
Data_Get_Struct(self, xmlTextReader, reader);
|
392
423
|
base_uri = (const char *)xmlTextReaderBaseUri(reader);
|
393
|
-
if (base_uri == NULL) return Qnil;
|
424
|
+
if (base_uri == NULL) { return Qnil; }
|
394
425
|
|
395
426
|
return NOKOGIRI_STR_NEW2(base_uri);
|
396
427
|
}
|
@@ -401,7 +432,8 @@ static VALUE base_uri(VALUE self)
|
|
401
432
|
*
|
402
433
|
* Get the state of the reader
|
403
434
|
*/
|
404
|
-
static VALUE
|
435
|
+
static VALUE
|
436
|
+
state(VALUE self)
|
405
437
|
{
|
406
438
|
xmlTextReaderPtr reader;
|
407
439
|
Data_Get_Struct(self, xmlTextReader, reader);
|
@@ -414,7 +446,8 @@ static VALUE state(VALUE self)
|
|
414
446
|
*
|
415
447
|
* Get the type of readers current node
|
416
448
|
*/
|
417
|
-
static VALUE
|
449
|
+
static VALUE
|
450
|
+
node_type(VALUE self)
|
418
451
|
{
|
419
452
|
xmlTextReaderPtr reader;
|
420
453
|
Data_Get_Struct(self, xmlTextReader, reader);
|
@@ -427,7 +460,8 @@ static VALUE node_type(VALUE self)
|
|
427
460
|
*
|
428
461
|
* Move the Reader forward through the XML document.
|
429
462
|
*/
|
430
|
-
static VALUE
|
463
|
+
static VALUE
|
464
|
+
read_more(VALUE self)
|
431
465
|
{
|
432
466
|
xmlTextReaderPtr reader;
|
433
467
|
xmlErrorPtr error;
|
@@ -442,14 +476,15 @@ static VALUE read_more(VALUE self)
|
|
442
476
|
ret = xmlTextReaderRead(reader);
|
443
477
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
444
478
|
|
445
|
-
if(ret == 1) return self;
|
446
|
-
if(ret == 0) return Qnil;
|
479
|
+
if (ret == 1) { return self; }
|
480
|
+
if (ret == 0) { return Qnil; }
|
447
481
|
|
448
482
|
error = xmlGetLastError();
|
449
|
-
if(error)
|
483
|
+
if (error) {
|
450
484
|
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
451
|
-
else
|
485
|
+
} else {
|
452
486
|
rb_raise(rb_eRuntimeError, "Error pulling: %d", ret);
|
487
|
+
}
|
453
488
|
|
454
489
|
return Qnil;
|
455
490
|
}
|
@@ -461,10 +496,11 @@ static VALUE read_more(VALUE self)
|
|
461
496
|
* Read the contents of the current node, including child nodes and markup.
|
462
497
|
* Returns a utf-8 encoded string.
|
463
498
|
*/
|
464
|
-
static VALUE
|
499
|
+
static VALUE
|
500
|
+
inner_xml(VALUE self)
|
465
501
|
{
|
466
502
|
xmlTextReaderPtr reader;
|
467
|
-
xmlChar*
|
503
|
+
xmlChar *value;
|
468
504
|
VALUE str;
|
469
505
|
|
470
506
|
Data_Get_Struct(self, xmlTextReader, reader);
|
@@ -472,8 +508,8 @@ static VALUE inner_xml(VALUE self)
|
|
472
508
|
value = xmlTextReaderReadInnerXml(reader);
|
473
509
|
|
474
510
|
str = Qnil;
|
475
|
-
if(value) {
|
476
|
-
str = NOKOGIRI_STR_NEW2((char*)value);
|
511
|
+
if (value) {
|
512
|
+
str = NOKOGIRI_STR_NEW2((char *)value);
|
477
513
|
xmlFree(value);
|
478
514
|
}
|
479
515
|
|
@@ -487,7 +523,8 @@ static VALUE inner_xml(VALUE self)
|
|
487
523
|
* Read the current node and its contents, including child nodes and markup.
|
488
524
|
* Returns a utf-8 encoded string.
|
489
525
|
*/
|
490
|
-
static VALUE
|
526
|
+
static VALUE
|
527
|
+
outer_xml(VALUE self)
|
491
528
|
{
|
492
529
|
xmlTextReaderPtr reader;
|
493
530
|
xmlChar *value;
|
@@ -497,8 +534,8 @@ static VALUE outer_xml(VALUE self)
|
|
497
534
|
|
498
535
|
value = xmlTextReaderReadOuterXml(reader);
|
499
536
|
|
500
|
-
if(value) {
|
501
|
-
str = NOKOGIRI_STR_NEW2((char*)value);
|
537
|
+
if (value) {
|
538
|
+
str = NOKOGIRI_STR_NEW2((char *)value);
|
502
539
|
xmlFree(value);
|
503
540
|
}
|
504
541
|
return str;
|
@@ -510,31 +547,32 @@ static VALUE outer_xml(VALUE self)
|
|
510
547
|
*
|
511
548
|
* Create a new reader that parses +string+
|
512
549
|
*/
|
513
|
-
static VALUE
|
550
|
+
static VALUE
|
551
|
+
from_memory(int argc, VALUE *argv, VALUE klass)
|
514
552
|
{
|
515
553
|
VALUE rb_buffer, rb_url, encoding, rb_options;
|
516
554
|
xmlTextReaderPtr reader;
|
517
|
-
const char *
|
518
|
-
const char *
|
555
|
+
const char *c_url = NULL;
|
556
|
+
const char *c_encoding = NULL;
|
519
557
|
int c_options = 0;
|
520
558
|
VALUE rb_reader, args[3];
|
521
559
|
|
522
560
|
rb_scan_args(argc, argv, "13", &rb_buffer, &rb_url, &encoding, &rb_options);
|
523
561
|
|
524
|
-
if (!RTEST(rb_buffer)) rb_raise(rb_eArgError, "string cannot be nil");
|
525
|
-
if (RTEST(rb_url)) c_url = StringValueCStr(rb_url);
|
526
|
-
if (RTEST(encoding)) c_encoding = StringValueCStr(encoding);
|
527
|
-
if (RTEST(rb_options)) c_options = (int)NUM2INT(rb_options);
|
562
|
+
if (!RTEST(rb_buffer)) { rb_raise(rb_eArgError, "string cannot be nil"); }
|
563
|
+
if (RTEST(rb_url)) { c_url = StringValueCStr(rb_url); }
|
564
|
+
if (RTEST(encoding)) { c_encoding = StringValueCStr(encoding); }
|
565
|
+
if (RTEST(rb_options)) { c_options = (int)NUM2INT(rb_options); }
|
528
566
|
|
529
567
|
reader = xmlReaderForMemory(
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
if(reader == NULL) {
|
568
|
+
StringValuePtr(rb_buffer),
|
569
|
+
(int)RSTRING_LEN(rb_buffer),
|
570
|
+
c_url,
|
571
|
+
c_encoding,
|
572
|
+
c_options
|
573
|
+
);
|
574
|
+
|
575
|
+
if (reader == NULL) {
|
538
576
|
xmlFreeTextReader(reader);
|
539
577
|
rb_raise(rb_eRuntimeError, "couldn't create a parser");
|
540
578
|
}
|
@@ -554,32 +592,33 @@ static VALUE from_memory(int argc, VALUE *argv, VALUE klass)
|
|
554
592
|
*
|
555
593
|
* Create a new reader that parses +io+
|
556
594
|
*/
|
557
|
-
static VALUE
|
595
|
+
static VALUE
|
596
|
+
from_io(int argc, VALUE *argv, VALUE klass)
|
558
597
|
{
|
559
598
|
VALUE rb_io, rb_url, encoding, rb_options;
|
560
599
|
xmlTextReaderPtr reader;
|
561
|
-
const char *
|
562
|
-
const char *
|
600
|
+
const char *c_url = NULL;
|
601
|
+
const char *c_encoding = NULL;
|
563
602
|
int c_options = 0;
|
564
603
|
VALUE rb_reader, args[3];
|
565
604
|
|
566
605
|
rb_scan_args(argc, argv, "13", &rb_io, &rb_url, &encoding, &rb_options);
|
567
606
|
|
568
|
-
if (!RTEST(rb_io)) rb_raise(rb_eArgError, "io cannot be nil");
|
569
|
-
if (RTEST(rb_url)) c_url = StringValueCStr(rb_url);
|
570
|
-
if (RTEST(encoding)) c_encoding = StringValueCStr(encoding);
|
571
|
-
if (RTEST(rb_options)) c_options = (int)NUM2INT(rb_options);
|
607
|
+
if (!RTEST(rb_io)) { rb_raise(rb_eArgError, "io cannot be nil"); }
|
608
|
+
if (RTEST(rb_url)) { c_url = StringValueCStr(rb_url); }
|
609
|
+
if (RTEST(encoding)) { c_encoding = StringValueCStr(encoding); }
|
610
|
+
if (RTEST(rb_options)) { c_options = (int)NUM2INT(rb_options); }
|
572
611
|
|
573
612
|
reader = xmlReaderForIO(
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
if(reader == NULL) {
|
613
|
+
(xmlInputReadCallback)noko_io_read,
|
614
|
+
(xmlInputCloseCallback)noko_io_close,
|
615
|
+
(void *)rb_io,
|
616
|
+
c_url,
|
617
|
+
c_encoding,
|
618
|
+
c_options
|
619
|
+
);
|
620
|
+
|
621
|
+
if (reader == NULL) {
|
583
622
|
xmlFreeTextReader(reader);
|
584
623
|
rb_raise(rb_eRuntimeError, "couldn't create a parser");
|
585
624
|
}
|
@@ -599,59 +638,54 @@ static VALUE from_io(int argc, VALUE *argv, VALUE klass)
|
|
599
638
|
*
|
600
639
|
* Returns true if the current node is empty, otherwise false.
|
601
640
|
*/
|
602
|
-
static VALUE
|
641
|
+
static VALUE
|
642
|
+
empty_element_p(VALUE self)
|
603
643
|
{
|
604
644
|
xmlTextReaderPtr reader;
|
605
645
|
|
606
646
|
Data_Get_Struct(self, xmlTextReader, reader);
|
607
647
|
|
608
|
-
if(xmlTextReaderIsEmptyElement(reader))
|
648
|
+
if (xmlTextReaderIsEmptyElement(reader)) {
|
609
649
|
return Qtrue;
|
650
|
+
}
|
610
651
|
|
611
652
|
return Qfalse;
|
612
653
|
}
|
613
654
|
|
614
|
-
|
615
|
-
|
616
|
-
void init_xml_reader()
|
655
|
+
void
|
656
|
+
noko_init_xml_reader()
|
617
657
|
{
|
618
|
-
VALUE module = rb_define_module("Nokogiri");
|
619
|
-
VALUE xml = rb_define_module_under(module, "XML");
|
620
|
-
|
621
658
|
/*
|
622
659
|
* The Reader parser allows you to effectively pull parse an XML document.
|
623
660
|
* Once instantiated, call Nokogiri::XML::Reader#each to iterate over each
|
624
661
|
* node. Note that you may only iterate over the document once!
|
625
662
|
*/
|
626
|
-
|
627
|
-
|
628
|
-
cNokogiriXmlReader
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
rb_define_method(
|
634
|
-
rb_define_method(
|
635
|
-
rb_define_method(
|
636
|
-
rb_define_method(
|
637
|
-
rb_define_method(
|
638
|
-
rb_define_method(
|
639
|
-
rb_define_method(
|
640
|
-
rb_define_method(
|
641
|
-
rb_define_method(
|
642
|
-
rb_define_method(
|
643
|
-
rb_define_method(
|
644
|
-
rb_define_method(
|
645
|
-
rb_define_method(
|
646
|
-
rb_define_method(
|
647
|
-
rb_define_method(
|
648
|
-
rb_define_method(
|
649
|
-
rb_define_method(
|
650
|
-
rb_define_method(
|
651
|
-
rb_define_method(
|
652
|
-
rb_define_method(
|
653
|
-
rb_define_method(
|
654
|
-
rb_define_method(klass, "base_uri", base_uri, 0);
|
655
|
-
|
656
|
-
rb_define_private_method(klass, "attr_nodes", attribute_nodes, 0);
|
663
|
+
cNokogiriXmlReader = rb_define_class_under(mNokogiriXml, "Reader", rb_cObject);
|
664
|
+
|
665
|
+
rb_define_singleton_method(cNokogiriXmlReader, "from_memory", from_memory, -1);
|
666
|
+
rb_define_singleton_method(cNokogiriXmlReader, "from_io", from_io, -1);
|
667
|
+
|
668
|
+
rb_define_method(cNokogiriXmlReader, "attribute", reader_attribute, 1);
|
669
|
+
rb_define_method(cNokogiriXmlReader, "attribute_at", attribute_at, 1);
|
670
|
+
rb_define_method(cNokogiriXmlReader, "attribute_count", attribute_count, 0);
|
671
|
+
rb_define_method(cNokogiriXmlReader, "attribute_nodes", rb_xml_reader_attribute_nodes, 0);
|
672
|
+
rb_define_method(cNokogiriXmlReader, "attributes?", attributes_eh, 0);
|
673
|
+
rb_define_method(cNokogiriXmlReader, "base_uri", base_uri, 0);
|
674
|
+
rb_define_method(cNokogiriXmlReader, "default?", default_eh, 0);
|
675
|
+
rb_define_method(cNokogiriXmlReader, "depth", depth, 0);
|
676
|
+
rb_define_method(cNokogiriXmlReader, "empty_element?", empty_element_p, 0);
|
677
|
+
rb_define_method(cNokogiriXmlReader, "inner_xml", inner_xml, 0);
|
678
|
+
rb_define_method(cNokogiriXmlReader, "lang", lang, 0);
|
679
|
+
rb_define_method(cNokogiriXmlReader, "local_name", local_name, 0);
|
680
|
+
rb_define_method(cNokogiriXmlReader, "name", name, 0);
|
681
|
+
rb_define_method(cNokogiriXmlReader, "namespace_uri", namespace_uri, 0);
|
682
|
+
rb_define_method(cNokogiriXmlReader, "namespaces", namespaces, 0);
|
683
|
+
rb_define_method(cNokogiriXmlReader, "node_type", node_type, 0);
|
684
|
+
rb_define_method(cNokogiriXmlReader, "outer_xml", outer_xml, 0);
|
685
|
+
rb_define_method(cNokogiriXmlReader, "prefix", prefix, 0);
|
686
|
+
rb_define_method(cNokogiriXmlReader, "read", read_more, 0);
|
687
|
+
rb_define_method(cNokogiriXmlReader, "state", state, 0);
|
688
|
+
rb_define_method(cNokogiriXmlReader, "value", value, 0);
|
689
|
+
rb_define_method(cNokogiriXmlReader, "value?", value_eh, 0);
|
690
|
+
rb_define_method(cNokogiriXmlReader, "xml_version", xml_version, 0);
|
657
691
|
}
|