tenderlove-nokogiri 0.0.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/History.txt +6 -0
  2. data/Manifest.txt +120 -0
  3. data/README.ja.txt +86 -0
  4. data/README.txt +87 -0
  5. data/Rakefile +264 -0
  6. data/ext/nokogiri/extconf.rb +59 -0
  7. data/ext/nokogiri/html_document.c +83 -0
  8. data/ext/nokogiri/html_document.h +10 -0
  9. data/ext/nokogiri/html_sax_parser.c +32 -0
  10. data/ext/nokogiri/html_sax_parser.h +11 -0
  11. data/ext/nokogiri/native.c +40 -0
  12. data/ext/nokogiri/native.h +51 -0
  13. data/ext/nokogiri/xml_cdata.c +52 -0
  14. data/ext/nokogiri/xml_cdata.h +9 -0
  15. data/ext/nokogiri/xml_document.c +159 -0
  16. data/ext/nokogiri/xml_document.h +10 -0
  17. data/ext/nokogiri/xml_dtd.c +117 -0
  18. data/ext/nokogiri/xml_dtd.h +8 -0
  19. data/ext/nokogiri/xml_node.c +709 -0
  20. data/ext/nokogiri/xml_node.h +15 -0
  21. data/ext/nokogiri/xml_node_set.c +124 -0
  22. data/ext/nokogiri/xml_node_set.h +9 -0
  23. data/ext/nokogiri/xml_reader.c +429 -0
  24. data/ext/nokogiri/xml_reader.h +10 -0
  25. data/ext/nokogiri/xml_sax_parser.c +174 -0
  26. data/ext/nokogiri/xml_sax_parser.h +10 -0
  27. data/ext/nokogiri/xml_syntax_error.c +194 -0
  28. data/ext/nokogiri/xml_syntax_error.h +11 -0
  29. data/ext/nokogiri/xml_text.c +29 -0
  30. data/ext/nokogiri/xml_text.h +9 -0
  31. data/ext/nokogiri/xml_xpath.c +46 -0
  32. data/ext/nokogiri/xml_xpath.h +11 -0
  33. data/ext/nokogiri/xml_xpath_context.c +81 -0
  34. data/ext/nokogiri/xml_xpath_context.h +9 -0
  35. data/ext/nokogiri/xslt_stylesheet.c +108 -0
  36. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  37. data/lib/nokogiri/css/node.rb +95 -0
  38. data/lib/nokogiri/css/parser.rb +24 -0
  39. data/lib/nokogiri/css/parser.y +198 -0
  40. data/lib/nokogiri/css/tokenizer.rb +9 -0
  41. data/lib/nokogiri/css/tokenizer.rex +63 -0
  42. data/lib/nokogiri/css/xpath_visitor.rb +165 -0
  43. data/lib/nokogiri/css.rb +6 -0
  44. data/lib/nokogiri/decorators/hpricot/node.rb +58 -0
  45. data/lib/nokogiri/decorators/hpricot/node_set.rb +14 -0
  46. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +17 -0
  47. data/lib/nokogiri/decorators/hpricot.rb +3 -0
  48. data/lib/nokogiri/decorators.rb +1 -0
  49. data/lib/nokogiri/hpricot.rb +47 -0
  50. data/lib/nokogiri/html/builder.rb +9 -0
  51. data/lib/nokogiri/html/document.rb +9 -0
  52. data/lib/nokogiri/html/sax/parser.rb +21 -0
  53. data/lib/nokogiri/html.rb +95 -0
  54. data/lib/nokogiri/version.rb +3 -0
  55. data/lib/nokogiri/xml/after_handler.rb +18 -0
  56. data/lib/nokogiri/xml/before_handler.rb +32 -0
  57. data/lib/nokogiri/xml/builder.rb +79 -0
  58. data/lib/nokogiri/xml/cdata.rb +9 -0
  59. data/lib/nokogiri/xml/document.rb +30 -0
  60. data/lib/nokogiri/xml/dtd.rb +6 -0
  61. data/lib/nokogiri/xml/node.rb +195 -0
  62. data/lib/nokogiri/xml/node_set.rb +183 -0
  63. data/lib/nokogiri/xml/notation.rb +6 -0
  64. data/lib/nokogiri/xml/reader.rb +14 -0
  65. data/lib/nokogiri/xml/sax/document.rb +59 -0
  66. data/lib/nokogiri/xml/sax/parser.rb +33 -0
  67. data/lib/nokogiri/xml/sax.rb +9 -0
  68. data/lib/nokogiri/xml/syntax_error.rb +21 -0
  69. data/lib/nokogiri/xml/text.rb +6 -0
  70. data/lib/nokogiri/xml/xpath.rb +6 -0
  71. data/lib/nokogiri/xml/xpath_context.rb +14 -0
  72. data/lib/nokogiri/xml.rb +67 -0
  73. data/lib/nokogiri/xslt/stylesheet.rb +6 -0
  74. data/lib/nokogiri/xslt.rb +11 -0
  75. data/lib/nokogiri.rb +51 -0
  76. data/nokogiri.gemspec +34 -0
  77. data/test/css/test_nthiness.rb +159 -0
  78. data/test/css/test_parser.rb +224 -0
  79. data/test/css/test_tokenizer.rb +162 -0
  80. data/test/css/test_xpath_visitor.rb +54 -0
  81. data/test/files/staff.xml +59 -0
  82. data/test/files/staff.xslt +32 -0
  83. data/test/files/tlm.html +850 -0
  84. data/test/helper.rb +70 -0
  85. data/test/hpricot/files/basic.xhtml +17 -0
  86. data/test/hpricot/files/boingboing.html +2266 -0
  87. data/test/hpricot/files/cy0.html +3653 -0
  88. data/test/hpricot/files/immob.html +400 -0
  89. data/test/hpricot/files/pace_application.html +1320 -0
  90. data/test/hpricot/files/tenderlove.html +16 -0
  91. data/test/hpricot/files/uswebgen.html +220 -0
  92. data/test/hpricot/files/utf8.html +1054 -0
  93. data/test/hpricot/files/week9.html +1723 -0
  94. data/test/hpricot/files/why.xml +19 -0
  95. data/test/hpricot/load_files.rb +7 -0
  96. data/test/hpricot/test_alter.rb +67 -0
  97. data/test/hpricot/test_builder.rb +27 -0
  98. data/test/hpricot/test_parser.rb +423 -0
  99. data/test/hpricot/test_paths.rb +15 -0
  100. data/test/hpricot/test_preserved.rb +78 -0
  101. data/test/hpricot/test_xml.rb +30 -0
  102. data/test/html/sax/test_parser.rb +27 -0
  103. data/test/html/test_builder.rb +78 -0
  104. data/test/html/test_document.rb +86 -0
  105. data/test/test_convert_xpath.rb +180 -0
  106. data/test/test_nokogiri.rb +36 -0
  107. data/test/test_reader.rb +222 -0
  108. data/test/test_xslt_transforms.rb +29 -0
  109. data/test/xml/sax/test_parser.rb +93 -0
  110. data/test/xml/test_builder.rb +16 -0
  111. data/test/xml/test_cdata.rb +18 -0
  112. data/test/xml/test_document.rb +171 -0
  113. data/test/xml/test_dtd.rb +43 -0
  114. data/test/xml/test_node.rb +223 -0
  115. data/test/xml/test_node_set.rb +116 -0
  116. data/test/xml/test_text.rb +13 -0
  117. metadata +214 -0
