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,709 @@
1
+ #include <xml_node.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * encode_special_chars(string)
6
+ *
7
+ * Encode any special characters in +string+
8
+ */
9
+ static VALUE encode_special_chars(VALUE self, VALUE string)
10
+ {
11
+ xmlNodePtr node;
12
+ Data_Get_Struct(self, xmlNode, node);
13
+ xmlChar * encoded = xmlEncodeSpecialChars(
14
+ node->doc,
15
+ (const xmlChar *)StringValuePtr(string)
16
+ );
17
+
18
+ VALUE encoded_str = rb_str_new2((const char *)encoded);
19
+ free(encoded);
20
+
21
+ return encoded_str;
22
+ }
23
+
24
+ /*
25
+ * call-seq:
26
+ * internal_subset
27
+ *
28
+ * Get the internal subset
29
+ */
30
+ static VALUE internal_subset(VALUE self)
31
+ {
32
+ xmlNodePtr node;
33
+ xmlDocPtr doc;
34
+ Data_Get_Struct(self, xmlNode, node);
35
+
36
+ if(!node->doc) return Qnil;
37
+
38
+ doc = node->doc;
39
+
40
+ if(!doc->intSubset) return Qnil;
41
+
42
+ return Nokogiri_wrap_xml_node((xmlNodePtr)doc->intSubset);
43
+ }
44
+
45
+ /*
46
+ * call-seq:
47
+ * dup
48
+ *
49
+ * Copy this node
50
+ */
51
+ static VALUE duplicate_node(VALUE self)
52
+ {
53
+ xmlNodePtr node, dup;
54
+ Data_Get_Struct(self, xmlNode, node);
55
+
56
+ dup = xmlCopyNode(node, 1);
57
+ if(dup == NULL) return Qnil;
58
+
59
+ return Nokogiri_wrap_xml_node(dup);
60
+ }
61
+
62
+ /*
63
+ * call-seq:
64
+ * unlink
65
+ *
66
+ * Unlink this node from its current context.
67
+ */
68
+ static VALUE unlink_node(VALUE self)
69
+ {
70
+ xmlNodePtr node;
71
+ Data_Get_Struct(self, xmlNode, node);
72
+ xmlUnlinkNode(node);
73
+ Nokogiri_xml_node_owned_set(node);
74
+ return self;
75
+ }
76
+
77
+ /*
78
+ * call-seq:
79
+ * blank?
80
+ *
81
+ * Is this node blank?
82
+ */
83
+ static VALUE blank_eh(VALUE self)
84
+ {
85
+ xmlNodePtr node;
86
+ Data_Get_Struct(self, xmlNode, node);
87
+ if(1 == xmlIsBlankNode(node))
88
+ return Qtrue;
89
+ return Qfalse;
90
+ }
91
+
92
+ /*
93
+ * call-seq:
94
+ * next_sibling
95
+ *
96
+ * Returns the next sibling node
97
+ */
98
+ static VALUE next_sibling(VALUE self)
99
+ {
100
+ xmlNodePtr node, sibling;
101
+ Data_Get_Struct(self, xmlNode, node);
102
+
103
+ sibling = node->next;
104
+ if(!sibling) return Qnil;
105
+
106
+ return Nokogiri_wrap_xml_node(sibling) ;
107
+ }
108
+
109
+ /*
110
+ * call-seq:
111
+ * previous_sibling
112
+ *
113
+ * Returns the previous sibling node
114
+ */
115
+ static VALUE previous_sibling(VALUE self)
116
+ {
117
+ xmlNodePtr node, sibling;
118
+ Data_Get_Struct(self, xmlNode, node);
119
+
120
+ sibling = node->prev;
121
+ if(!sibling) return Qnil;
122
+
123
+ return Nokogiri_wrap_xml_node(sibling);
124
+ }
125
+
126
+ /*
127
+ * call-seq:
128
+ * replace(new_node)
129
+ *
130
+ * replace node with the new node in the document.
131
+ */
132
+ static VALUE replace(VALUE self, VALUE _new_node)
133
+ {
134
+ xmlNodePtr node, new_node;
135
+ Data_Get_Struct(self, xmlNode, node);
136
+ Data_Get_Struct(_new_node, xmlNode, new_node);
137
+
138
+ xmlReplaceNode(node, new_node);
139
+ Nokogiri_xml_node_owned_set(node);
140
+ Nokogiri_xml_node_owned_set(new_node);
141
+ return self ;
142
+ }
143
+
144
+
145
+ /*
146
+ * call-seq:
147
+ * child
148
+ *
149
+ * Returns the child node
150
+ */
151
+ static VALUE child(VALUE self)
152
+ {
153
+ xmlNodePtr node, child;
154
+ Data_Get_Struct(self, xmlNode, node);
155
+
156
+ child = node->children;
157
+ if(!child) return Qnil;
158
+
159
+ return Nokogiri_wrap_xml_node(child);
160
+ }
161
+
162
+ /*
163
+ * call-seq:
164
+ * key?(attribute)
165
+ *
166
+ * Returns true if +attribute+ is set
167
+ */
168
+ static VALUE key_eh(VALUE self, VALUE attribute)
169
+ {
170
+ xmlNodePtr node;
171
+ Data_Get_Struct(self, xmlNode, node);
172
+ if(xmlHasProp(node, (xmlChar *)StringValuePtr(attribute)))
173
+ return Qtrue;
174
+ return Qfalse;
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * []=(property, value)
180
+ *
181
+ * Set the +property+ to +value+
182
+ */
183
+ static VALUE set(VALUE self, VALUE property, VALUE value)
184
+ {
185
+ xmlNodePtr node;
186
+ Data_Get_Struct(self, xmlNode, node);
187
+ xmlSetProp(node, (xmlChar *)StringValuePtr(property),
188
+ (xmlChar *)StringValuePtr(value));
189
+
190
+ return value;
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * remove_attribute(property)
196
+ *
197
+ * remove the property +property+
198
+ */
199
+ static VALUE remove_prop(VALUE self, VALUE property)
200
+ {
201
+ xmlNodePtr node;
202
+ xmlAttrPtr attr ;
203
+ Data_Get_Struct(self, xmlNode, node);
204
+ attr = xmlHasProp(node, (xmlChar *)StringValuePtr(property));
205
+ if (attr) { xmlRemoveProp(attr); }
206
+ return Qnil;
207
+ }
208
+
209
+ /*
210
+ * call-seq:
211
+ * get(attribute)
212
+ *
213
+ * Get the value for +attribute+
214
+ */
215
+ static VALUE get(VALUE self, VALUE attribute)
216
+ {
217
+ xmlNodePtr node;
218
+ xmlChar* propstr ;
219
+ VALUE rval ;
220
+ Data_Get_Struct(self, xmlNode, node);
221
+ propstr = xmlGetProp(node, (xmlChar *)StringValuePtr(attribute));
222
+ rval = rb_str_new2((char *)propstr) ;
223
+ xmlFree(propstr);
224
+ return rval ;
225
+ }
226
+
227
+ /*
228
+ * call-seq:
229
+ * attributes()
230
+ *
231
+ * returns a hash containing the node's attributes.
232
+ */
233
+ static VALUE attributes(VALUE self)
234
+ {
235
+ /* this code in the mode of xmlHasProp() */
236
+ xmlNodePtr node ;
237
+ VALUE attr ;
238
+
239
+ attr = rb_hash_new() ;
240
+ Data_Get_Struct(self, xmlNode, node);
241
+
242
+ Nokogiri_xml_node_properties(node, attr);
243
+
244
+ return attr ;
245
+ }
246
+
247
+ /*
248
+ * call-seq:
249
+ * namespaces()
250
+ *
251
+ * returns a hash containing the node's namespaces.
252
+ */
253
+ static VALUE namespaces(VALUE self)
254
+ {
255
+ /* this code in the mode of xmlHasProp() */
256
+ xmlNodePtr node ;
257
+ VALUE attr ;
258
+
259
+ attr = rb_hash_new() ;
260
+ Data_Get_Struct(self, xmlNode, node);
261
+
262
+ Nokogiri_xml_node_namespaces(node, attr);
263
+
264
+ return attr ;
265
+ }
266
+
267
+ /*
268
+ * call-seq:
269
+ * type
270
+ *
271
+ * Get the type for this node
272
+ */
273
+ static VALUE type(VALUE self)
274
+ {
275
+ xmlNodePtr node;
276
+ Data_Get_Struct(self, xmlNode, node);
277
+ return INT2NUM((int)node->type);
278
+ }
279
+
280
+ /*
281
+ * call-seq:
282
+ * content=
283
+ *
284
+ * Set the content for this Node
285
+ */
286
+ static VALUE set_content(VALUE self, VALUE content)
287
+ {
288
+ xmlNodePtr node;
289
+ Data_Get_Struct(self, xmlNode, node);
290
+ xmlNodeSetContent(node, (xmlChar *)StringValuePtr(content));
291
+ return content;
292
+ }
293
+
294
+ /*
295
+ * call-seq:
296
+ * content
297
+ *
298
+ * Returns the content for this Node
299
+ */
300
+ static VALUE get_content(VALUE self)
301
+ {
302
+ xmlNodePtr node;
303
+ Data_Get_Struct(self, xmlNode, node);
304
+
305
+ xmlChar * content = xmlNodeGetContent(node);
306
+ if(content) {
307
+ VALUE rval = rb_str_new2((char *)content);
308
+ xmlFree(content);
309
+ return rval;
310
+ }
311
+ return Qnil;
312
+ }
313
+
314
+ /*
315
+ * call-seq:
316
+ * parent=(parent_node)
317
+ *
318
+ * Set the parent Node for this Node
319
+ */
320
+ static VALUE set_parent(VALUE self, VALUE parent_node)
321
+ {
322
+ xmlNodePtr node, parent;
323
+ Data_Get_Struct(self, xmlNode, node);
324
+ Data_Get_Struct(parent_node, xmlNode, parent);
325
+
326
+ xmlAddChild(parent, node);
327
+ Nokogiri_xml_node_owned_set(node);
328
+ return parent_node;
329
+ }
330
+
331
+ /*
332
+ * call-seq:
333
+ * parent
334
+ *
335
+ * Get the parent Node for this Node
336
+ */
337
+ static VALUE get_parent(VALUE self)
338
+ {
339
+ xmlNodePtr node, parent;
340
+ Data_Get_Struct(self, xmlNode, node);
341
+
342
+ parent = node->parent;
343
+ if(!parent) return Qnil;
344
+
345
+ return Nokogiri_wrap_xml_node(parent) ;
346
+ }
347
+
348
+ /*
349
+ * call-seq:
350
+ * name=(new_name)
351
+ *
352
+ * Set the name for this Node
353
+ */
354
+ static VALUE set_name(VALUE self, VALUE new_name)
355
+ {
356
+ xmlNodePtr node;
357
+ Data_Get_Struct(self, xmlNode, node);
358
+ xmlNodeSetName(node, (xmlChar*)StringValuePtr(new_name));
359
+ return new_name;
360
+ }
361
+
362
+ /*
363
+ * call-seq:
364
+ * name
365
+ *
366
+ * Returns the name for this Node
367
+ */
368
+ static VALUE get_name(VALUE self)
369
+ {
370
+ xmlNodePtr node;
371
+ Data_Get_Struct(self, xmlNode, node);
372
+ return rb_str_new2((const char *)node->name);
373
+ }
374
+
375
+ /*
376
+ * call-seq:
377
+ * path
378
+ *
379
+ * Returns the path associated with this Node
380
+ */
381
+ static VALUE path(VALUE self)
382
+ {
383
+ xmlNodePtr node;
384
+ xmlChar *path ;
385
+ VALUE rval ;
386
+ Data_Get_Struct(self, xmlNode, node);
387
+
388
+ path = xmlGetNodePath(node);
389
+ rval = rb_str_new2((char *)path);
390
+ xmlFree(path);
391
+ return rval ;
392
+ }
393
+
394
+ /*
395
+ * call-seq:
396
+ * document
397
+ *
398
+ * Returns the Nokogiri::XML::Document associated with this Node
399
+ */
400
+ static VALUE document(VALUE self)
401
+ {
402
+ xmlNodePtr node;
403
+ Data_Get_Struct(self, xmlNode, node);
404
+
405
+ if(!node->doc) return Qnil;
406
+ return (VALUE)node->doc->_private;
407
+ }
408
+
409
+ /*
410
+ * call-seq:
411
+ * add_next_sibling(node)
412
+ *
413
+ * Insert +node+ after this node (as a sibling).
414
+ */
415
+ static VALUE add_next_sibling(VALUE self, VALUE rb_node)
416
+ {
417
+ xmlNodePtr node, new_sibling;
418
+ Data_Get_Struct(self, xmlNode, node);
419
+ Data_Get_Struct(rb_node, xmlNode, new_sibling);
420
+ xmlAddNextSibling(node, new_sibling);
421
+
422
+ rb_funcall(rb_node, rb_intern("decorate!"), 0);
423
+ Nokogiri_xml_node_owned_set(new_sibling);
424
+
425
+ return rb_node;
426
+ }
427
+
428
+ /*
429
+ * call-seq:
430
+ * add_previous_sibling(node)
431
+ *
432
+ * Insert +node+ before this node (as a sibling).
433
+ */
434
+ static VALUE add_previous_sibling(VALUE self, VALUE rb_node)
435
+ {
436
+ xmlNodePtr node, new_sibling;
437
+ Data_Get_Struct(self, xmlNode, node);
438
+ Data_Get_Struct(rb_node, xmlNode, new_sibling);
439
+ xmlAddPrevSibling(node, new_sibling);
440
+
441
+ rb_funcall(rb_node, rb_intern("decorate!"), 0);
442
+ Nokogiri_xml_node_owned_set(new_sibling);
443
+
444
+ return rb_node;
445
+ }
446
+
447
+ /*
448
+ * call-seq:
449
+ * to_xml
450
+ *
451
+ * Returns this node as XML
452
+ */
453
+ static VALUE to_xml(VALUE self)
454
+ {
455
+ xmlBufferPtr buf ;
456
+ xmlNodePtr node ;
457
+ VALUE xml ;
458
+
459
+ Data_Get_Struct(self, xmlNode, node);
460
+
461
+ buf = xmlBufferCreate() ;
462
+ xmlNodeDump(buf, node->doc, node, 2, 1);
463
+ xml = rb_str_new2((char*)buf->content);
464
+ xmlBufferFree(buf);
465
+ return xml ;
466
+ }
467
+
468
+
469
+ /*
470
+ * call-seq:
471
+ * new(name)
472
+ *
473
+ * Create a new node with +name+
474
+ */
475
+ static VALUE new(VALUE klass, VALUE name)
476
+ {
477
+ xmlNodePtr node = xmlNewNode(NULL, (xmlChar *)StringValuePtr(name));
478
+ VALUE rb_node = Nokogiri_wrap_xml_node(node) ;
479
+
480
+ if(rb_block_given_p()) rb_yield(rb_node);
481
+
482
+ Nokogiri_xml_node_owned_set(node);
483
+
484
+ return rb_node;
485
+ }
486
+
487
+
488
+ /*
489
+ * call-seq:
490
+ * new_from_str(string)
491
+ *
492
+ * Create a new node by parsing +string+
493
+ */
494
+ static VALUE new_from_str(VALUE klass, VALUE xml)
495
+ {
496
+ /*
497
+ * I couldn't find a more efficient way to do this. So we create a new
498
+ * document and copy (recursively) the root node.
499
+ */
500
+ VALUE rb_doc ;
501
+ xmlDocPtr doc ;
502
+ xmlNodePtr node ;
503
+
504
+ rb_doc = rb_funcall(cNokogiriXmlDocument, rb_intern("read_memory"), 4,
505
+ xml, Qnil, Qnil, INT2NUM(0));
506
+ Data_Get_Struct(rb_doc, xmlDoc, doc);
507
+ node = xmlCopyNode(xmlDocGetRootElement(doc), 1); /* 1 => recursive */
508
+ return Nokogiri_wrap_xml_node(node);
509
+ }
510
+
511
+ static void deallocate(xmlNodePtr node)
512
+ {
513
+ if (! Nokogiri_xml_node_owned_get(node)) {
514
+ NOKOGIRI_DEBUG_START_NODE(node);
515
+ xmlFreeNode(node);
516
+ NOKOGIRI_DEBUG_END(node);
517
+ }
518
+ }
519
+
520
+ static void gc_mark_node(xmlNodePtr node)
521
+ {
522
+ xmlNodePtr child ;
523
+ /* mark document */
524
+ if (node && node->doc && node->doc->_private)
525
+ rb_gc_mark((VALUE)node->doc->_private);
526
+ /* mark parent node */
527
+ if (node && node->parent && node->parent->_private)
528
+ rb_gc_mark((VALUE)node->parent->_private);
529
+ /* mark children nodes */
530
+ for (child = node->children ; child ; child = child->next) {
531
+ if (child->_private)
532
+ rb_gc_mark((VALUE)child->_private);
533
+ }
534
+ /* mark sibling nodes */
535
+ if (node->next && node->next->_private)
536
+ rb_gc_mark((VALUE)node->next->_private) ;
537
+ if (node->prev && node->prev->_private)
538
+ rb_gc_mark((VALUE)node->prev->_private) ;
539
+ }
540
+
541
+ VALUE Nokogiri_wrap_xml_node(xmlNodePtr node)
542
+ {
543
+ if (node->_private)
544
+ return (VALUE)node->_private ;
545
+
546
+ VALUE rb_node = Qnil;
547
+
548
+ switch(node->type)
549
+ {
550
+ VALUE klass;
551
+
552
+ case XML_TEXT_NODE:
553
+ klass = rb_const_get(mNokogiriXml, rb_intern("Text"));
554
+ rb_node = Data_Wrap_Struct(klass, gc_mark_node, deallocate, node) ;
555
+ break;
556
+ case XML_ELEMENT_NODE:
557
+ klass = rb_const_get(mNokogiriXml, rb_intern("Element"));
558
+ rb_node = Data_Wrap_Struct(klass, gc_mark_node, deallocate, node) ;
559
+ break;
560
+ case XML_ENTITY_DECL:
561
+ klass = rb_const_get(mNokogiriXml, rb_intern("EntityDeclaration"));
562
+ rb_node = Data_Wrap_Struct(klass, gc_mark_node, deallocate, node) ;
563
+ break;
564
+ case XML_CDATA_SECTION_NODE:
565
+ klass = rb_const_get(mNokogiriXml, rb_intern("CDATA"));
566
+ rb_node = Data_Wrap_Struct(klass, gc_mark_node, deallocate, node) ;
567
+ break;
568
+ case XML_DTD_NODE:
569
+ klass = rb_const_get(mNokogiriXml, rb_intern("DTD"));
570
+ rb_node = Data_Wrap_Struct(klass, gc_mark_node, deallocate, node) ;
571
+ break;
572
+ default:
573
+ rb_node = Data_Wrap_Struct(cNokogiriXmlNode, gc_mark_node, deallocate, node) ;
574
+ }
575
+
576
+ node->_private = (void*)rb_node ;
577
+ rb_funcall(rb_node, rb_intern("decorate!"), 0);
578
+ Nokogiri_xml_node_owned_set(node);
579
+ return rb_node ;
580
+ }
581
+
582
+
583
+ void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_hash)
584
+ {
585
+ xmlAttrPtr prop;
586
+ xmlChar* propstr ;
587
+ prop = node->properties ;
588
+ while (prop != NULL) {
589
+ propstr = xmlGetProp(node, prop->name) ;
590
+ rb_hash_aset(attr_hash, rb_str_new2((const char*)prop->name),
591
+ rb_str_new2((char*)propstr));
592
+ xmlFree(propstr);
593
+ prop = prop->next ;
594
+ }
595
+ }
596
+
597
+
598
+ #define XMLNS_PREFIX "xmlns"
599
+ #define XMLNS_PREFIX_LEN 6 /* including either colon or \0 */
600
+ #define XMLNS_BUFFER_LEN 128
601
+ void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
602
+ {
603
+ xmlNsPtr ns;
604
+ static char buffer[XMLNS_BUFFER_LEN] ;
605
+ char *key ;
606
+ size_t keylen ;
607
+
608
+ if (node->type != XML_ELEMENT_NODE) return ;
609
+
610
+ ns = node->nsDef;
611
+ while (ns != NULL) {
612
+
613
+ keylen = XMLNS_PREFIX_LEN + (ns->prefix ? (strlen((const char*)ns->prefix) + 1) : 0) ;
614
+ if (keylen > XMLNS_BUFFER_LEN) {
615
+ key = (char*)malloc(keylen) ;
616
+ } else {
617
+ key = buffer ;
618
+ }
619
+
620
+ if (ns->prefix) {
621
+ sprintf(key, "%s:%s", XMLNS_PREFIX, ns->prefix);
622
+ } else {
623
+ sprintf(key, "%s", XMLNS_PREFIX);
624
+ }
625
+
626
+ rb_hash_aset(attr_hash, rb_str_new2(key), rb_str_new2((const char*)ns->href)) ;
627
+ if (key != buffer) {
628
+ free(key);
629
+ }
630
+ ns = ns->next ;
631
+ }
632
+ }
633
+
634
+
635
+ void Nokogiri_xml_node_owned_set(xmlNodePtr node)
636
+ {
637
+ VALUE hash = rb_cvar_get(cNokogiriXmlNode, rb_intern("@@owned"));
638
+ rb_hash_aset(hash, INT2NUM((long)node), node->parent ? Qtrue : Qfalse) ;
639
+ }
640
+
641
+ int Nokogiri_xml_node_owned_get(xmlNodePtr node)
642
+ {
643
+ VALUE hash = rb_cvar_get(cNokogiriXmlNode, rb_intern("@@owned"));
644
+ VALUE q = rb_hash_aref(hash, INT2NUM((long)node)) ;
645
+ return q == Qtrue ? Qtrue : Qfalse ;
646
+ }
647
+
648
+ /*
649
+ * call-seq:
650
+ * owned?
651
+ *
652
+ * Is this node owned by a document?
653
+ */
654
+ static VALUE owned_eh(VALUE self)
655
+ {
656
+ xmlNodePtr node ;
657
+ VALUE hash = rb_cvar_get(cNokogiriXmlNode, rb_intern("@@owned"));
658
+ Data_Get_Struct(self, xmlNode, node);
659
+ return rb_hash_aref(hash, INT2NUM((long)node)) == Qtrue ? Qtrue : Qfalse ;
660
+ }
661
+
662
+
663
+ VALUE cNokogiriXmlNode ;
664
+ void init_xml_node()
665
+ {
666
+ /*
667
+ * HACK. This is so that rdoc will work with this C file.
668
+ */
669
+ /*
670
+ VALUE nokogiri = rb_define_module("Nokogiri");
671
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
672
+ VALUE klass = rb_define_class_under(xml, "Node", rb_cObject);
673
+ */
674
+
675
+ VALUE klass = cNokogiriXmlNode = rb_const_get(mNokogiriXml, rb_intern("Node"));
676
+
677
+ rb_define_singleton_method(klass, "new", new, 1);
678
+ rb_define_singleton_method(klass, "new_from_str", new_from_str, 1);
679
+
680
+ rb_define_method(klass, "document", document, 0);
681
+ rb_define_method(klass, "name", get_name, 0);
682
+ rb_define_method(klass, "name=", set_name, 1);
683
+ rb_define_method(klass, "parent=", set_parent, 1);
684
+ rb_define_method(klass, "parent", get_parent, 0);
685
+ rb_define_method(klass, "child", child, 0);
686
+ rb_define_method(klass, "next_sibling", next_sibling, 0);
687
+ rb_define_method(klass, "previous_sibling", previous_sibling, 0);
688
+ rb_define_method(klass, "replace", replace, 1);
689
+ rb_define_method(klass, "type", type, 0);
690
+ rb_define_method(klass, "content", get_content, 0);
691
+ rb_define_method(klass, "path", path, 0);
692
+ rb_define_method(klass, "key?", key_eh, 1);
693
+ rb_define_method(klass, "blank?", blank_eh, 0);
694
+ rb_define_method(klass, "[]=", set, 2);
695
+ rb_define_method(klass, "remove_attribute", remove_prop, 1);
696
+ rb_define_method(klass, "attributes", attributes, 0);
697
+ rb_define_method(klass, "namespaces", namespaces, 0);
698
+ rb_define_method(klass, "add_previous_sibling", add_previous_sibling, 1);
699
+ rb_define_method(klass, "add_next_sibling", add_next_sibling, 1);
700
+ rb_define_method(klass, "encode_special_chars", encode_special_chars, 1);
701
+ rb_define_method(klass, "to_xml", to_xml, 0);
702
+ rb_define_method(klass, "dup", duplicate_node, 0);
703
+ rb_define_method(klass, "unlink", unlink_node, 0);
704
+ rb_define_method(klass, "internal_subset", internal_subset, 0);
705
+
706
+ rb_define_private_method(klass, "native_content=", set_content, 1);
707
+ rb_define_private_method(klass, "get", get, 1);
708
+ rb_define_private_method(klass, "owned?", owned_eh, 0);
709
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NOKOGIRI_XML_NODE
2
+ #define NOKOGIRI_XML_NODE
3
+
4
+ #include <native.h>
5
+
6
+ void init_xml_node();
7
+ VALUE Nokogiri_wrap_xml_node(xmlNodePtr root);
8
+
9
+ extern VALUE cNokogiriXmlNode ;
10
+ VALUE Nokogiri_wrap_xml_node(xmlNodePtr node) ;
11
+ void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_hash) ;
12
+ void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash) ;
13
+ int Nokogiri_xml_node_owned_get(xmlNodePtr node) ;
14
+ void Nokogiri_xml_node_owned_set(xmlNodePtr node) ;
15
+ #endif