@@ -0,0 +1,124 @@
1
+ #include <xml_node_set.h>
2
+ #include <libxml/xpathInternals.h>
3
+ /*
4
+ * call-seq:
5
+ * length
6
+ *
7
+ * Get the length of the node set
8
+ */
9
+ static VALUE length(VALUE self)
10
+ {
11
+ xmlNodeSetPtr node_set;
12
+ Data_Get_Struct(self, xmlNodeSet, node_set);
13
+
14
+ if(node_set)
15
+ return INT2NUM(node_set->nodeNr);
16
+
17
+ return INT2NUM(0);
18
+ }
19
+
20
+ /*
21
+ * call-seq:
22
+ * push(node)
23
+ *
24
+ * Append +node+ to the NodeSet.
25
+ */
26
+ static VALUE push(VALUE self, VALUE rb_node)
27
+ {
28
+ xmlNodeSetPtr node_set;
29
+ xmlNodePtr node;
30
+
31
+ Data_Get_Struct(self, xmlNodeSet, node_set);
32
+ Data_Get_Struct(rb_node, xmlNode, node);
33
+ xmlXPathNodeSetAdd(node_set, node);
34
+ return self;
35
+ }
36
+
37
+ /*
38
+ * call-seq:
39
+ * [](i)
40
+ *
41
+ * Get the node at index +i+
42
+ */
43
+ static VALUE index_at(VALUE self, VALUE number)
44
+ {
45
+ int i = NUM2INT(number);
46
+ xmlNodeSetPtr node_set;
47
+ Data_Get_Struct(self, xmlNodeSet, node_set);
48
+
49
+ if(i >= node_set->nodeNr || abs(i) > node_set->nodeNr)
50
+ return Qnil;
51
+
52
+ if(i < 0)
53
+ i = i + node_set->nodeNr;
54
+
55
+ return Nokogiri_wrap_xml_node(node_set->nodeTab[i]);
56
+ }
57
+
58
+ static void gc_mark(xmlNodeSetPtr node_set)
59
+ {
60
+ int j ;
61
+ for (j = 0 ; j < node_set->nodeNr ; ++j) {
62
+ if (node_set->nodeTab[j]->_private)
63
+ rb_gc_mark((VALUE)node_set->nodeTab[j]->_private);
64
+ }
65
+ }
66
+
67
+ static void deallocate(xmlNodeSetPtr node_set)
68
+ {
69
+ /*
70
+ * xmlXPathFreeNodeSet() contains an implicit assumption that it is being
71
+ * called before any of its pointed-to nodes have been free()d. this
72
+ * assumption lies in the operation where it dereferences nodeTab pointers
73
+ * while searching for namespace nodes to free.
74
+ *
75
+ * however, since Ruby's GC mechanism cannot guarantee the strict order in
76
+ * which ruby objects will be GC'd, nodes may be garbage collected before a
77
+ * nodeset containing pointers to those nodes. (this is true regardless of
78
+ * how we declare dependencies between objects with rb_gc_mark().)
79
+ *
80
+ * as a result, xmlXPathFreeNodeSet() will perform unsafe memory operations,
81
+ * and calling it would be evil.
82
+ *
83
+ * on the bright side, though, Nokogiri's API currently does not cause
84
+ * namespace nodes to be included in node sets, ever.
85
+ *
86
+ * armed with that fact, we examined xmlXPathFreeNodeSet() and related libxml
87
+ * code and determined that, within the Nokogiri abstraction, we will not
88
+ * leak memory if we simply free the node set's memory directly. that's only
89
+ * quasi-evil!
90
+ *
91
+ * there's probably a lesson in here somewhere about intermingling, within a
92
+ * single array, structs with different memory-ownership semantics. or more
93
+ * generally, a lesson about building an API in C/C++ that does not contain
94
+ * assumptions about the strict order in which memory will be released. hey,
95
+ * that sounds like a great idea for a blog post! get to it!
96
+ *
97
+ * "In Valgrind We Trust." seriously.
98
+ */
99
+ NOKOGIRI_DEBUG_START(node_set) ;
100
+ if (node_set->nodeTab != NULL)
101
+ xmlFree(node_set->nodeTab);
102
+ xmlFree(node_set);
103
+ NOKOGIRI_DEBUG_END(node_set) ;
104
+ }
105
+
106
+ static VALUE allocate(VALUE klass)
107
+ {
108
+ return Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL));
109
+ }
110
+
111
+ VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set)
112
+ {
113
+ return Data_Wrap_Struct(cNokogiriXmlNodeSet, gc_mark, deallocate, node_set);
114
+ }
115
+
116
+ VALUE cNokogiriXmlNodeSet ;
117
+ void init_xml_node_set(void)
118
+ {
119
+ VALUE klass = cNokogiriXmlNodeSet = rb_eval_string("Nokogiri::XML::NodeSet");
120
+ rb_define_alloc_func(klass, allocate);
121
+ rb_define_method(klass, "length", length, 0);
122
+ rb_define_method(klass, "[]", index_at, 1);
123
+ rb_define_method(klass, "push", push, 1);
124
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef NOKOGIRI_XML_NODE_SET
2
+ #define NOKOGIRI_XML_NODE_SET
3
+
4
+ #include <native.h>
5
+ void init_xml_node_set();
6
+
7
+ extern VALUE cNokogiriXmlNodeSet ;
8
+ VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set) ;
9
+ #endif
@@ -0,0 +1,429 @@
1
+ #include <xml_reader.h>
2
+
3
+ static void dealloc(xmlTextReaderPtr reader)
4
+ {
5
+ NOKOGIRI_DEBUG_START(reader);
6
+ xmlFreeTextReader(reader);
7
+ NOKOGIRI_DEBUG_END(reader);
8
+ }
9
+
10
+ static int has_attributes(xmlTextReaderPtr reader)
11
+ {
12
+ /*
13
+ * this implementation of xmlTextReaderHasAttributes explicitly includes
14
+ * namespaces and properties, because some earlier versions ignore
15
+ * namespaces.
16
+ */
17
+ xmlNodePtr node ;
18
+ node = xmlTextReaderCurrentNode(reader);
19
+ if (node == NULL)
20
+ return(0);
21
+
22
+ if ((node->type == XML_ELEMENT_NODE) &&
23
+ ((node->properties != NULL) || (node->nsDef != NULL)))
24
+ return(1);
25
+ return(0);
26
+ }
27
+
28
+ /*
29
+ * call-seq:
30
+ * default?
31
+ *
32
+ * Was an attribute generated from the default value in the DTD or schema?
33
+ */
34
+ static VALUE default_eh(VALUE self)
35
+ {
36
+ xmlTextReaderPtr reader;
37
+ Data_Get_Struct(self, xmlTextReader, reader);
38
+ int eh = xmlTextReaderIsDefault(reader);
39
+ if(eh == 0) return Qfalse;
40
+ if(eh == 1) return Qtrue;
41
+
42
+ return Qnil;
43
+ }
44
+
45
+ /*
46
+ * call-seq:
47
+ * value?
48
+ *
49
+ * Does this node have a text value?
50
+ */
51
+ static VALUE value_eh(VALUE self)
52
+ {
53
+ xmlTextReaderPtr reader;
54
+ Data_Get_Struct(self, xmlTextReader, reader);
55
+ int eh = xmlTextReaderHasValue(reader);
56
+ if(eh == 0) return Qfalse;
57
+ if(eh == 1) return Qtrue;
58
+
59
+ return Qnil;
60
+ }
61
+
62
+ /*
63
+ * call-seq:
64
+ * attributes?
65
+ *
66
+ * Does this node have attributes?
67
+ */
68
+ static VALUE attributes_eh(VALUE self)
69
+ {
70
+ xmlTextReaderPtr reader;
71
+ Data_Get_Struct(self, xmlTextReader, reader);
72
+ int eh = has_attributes(reader);
73
+ if(eh == 0) return Qfalse;
74
+ if(eh == 1) return Qtrue;
75
+
76
+ return Qnil;
77
+ }
78
+
79
+ /*
80
+ * call-seq:
81
+ * attributes
82
+ *
83
+ * Get a Hash of attributes for this node
84
+ */
85
+ static VALUE attributes(VALUE self)
86
+ {
87
+ xmlTextReaderPtr reader;
88
+ VALUE attr ;
89
+
90
+ Data_Get_Struct(self, xmlTextReader, reader);
91
+
92
+ attr = rb_hash_new() ;
93
+
94
+ if (! has_attributes(reader))
95
+ return attr ;
96
+
97
+ xmlNodePtr ptr = xmlTextReaderExpand(reader);
98
+ if(ptr == NULL) return Qnil;
99
+
100
+ Nokogiri_xml_node_namespaces(ptr, attr);
101
+ Nokogiri_xml_node_properties(ptr, attr);
102
+
103
+ return attr ;
104
+ }
105
+
106
+ /*
107
+ * call-seq:
108
+ * attribute_at(index)
109
+ *
110
+ * Get the value of attribute at +index+
111
+ */
112
+ static VALUE attribute_at(VALUE self, VALUE index)
113
+ {
114
+ xmlTextReaderPtr reader;
115
+ Data_Get_Struct(self, xmlTextReader, reader);
116
+
117
+ if(index == Qnil) return Qnil;
118
+ index = rb_funcall(index, rb_intern("to_i"), 0);
119
+
120
+ xmlChar * value = xmlTextReaderGetAttributeNo(
121
+ reader,
122
+ NUM2INT(index)
123
+ );
124
+ if(value == NULL) return Qnil;
125
+
126
+ VALUE rb_value = rb_str_new2((const char *)value);
127
+ xmlFree(value);
128
+ return rb_value;
129
+ }
130
+
131
+ /*
132
+ * call-seq:
133
+ * attribute(name)
134
+ *
135
+ * Get the value of attribute named +name+
136
+ */
137
+ static VALUE reader_attribute(VALUE self, VALUE name)
138
+ {
139
+ xmlTextReaderPtr reader;
140
+ xmlChar *value ;
141
+ Data_Get_Struct(self, xmlTextReader, reader);
142
+
143
+ if(name == Qnil) return Qnil;
144
+ name = StringValue(name) ;
145
+
146
+ value = xmlTextReaderGetAttribute(reader, (xmlChar*)StringValuePtr(name));
147
+ if(value == NULL) {
148
+ /* this section is an attempt to workaround older versions of libxml that
149
+ don't handle namespaces properly in all attribute-and-friends functions */
150
+ xmlChar *prefix = NULL ;
151
+ xmlChar *localname = xmlSplitQName2((xmlChar*)StringValuePtr(name), &prefix);
152
+ if (localname != NULL) {
153
+ value = xmlTextReaderLookupNamespace(reader, localname);
154
+ free(localname) ;
155
+ } else {
156
+ value = xmlTextReaderLookupNamespace(reader, prefix);
157
+ }
158
+ }
159
+ if(value == NULL) return Qnil;
160
+
161
+ VALUE rb_value = rb_str_new2((const char *)value);
162
+ xmlFree(value);
163
+ return rb_value;
164
+ }
165
+
166
+ /*
167
+ * call-seq:
168
+ * attribute_count
169
+ *
170
+ * Get the number of attributes for the current node
171
+ */
172
+ static VALUE attribute_count(VALUE self)
173
+ {
174
+ xmlTextReaderPtr reader;
175
+ Data_Get_Struct(self, xmlTextReader, reader);
176
+ int count = xmlTextReaderAttributeCount(reader);
177
+ if(count == -1) return Qnil;
178
+
179
+ return INT2NUM(count);
180
+ }
181
+
182
+ /*
183
+ * call-seq:
184
+ * depth
185
+ *
186
+ * Get the depth of the node
187
+ */
188
+ static VALUE depth(VALUE self)
189
+ {
190
+ xmlTextReaderPtr reader;
191
+ Data_Get_Struct(self, xmlTextReader, reader);
192
+ int depth = xmlTextReaderDepth(reader);
193
+ if(depth == -1) return Qnil;
194
+
195
+ return INT2NUM(depth);
196
+ }
197
+
198
+ /*
199
+ * call-seq:
200
+ * encoding
201
+ *
202
+ * Get the encoding for the document
203
+ */
204
+ static VALUE encoding(VALUE self)
205
+ {
206
+ xmlTextReaderPtr reader;
207
+ Data_Get_Struct(self, xmlTextReader, reader);
208
+ const char * encoding = (const char *)xmlTextReaderConstEncoding(reader);
209
+ if(encoding == NULL) return Qnil;
210
+
211
+ return rb_str_new2(encoding);
212
+ }
213
+
214
+ /*
215
+ * call-seq:
216
+ * xml_version
217
+ *
218
+ * Get the XML version of the document being read
219
+ */
220
+ static VALUE xml_version(VALUE self)
221
+ {
222
+ xmlTextReaderPtr reader;
223
+ Data_Get_Struct(self, xmlTextReader, reader);
224
+ const char * version = (const char *)xmlTextReaderConstXmlVersion(reader);
225
+ if(version == NULL) return Qnil;
226
+
227
+ return rb_str_new2(version);
228
+ }
229
+
230
+ /*
231
+ * call-seq:
232
+ * lang
233
+ *
234
+ * Get the xml:lang scope within which the node resides.
235
+ */
236
+ static VALUE lang(VALUE self)
237
+ {
238
+ xmlTextReaderPtr reader;
239
+ Data_Get_Struct(self, xmlTextReader, reader);
240
+ const char * lang = (const char *)xmlTextReaderConstXmlLang(reader);
241
+ if(lang == NULL) return Qnil;
242
+
243
+ return rb_str_new2(lang);
244
+ }
245
+
246
+ /*
247
+ * call-seq:
248
+ * value
249
+ *
250
+ * Get the text value of the node if present
251
+ */
252
+ static VALUE value(VALUE self)
253
+ {
254
+ xmlTextReaderPtr reader;
255
+ Data_Get_Struct(self, xmlTextReader, reader);
256
+ const char * value = (const char *)xmlTextReaderConstValue(reader);
257
+ if(value == NULL) return Qnil;
258
+
259
+ return rb_str_new2(value);
260
+ }
261
+
262
+ /*
263
+ * call-seq:
264
+ * prefix
265
+ *
266
+ * Get the shorthand reference to the namespace associated with the node.
267
+ */
268
+ static VALUE prefix(VALUE self)
269
+ {
270
+ xmlTextReaderPtr reader;
271
+ Data_Get_Struct(self, xmlTextReader, reader);
272
+ const char * prefix = (const char *)xmlTextReaderConstPrefix(reader);
273
+ if(prefix == NULL) return Qnil;
274
+
275
+ return rb_str_new2(prefix);
276
+ }
277
+
278
+ /*
279
+ * call-seq:
280
+ * namespace_uri
281
+ *
282
+ * Get the URI defining the namespace associated with the node
283
+ */
284
+ static VALUE namespace_uri(VALUE self)
285
+ {
286
+ xmlTextReaderPtr reader;
287
+ Data_Get_Struct(self, xmlTextReader, reader);
288
+ const char * uri = (const char *)xmlTextReaderConstNamespaceUri(reader);
289
+ if(uri == NULL) return Qnil;
290
+
291
+ return rb_str_new2(uri);
292
+ }
293
+
294
+ /*
295
+ * call-seq:
296
+ * local_name
297
+ *
298
+ * Get the local name of the node
299
+ */
300
+ static VALUE local_name(VALUE self)
301
+ {
302
+ xmlTextReaderPtr reader;
303
+ Data_Get_Struct(self, xmlTextReader, reader);
304
+ const char * name = (const char *)xmlTextReaderConstLocalName(reader);
305
+ if(name == NULL) return Qnil;
306
+
307
+ return rb_str_new2(name);
308
+ }
309
+
310
+ /*
311
+ * call-seq:
312
+ * name
313
+ *
314
+ * Get the name of the node
315
+ */
316
+ static VALUE name(VALUE self)
317
+ {
318
+ xmlTextReaderPtr reader;
319
+ Data_Get_Struct(self, xmlTextReader, reader);
320
+ const char * name = (const char *)xmlTextReaderConstName(reader);
321
+ if(name == NULL) return Qnil;
322
+
323
+ return rb_str_new2(name);
324
+ }
325
+
326
+ /*
327
+ * call-seq:
328
+ * state
329
+ *
330
+ * Get the state of the reader
331
+ */
332
+ static VALUE state(VALUE self)
333
+ {
334
+ xmlTextReaderPtr reader;
335
+ Data_Get_Struct(self, xmlTextReader, reader);
336
+ return INT2NUM(xmlTextReaderReadState(reader));
337
+ }
338
+
339
+ /*
340
+ * call-seq:
341
+ * read
342
+ *
343
+ * Move the Reader forward through the XML document.
344
+ */
345
+ static VALUE read_more(VALUE self)
346
+ {
347
+ xmlTextReaderPtr reader;
348
+ Data_Get_Struct(self, xmlTextReader, reader);
349
+
350
+ int ret = xmlTextReaderRead(reader);
351
+ if(ret == 1) return self;
352
+ if(ret == 0) return Qnil;
353
+
354
+ rb_raise(rb_eRuntimeError, "Error pulling: %d", ret);
355
+ }
356
+
357
+ /*
358
+ * call-seq:
359
+ * from_memory(string, url = nil, encoding = nil, options = 0)
360
+ *
361
+ * Create a new reader that parses +string+
362
+ */
363
+ static VALUE from_memory(int argc, VALUE *argv, VALUE klass)
364
+ {
365
+ VALUE rb_buffer, rb_url, encoding, rb_options;
366
+
367
+ const char * c_url = NULL;
368
+ const char * c_encoding = NULL;
369
+ int c_options = 0;
370
+
371
+ rb_scan_args(argc, argv, "13", &rb_buffer, &rb_url, &encoding, &rb_options);
372
+
373
+ rb_buffer = StringValue(rb_buffer) ;
374
+ if (RTEST(rb_url)) c_url = StringValuePtr(rb_url);
375
+ if (RTEST(encoding)) c_encoding = StringValuePtr(rb_url);
376
+ if (RTEST(rb_options)) c_options = NUM2INT(rb_options);
377
+
378
+ xmlTextReaderPtr reader = xmlReaderForMemory(
379
+ StringValuePtr(rb_buffer),
380
+ NUM2INT(rb_funcall(rb_buffer, rb_intern("length"), 0)),
381
+ c_url,
382
+ c_encoding,
383
+ c_options
384
+ );
385
+
386
+ if(reader == NULL) {
387
+ xmlFreeTextReader(reader);
388
+ rb_raise(rb_eRuntimeError, "couldn't create a parser");
389
+ }
390
+
391
+ return Data_Wrap_Struct(klass, NULL, dealloc, reader);
392
+ }
393
+
394
+ VALUE cNokogiriXmlReader;
395
+
396
+ void init_xml_reader()
397
+ {
398
+ VALUE module = rb_define_module("Nokogiri");
399
+ VALUE xml = rb_define_module_under(module, "XML");
400
+
401
+ /*
402
+ * The Reader parser allows you to effectively pull parse an XML document.
403
+ * Once instantiated, call Nokogiri::XML::Reader#each to iterate over each
404
+ * node. Note that you may only iterate over the document once!
405
+ */
406
+ VALUE klass = rb_define_class_under(xml, "Reader", rb_cObject);
407
+
408
+ cNokogiriXmlReader = klass;
409
+
410
+ rb_define_singleton_method(klass, "from_memory", from_memory, -1);
411
+ rb_define_method(klass, "read", read_more, 0);
412
+ rb_define_method(klass, "state", state, 0);
413
+ rb_define_method(klass, "name", name, 0);
414
+ rb_define_method(klass, "local_name", local_name, 0);
415
+ rb_define_method(klass, "namespace_uri", namespace_uri, 0);
416
+ rb_define_method(klass, "prefix", prefix, 0);
417
+ rb_define_method(klass, "value", value, 0);
418
+ rb_define_method(klass, "lang", lang, 0);
419
+ rb_define_method(klass, "xml_version", xml_version, 0);
420
+ rb_define_method(klass, "encoding", encoding, 0);
421
+ rb_define_method(klass, "depth", depth, 0);
422
+ rb_define_method(klass, "attribute_count", attribute_count, 0);
423
+ rb_define_method(klass, "attribute", reader_attribute, 1);
424
+ rb_define_method(klass, "attribute_at", attribute_at, 1);
425
+ rb_define_method(klass, "attributes", attributes, 0);
426
+ rb_define_method(klass, "attributes?", attributes_eh, 0);
427
+ rb_define_method(klass, "value?", value_eh, 0);
428
+ rb_define_method(klass, "default?", default_eh, 0);
429
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef NOKOGIRI_XML_READER
2
+ #define NOKOGIRI_XML_READER
3
+
4
+ #include <native.h>
5
+
6
+ void init_xml_reader();
7
+
8
+ extern VALUE cNokogiriXmlReader;
9
+
10
+ #endif