libxml-ruby 0.3.6 → 0.3.8

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.
Files changed (54) hide show
  1. data/CHANGELOG +28 -3
  2. data/LICENSE +2 -2
  3. data/README +21 -6
  4. data/Rakefile +13 -8
  5. data/TODO +5 -12
  6. data/ext/xml/extconf.rb +17 -17
  7. data/ext/xml/libxml.c +2 -2
  8. data/ext/xml/libxml.h +5 -2
  9. data/ext/xml/libxml.rb +107 -0
  10. data/ext/xml/ruby_xml_dtd.c +3 -3
  11. data/ext/xml/ruby_xml_node.c +112 -25
  12. data/ext/xml/ruby_xml_node_set.c +61 -10
  13. data/ext/xml/ruby_xml_parser.c +62 -8
  14. data/ext/xml/ruby_xml_sax_parser.c +298 -53
  15. data/ext/xml/ruby_xml_sax_parser.h +32 -1
  16. data/ext/xml/ruby_xml_schema.c +1 -1
  17. data/ext/xml/ruby_xml_schema.h +1 -1
  18. data/ext/xml/ruby_xml_xpath.c +7 -1
  19. data/ext/xml/ruby_xml_xpath_context.c +2 -1
  20. data/ext/xml/ruby_xml_xpath_context.h +2 -2
  21. data/ext/xml/ruby_xml_xpointer_context.c +1 -2
  22. data/ext/xml/sax_parser_callbacks.inc +202 -0
  23. data/tests/copy_bug.rb +1 -2
  24. data/tests/dtd-test.rb +1 -1
  25. data/tests/libxml_test.rb +2 -0
  26. data/tests/model/saxtest.xml +5 -0
  27. data/tests/runner.rb +2 -4
  28. data/tests/schema-test.rb +1 -1
  29. data/tests/tc_xml_document.rb +2 -2
  30. data/tests/tc_xml_document_write.rb +2 -2
  31. data/tests/tc_xml_document_write2.rb +2 -2
  32. data/tests/tc_xml_document_write3.rb +2 -2
  33. data/tests/tc_xml_node.rb +2 -2
  34. data/tests/tc_xml_node2.rb +2 -2
  35. data/tests/tc_xml_node3.rb +28 -0
  36. data/tests/tc_xml_node4.rb +84 -0
  37. data/tests/tc_xml_node_set.rb +2 -2
  38. data/tests/tc_xml_node_set2.rb +38 -0
  39. data/tests/tc_xml_node_xlink.rb +2 -2
  40. data/tests/tc_xml_parser.rb +2 -2
  41. data/tests/tc_xml_parser2.rb +2 -2
  42. data/tests/tc_xml_parser3.rb +2 -2
  43. data/tests/tc_xml_parser4.rb +2 -2
  44. data/tests/tc_xml_parser5.rb +2 -2
  45. data/tests/tc_xml_parser6.rb +2 -2
  46. data/tests/tc_xml_parser7.rb +2 -2
  47. data/tests/tc_xml_parser8.rb +32 -0
  48. data/tests/tc_xml_parser_context.rb +2 -2
  49. data/tests/tc_xml_xinclude.rb +2 -2
  50. data/tests/tc_xml_xpath.rb +3 -2
  51. data/tests/tc_xml_xpointer.rb +3 -2
  52. data/tests/test_xml_sax_parser.rb +64 -0
  53. metadata +13 -6
  54. data/tests/tc_default_validation.rb +0 -0
@@ -1,10 +1,15 @@
1
- /* $Id: ruby_xml_node_set.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
1
+ /* $Id: ruby_xml_node_set.c,v 1.3 2006/04/14 14:45:25 roscopeco Exp $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
5
5
  #include "libxml.h"
6
6
  #include "ruby_xml_node_set.h"
7
7
 
8
+ /*
9
+ * Document-class: XML::Node::Set
10
+ *
11
+ * Includes Enumerable.
12
+ */
8
13
  VALUE cXMLNodeSet;
9
14
 
10
15
  // TODO maybe we should support [] on nodeset?
@@ -24,14 +29,14 @@ ruby_xml_node_set_to_a(VALUE self) {
24
29
 
25
30
  Data_Get_Struct(self, ruby_xml_node_set, rxnset);
26
31
 
27
- if ((rxnset->node_set == NULL) || (rxnset->node_set->nodeNr == 0))
28
- return(Qnil);
29
-
30
32
  set_ary = rb_ary_new();
31
- for (i = 0; i < rxnset->node_set->nodeNr; i++) {
32
- nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[i]);
33
- rb_ary_push(set_ary, nodeobj);
33
+ if (!((rxnset->node_set == NULL) || (rxnset->node_set->nodeNr == 0))) {
34
+ for (i = 0; i < rxnset->node_set->nodeNr; i++) {
35
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[i]);
36
+ rb_ary_push(set_ary, nodeobj);
37
+ }
34
38
  }
39
+
35
40
  return(set_ary);
36
41
  }
37
42
 
@@ -68,6 +73,48 @@ ruby_xml_node_set_each(VALUE self) {
68
73
  }
69
74
 
70
75
 
76
+ /*
77
+ * call-seq:
78
+ * nodeset.empty? => (true|false)
79
+ *
80
+ * Determine whether this nodeset is empty (contains no nodes).
81
+ */
82
+ VALUE
83
+ ruby_xml_node_set_empty_q(VALUE self) {
84
+ ruby_xml_node_set *rxnset;
85
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
86
+ return ( rxnset->node_set == NULL || rxnset->node_set->nodeNr <= 0 ) ? Qtrue : Qfalse;
87
+ }
88
+
89
+
90
+ /*
91
+ * call-seq:
92
+ * nodeset.first => node
93
+ *
94
+ * Returns the first node in this node set, or nil if none exist.
95
+ */
96
+ VALUE
97
+ ruby_xml_node_set_first(VALUE self) {
98
+ ruby_xml_node_set *rxnset;
99
+ VALUE nodeobj;
100
+
101
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
102
+
103
+ if (rxnset->node_set == NULL || rxnset->node_set->nodeNr < 1)
104
+ return(Qnil);
105
+
106
+ switch(rxnset->node_set->nodeTab[0]->type) {
107
+ case XML_ATTRIBUTE_NODE:
108
+ nodeobj = ruby_xml_attr_new2(cXMLAttr, rxnset->xd, (xmlAttrPtr)rxnset->node_set->nodeTab[0]);
109
+ break;
110
+ default:
111
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[0]);
112
+ }
113
+
114
+ return(nodeobj);
115
+ }
116
+
117
+
71
118
  void
72
119
  ruby_xml_node_set_free(ruby_xml_node_set *rxnset) {
73
120
  void *data;
@@ -108,7 +155,7 @@ ruby_xml_node_set_length(VALUE self) {
108
155
  return(INT2NUM(rxnset->node_set->nodeNr));
109
156
  }
110
157
 
111
- // TODO Check this for doublefree (should we mark nodes?)
158
+
112
159
  static void
113
160
  ruby_xml_node_set_mark(ruby_xml_node_set *rxnset) {
114
161
  if (rxnset == NULL) return;
@@ -186,12 +233,16 @@ ruby_xml_node_set_xpath_data_get(VALUE self) {
186
233
 
187
234
  void
188
235
  ruby_init_xml_node_set(void) {
189
- cXMLNodeSet = rb_define_class_under(cXMLNode, "Set", rb_cObject);
236
+ cXMLNodeSet = rb_define_class_under(cXMLNode, "Set", rb_cObject);
237
+ rb_include_module(cXMLNodeSet, rb_const_get(rb_cObject, rb_intern("Enumerable")));
190
238
 
191
- rb_define_method(cXMLNodeSet, "to_a", ruby_xml_node_set_to_a, 0);
192
239
  rb_define_method(cXMLNodeSet, "each", ruby_xml_node_set_each, 0);
240
+ rb_define_method(cXMLNodeSet, "empty?", ruby_xml_node_set_empty_q, 0);
241
+ rb_define_method(cXMLNodeSet, "first", ruby_xml_node_set_first, 0);
193
242
  rb_define_method(cXMLNodeSet, "length", ruby_xml_node_set_length, 0);
243
+ rb_define_method(cXMLNodeSet, "to_a", ruby_xml_node_set_to_a, 0);
194
244
  rb_define_method(cXMLNodeSet, "xpath", ruby_xml_node_set_xpath_get, 0);
195
245
  rb_define_method(cXMLNodeSet, "xpath_ctxt",
196
246
  ruby_xml_node_set_xpath_data_get, 0);
247
+
197
248
  }
@@ -1,9 +1,12 @@
1
- /* $Id: ruby_xml_parser.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
1
+ /* $Id: ruby_xml_parser.c,v 1.3 2006/03/27 20:49:19 roscopeco Exp $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
5
5
  #include "libxml.h"
6
6
 
7
+ static VALUE libxml_xmlRubyErrorProc = Qnil;
8
+ static int id_call;
9
+
7
10
  int ruby_xml_parser_count = 0;
8
11
  VALUE cXMLParser;
9
12
  VALUE eXMLParserParseError;
@@ -218,7 +221,7 @@ ruby_xml_parser_enabled_memory_debug_location_q(VALUE class) {
218
221
 
219
222
  /*
220
223
  * call-seq:
221
- * XML::Parser.enabled_catalog? => (true|false)
224
+ * XML::Parser.enabled_regexp? => (true|false)
222
225
  *
223
226
  * Determine whether libxml regular expression support is enabled.
224
227
  */
@@ -267,7 +270,7 @@ ruby_xml_parser_enabled_thread_q(VALUE class) {
267
270
 
268
271
  /*
269
272
  * call-seq:
270
- * XML::Parser.enabled_catalog? => (true|false)
273
+ * XML::Parser.enabled_unicode? => (true|false)
271
274
  *
272
275
  * Determine whether libxml unicode support is enabled.
273
276
  */
@@ -283,7 +286,7 @@ ruby_xml_parser_enabled_unicode_q(VALUE class) {
283
286
 
284
287
  /*
285
288
  * call-seq:
286
- * XML::Parser.enabled_catalog? => (true|false)
289
+ * XML::Parser.enabled_xinclude? => (true|false)
287
290
  *
288
291
  * Determine whether libxml xinclude support is enabled.
289
292
  */
@@ -299,7 +302,7 @@ ruby_xml_parser_enabled_xinclude_q(VALUE class) {
299
302
 
300
303
  /*
301
304
  * call-seq:
302
- * XML::Parser.enabled_catalog? => (true|false)
305
+ * XML::Parser.enabled_xpath? => (true|false)
303
306
  *
304
307
  * Determine whether libxml xpath support is enabled.
305
308
  */
@@ -315,7 +318,7 @@ ruby_xml_parser_enabled_xpath_q(VALUE class) {
315
318
 
316
319
  /*
317
320
  * call-seq:
318
- * XML::Parser.enabled_catalog? => (true|false)
321
+ * XML::Parser.enabled_xpointer? => (true|false)
319
322
  *
320
323
  * Determine whether libxml xpointer support is enabled.
321
324
  */
@@ -331,7 +334,7 @@ ruby_xml_parser_enabled_xpointer_q(VALUE class) {
331
334
 
332
335
  /*
333
336
  * call-seq:
334
- * XML::Parser.enabled_catalog? => (true|false)
337
+ * XML::Parser.enabled_zlib? => (true|false)
335
338
  *
336
339
  * Determine whether libxml zlib support is enabled.
337
340
  */
@@ -1216,6 +1219,52 @@ ruby_xml_parser_str_set(VALUE self, VALUE str) {
1216
1219
  return(data->str);
1217
1220
  }
1218
1221
 
1222
+ /*
1223
+ * call-seq:
1224
+ * XML::Parser.register_error_handler(lambda { |msg| ... }) => old_handler
1225
+ * XML::Parser.register_error_handler(nil) => old_handler
1226
+ *
1227
+ * Register the attached block as the handler for parser errors.
1228
+ * A message describing parse errors is passed to the block.
1229
+ * Libxml passes error messages to the handler in parts, one per call.
1230
+ * A typical error results in six calls to this proc, with arguments:
1231
+ *
1232
+ * "Entity: line 1: ",
1233
+ * "parser ",
1234
+ * "error : ",
1235
+ * "Opening and ending tag mismatch: foo line 1 and foz\n",
1236
+ * "<foo><bar/></foz>\n",
1237
+ * " ^\n"
1238
+ *
1239
+ * Note that the error handler is shared by all threads.
1240
+ */
1241
+ VALUE
1242
+ ruby_xml_parser_registerErrorHandler(VALUE self, VALUE proc) {
1243
+ VALUE old_block = libxml_xmlRubyErrorProc;
1244
+ libxml_xmlRubyErrorProc = proc;
1245
+ return(old_block);
1246
+ }
1247
+
1248
+ static void
1249
+ libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, ...)
1250
+ {
1251
+ va_list ap;
1252
+ char str[1000];
1253
+ VALUE rstr;
1254
+
1255
+ if (libxml_xmlRubyErrorProc == Qnil) {
1256
+ va_start(ap, msg);
1257
+ vfprintf(stderr, msg, ap);
1258
+ va_end(ap);
1259
+ } else {
1260
+ va_start(ap, msg);
1261
+ if (vsnprintf(str, 999, msg, ap) >= 998) str[999] = 0;
1262
+ va_end(ap);
1263
+
1264
+ rstr = rb_str_new2(str);
1265
+ rb_funcall2(libxml_xmlRubyErrorProc, id_call, 1, &rstr);
1266
+ }
1267
+ }
1219
1268
 
1220
1269
  /* #define RUBY_XML_PARSER_ENABLED_INIT(func, method) \
1221
1270
  rb_define_singleton_method(cXMLParser, method, \
@@ -1351,7 +1400,7 @@ ruby_init_parser(void) {
1351
1400
  ruby_xml_parser_memory_used, 0);
1352
1401
  rb_define_singleton_method(cXMLParser, "new", ruby_xml_parser_new, 0);
1353
1402
  rb_define_singleton_method(cXMLParser, "string", ruby_xml_parser_new_string, 1);
1354
-
1403
+ rb_define_singleton_method(cXMLParser, "register_error_handler", ruby_xml_parser_registerErrorHandler, 1);
1355
1404
  rb_define_method(cXMLParser, "filename", ruby_xml_parser_filename_get, 0);
1356
1405
  rb_define_method(cXMLParser, "filename=", ruby_xml_parser_filename_set, 1);
1357
1406
  rb_define_method(cXMLParser, "io", ruby_xml_parser_io_get, 0);
@@ -1360,4 +1409,9 @@ ruby_init_parser(void) {
1360
1409
  rb_define_method(cXMLParser, "parser_context", ruby_xml_parser_parser_context_get, 0);
1361
1410
  rb_define_method(cXMLParser, "string", ruby_xml_parser_str_get, 0);
1362
1411
  rb_define_method(cXMLParser, "string=", ruby_xml_parser_str_set, 1);
1412
+
1413
+ // set up error handling
1414
+ xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1415
+ xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1416
+ id_call = rb_intern("call");
1363
1417
  }
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_sax_parser.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
1
+ /* $Id: ruby_xml_sax_parser.c,v 1.4 2006/04/14 23:46:06 roscopeco Exp $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -6,6 +6,9 @@
6
6
  #include "ruby_xml_sax_parser.h"
7
7
 
8
8
  VALUE cXMLSaxParser;
9
+ VALUE callsym;
10
+
11
+ #include "sax_parser_callbacks.inc"
9
12
 
10
13
  void
11
14
  ruby_xml_sax_parser_free(ruby_xml_sax_parser *rxsp) {
@@ -14,6 +17,31 @@ ruby_xml_sax_parser_free(ruby_xml_sax_parser *rxsp) {
14
17
  /* xmlFreeSax_Parser(rxsp->sax_parser); */
15
18
  }
16
19
 
20
+ #define mark_handler(rxsp, handler) \
21
+ if (rxsp->cbp->handler && (rxsp->cbp->handler != Qnil)) \
22
+ rb_gc_mark(rxsp->cbp->handler)
23
+
24
+ void
25
+ ruby_xml_sax_parser_mark(ruby_xml_sax_parser *rxsp) {
26
+ mark_handler(rxsp, internalSubset);
27
+ mark_handler(rxsp, isStandalone);
28
+ mark_handler(rxsp, hasInternalSubset);
29
+ mark_handler(rxsp, hasExternalSubset);
30
+ mark_handler(rxsp, startDocument);
31
+ mark_handler(rxsp, endDocument);
32
+ mark_handler(rxsp, startElement);
33
+ mark_handler(rxsp, endElement);
34
+ mark_handler(rxsp, reference);
35
+ mark_handler(rxsp, characters);
36
+ mark_handler(rxsp, processingInstruction);
37
+ mark_handler(rxsp, comment);
38
+ mark_handler(rxsp, xmlParserWarning);
39
+ mark_handler(rxsp, xmlParserError);
40
+ mark_handler(rxsp, xmlParserFatalError);
41
+ mark_handler(rxsp, cdataBlock);
42
+ }
43
+
44
+
17
45
  /*
18
46
  * call-seq:
19
47
  * XML::SaxParser.new => sax_parser
@@ -23,46 +51,18 @@ ruby_xml_sax_parser_free(ruby_xml_sax_parser *rxsp) {
23
51
  VALUE
24
52
  ruby_xml_sax_parser_new(VALUE class) {
25
53
  ruby_xml_sax_parser *rxsp;
26
-
27
- xmlSAXHandler emptySAXHandlerStruct = {
28
- NULL, /* internalSubset */
29
- NULL, /* isStandalone */
30
- NULL, /* hasInternalSubset */
31
- NULL, /* hasExternalSubset */
32
- NULL, /* resolveEntity */
33
- NULL, /* getEntity */
34
- NULL, /* entityDecl */
35
- NULL, /* notationDecl */
36
- NULL, /* attributeDecl */
37
- NULL, /* elementDecl */
38
- NULL, /* unparsedEntityDecl */
39
- NULL, /* setDocumentLocator */
40
- NULL, /* startDocument */
41
- NULL, /* endDocument */
42
- NULL, /* startElement */
43
- NULL, /* endElement */
44
- NULL, /* reference */
45
- NULL, /* characters */
46
- NULL, /* ignorableWhitespace */
47
- NULL, /* processingInstruction */
48
- NULL, /* comment */
49
- NULL, /* xmlParserWarning */
50
- NULL, /* xmlParserError */
51
- NULL, /* xmlParserError */
52
- NULL, /* getParameterEntity */
53
- NULL, /* cdataBlock; */
54
- NULL, /* externalSubset; */
55
- 1
56
- };
57
-
54
+
58
55
  rxsp = ALLOC(ruby_xml_sax_parser);
59
- rxsp->xsh = &emptySAXHandlerStruct;
60
-
56
+ rxsp->cbp = ALLOC(ruby_xml_sax_parser_callbacks);
57
+ memset(rxsp->cbp, 0, sizeof(ruby_xml_sax_parser_callbacks));
58
+ rxsp->xsh = &rubySAXHandlerStruct;
59
+
61
60
  rxsp->xpc = NULL;
62
61
  rxsp->filename = Qnil;
63
62
  rxsp->str = Qnil;
64
63
 
65
- return(Data_Wrap_Struct(class, 0, ruby_xml_sax_parser_free, rxsp));
64
+ return(Data_Wrap_Struct(class, ruby_xml_sax_parser_mark,
65
+ ruby_xml_sax_parser_free, rxsp));
66
66
  }
67
67
 
68
68
 
@@ -95,39 +95,248 @@ ruby_xml_sax_parser_filename_set(VALUE self, VALUE filename) {
95
95
  return(rxsp->filename);
96
96
  }
97
97
 
98
+ #define set_handler(self, argc, argv, handler) \
99
+ VALUE proc; \
100
+ rb_scan_args(argc, argv, "0&", &proc); \
101
+ ruby_xml_sax_parser *rxsp; \
102
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp); \
103
+ rxsp->cbp->handler = proc; \
104
+ return(Qnil);
105
+
106
+
107
+ /*
108
+ * call-seq:
109
+ * parser.on_internal_subset { |name, external_id, system_id| ... } => nil
110
+ *
111
+ * Set the callback block for an internal subset event.
112
+ */
113
+ VALUE
114
+ ruby_xml_sax_parser_on_internal_subset(int argc, VALUE *argv, VALUE self) {
115
+ set_handler(self, argc, argv, internalSubset);
116
+ }
117
+
118
+
119
+ /*
120
+ * call-seq:
121
+ * parser.on_is_standalone { || ... } => nil
122
+ *
123
+ * Set the callback proc for 'is standalone' event.
124
+ */
125
+ VALUE
126
+ ruby_xml_sax_parser_on_is_standalone(int argc, VALUE *argv, VALUE self) {
127
+ set_handler(self, argc, argv, isStandalone);
128
+ }
129
+
130
+
131
+ /*
132
+ * call-seq:
133
+ * parser.on_has_internal_subset { || ... } => nil
134
+ *
135
+ * Set the callback proc for an internal subset notification event.
136
+ */
137
+ VALUE
138
+ ruby_xml_sax_parser_on_has_internal_subset(int argc, VALUE *argv, VALUE self) {
139
+ set_handler(self, argc, argv, hasInternalSubset);
140
+ }
141
+
142
+
143
+ /*
144
+ * call-seq:
145
+ * parser.on_has_external_subset { || ... } => nil
146
+ *
147
+ * Set the callback proc for an external subset notification event.
148
+ */
149
+ VALUE
150
+ ruby_xml_sax_parser_on_has_external_subset(int argc, VALUE *argv, VALUE self) {
151
+ set_handler(self, argc, argv, hasExternalSubset);
152
+ }
153
+
154
+
155
+ /*
156
+ * call-seq:
157
+ * parser.on_start_document { || ... } => nil
158
+ *
159
+ * Set the callback proc for a start document event.
160
+ */
161
+ VALUE
162
+ ruby_xml_sax_parser_on_start_document(int argc, VALUE *argv, VALUE self) {
163
+ set_handler(self, argc, argv, startDocument);
164
+ }
165
+
166
+
167
+ /*
168
+ * call-seq:
169
+ * parser.on_end_document { || ... } => nil
170
+ *
171
+ * Set the callback proc for an end document event.
172
+ */
173
+ VALUE
174
+ ruby_xml_sax_parser_on_end_document(int argc, VALUE *argv, VALUE self) {
175
+ set_handler(self, argc, argv, endDocument);
176
+ }
177
+
178
+
179
+ /*
180
+ * call-seq:
181
+ * parser.on_start_element { |name, attr_hash| ... } => nil
182
+ *
183
+ * Set the callback proc for an element start event.
184
+ */
185
+ VALUE
186
+ ruby_xml_sax_parser_on_start_element(int argc, VALUE *argv, VALUE self) {
187
+ set_handler(self, argc, argv, startElement);
188
+ }
189
+
190
+
191
+ /*
192
+ * call-seq:
193
+ * parser.on_end_element { |name| ... } => nil
194
+ *
195
+ * Set the callback proc for an element end event.
196
+ */
197
+ VALUE
198
+ ruby_xml_sax_parser_on_end_element(int argc, VALUE *argv, VALUE self) {
199
+ set_handler(self, argc, argv, endElement);
200
+ }
201
+
202
+
203
+ /*
204
+ * call-seq:
205
+ * parser.on_reference { |name| ... } => nil
206
+ *
207
+ * Set the callback proc for a reference event.
208
+ */
209
+ VALUE
210
+ ruby_xml_sax_parser_on_reference(int argc, VALUE *argv, VALUE self) {
211
+ set_handler(self, argc, argv, reference);
212
+ }
213
+
214
+
215
+ /*
216
+ * call-seq:
217
+ * parser.on_characters { |chars| ... } => nil
218
+ *
219
+ * Set the callback proc for a characters event.
220
+ */
221
+ VALUE
222
+ ruby_xml_sax_parser_on_characters(int argc, VALUE *argv, VALUE self) {
223
+ set_handler(self, argc, argv, characters);
224
+ }
225
+
226
+
227
+ /*
228
+ * call-seq:
229
+ * parser.on_processing_instruction { |target, data| ... } => nil
230
+ *
231
+ * Set the callback proc for an processing instruction event.
232
+ */
233
+ VALUE
234
+ ruby_xml_sax_parser_on_processing_instruction(int argc, VALUE *argv, VALUE self) {
235
+ set_handler(self, argc, argv, processingInstruction);
236
+ }
237
+
238
+
239
+ /*
240
+ * call-seq:
241
+ * parser.on_comment { |msg| ... } => nil
242
+ *
243
+ * Set the callback proc for a comment event.
244
+ */
245
+ VALUE
246
+ ruby_xml_sax_parser_on_comment(int argc, VALUE *argv, VALUE self) {
247
+ set_handler(self, argc, argv, comment);
248
+ }
249
+
98
250
 
99
251
  /*
100
252
  * call-seq:
101
- * parser.parse => document
253
+ * parser.on_parser_warning { |msg| ... } => nil
254
+ *
255
+ * Set the callback proc that receives parser warnings.
256
+ */
257
+ VALUE
258
+ ruby_xml_sax_parser_on_parser_warning(int argc, VALUE *argv, VALUE self) {
259
+ set_handler(self, argc, argv, xmlParserWarning);
260
+ }
261
+
262
+
263
+ /*
264
+ * call-seq:
265
+ * parser.on_parser_error { |msg| ... } => nil
266
+ *
267
+ * Set the callback proc that receives parser errors.
268
+ */
269
+ VALUE
270
+ ruby_xml_sax_parser_on_parser_error(int argc, VALUE *argv, VALUE self) {
271
+ set_handler(self, argc, argv, xmlParserError);
272
+ }
273
+
274
+
275
+ /*
276
+ * call-seq:
277
+ * parser.on_parser_fatal_error { |msg| ... } => nil
278
+ *
279
+ * Set the callback proc that receives fatal parser errors.
280
+ */
281
+ VALUE
282
+ ruby_xml_sax_parser_on_parser_fatal_error(int argc, VALUE *argv, VALUE self) {
283
+ set_handler(self, argc, argv, xmlParserFatalError);
284
+ }
285
+
286
+ /*
287
+ * call-seq:
288
+ * parser.on_cdata_block { |cdata| ... } => nil
289
+ *
290
+ * Set the callback proc for a CDATA block event.
291
+ */
292
+ VALUE
293
+ ruby_xml_sax_parser_on_cdata_block(int argc, VALUE *argv, VALUE self) {
294
+ set_handler(self, argc, argv, cdataBlock);
295
+ }
296
+
297
+ /*
298
+ * call-seq:
299
+ * parser.on_external_subset { |name, external_id, system_id| ... } => nil
300
+ *
301
+ * Set the callback proc for an external subset event.
302
+ */
303
+ VALUE
304
+ ruby_xml_sax_parser_on_external_subset(int argc, VALUE *argv, VALUE self) {
305
+ set_handler(self, argc, argv, externalSubset);
306
+ }
307
+
308
+
309
+ /*
310
+ * call-seq:
311
+ * parser.parse => (true|false)
102
312
  *
103
- * Parse the input XML.
313
+ * Parse the input XML, generating callbacks to the procs
314
+ * registered with the parser (via the on_xxxx attributes).
104
315
  */
105
316
  VALUE
106
317
  ruby_xml_sax_parser_parse(VALUE self) {
107
318
  char *str;
108
- int status;
319
+ int status = 1;
109
320
  ruby_xml_sax_parser *rxsp;
110
- VALUE docobj = Qnil;
111
321
 
112
322
  Data_Get_Struct(self, ruby_xml_sax_parser, rxsp);
113
323
 
114
324
  if (rxsp->filename != Qnil) {
115
- status = xmlSAXUserParseFile(rxsp->xsh, NULL, StringValuePtr(rxsp->filename));
116
-
117
- /* XXX This should return an exception for the various error codes
118
- * that can come back in status, but I'm too lazy to do that right
119
- * now. */
120
- if (status)
121
- docobj = Qfalse;
122
- else
123
- docobj = Qtrue;
325
+ status = xmlSAXUserParseFile(rxsp->xsh, rxsp->cbp, StringValuePtr(rxsp->filename));
124
326
  } else if (rxsp->str != Qnil) {
125
327
  str = StringValuePtr(rxsp->str);
126
- docobj = ruby_xml_document_new(cXMLDocument,
127
- xmlSAXParseMemory(rxsp->xsh, str,
128
- strlen(str), 0));
328
+ status = //ruby_xml_document_new(cXMLDocument,
329
+ xmlSAXUserParseMemory(rxsp->xsh, rxsp->cbp,
330
+ str, strlen(str)); //);
129
331
  }
130
- return(docobj);
332
+
333
+ /* XXX This should return an exception for the various error codes
334
+ * that can come back in status, but I'm too lazy to do that right
335
+ * now. */
336
+ if (status)
337
+ return(Qfalse);
338
+ else
339
+ return(Qtrue);
131
340
  }
132
341
 
133
342
 
@@ -168,6 +377,7 @@ ruby_xml_sax_parser_str_set(VALUE self, VALUE str) {
168
377
  void
169
378
  ruby_init_xml_sax_parser(void) {
170
379
  cXMLSaxParser = rb_define_class_under(mXML, "SaxParser", rb_cObject);
380
+ callsym = rb_intern("call");
171
381
 
172
382
  rb_define_singleton_method(cXMLSaxParser, "new", ruby_xml_sax_parser_new, 0);
173
383
 
@@ -178,4 +388,39 @@ ruby_init_xml_sax_parser(void) {
178
388
  rb_define_method(cXMLSaxParser, "parse", ruby_xml_sax_parser_parse, 0);
179
389
  rb_define_method(cXMLSaxParser, "string", ruby_xml_sax_parser_str_get, 0);
180
390
  rb_define_method(cXMLSaxParser, "string=", ruby_xml_sax_parser_str_set, 1);
391
+
392
+ rb_define_method(cXMLSaxParser, "on_internal_subset",
393
+ ruby_xml_sax_parser_on_internal_subset, -1);
394
+ rb_define_method(cXMLSaxParser, "on_is_standalone",
395
+ ruby_xml_sax_parser_on_is_standalone, -1);
396
+ rb_define_method(cXMLSaxParser, "on_has_internal_subset",
397
+ ruby_xml_sax_parser_on_has_internal_subset, -1);
398
+ rb_define_method(cXMLSaxParser, "on_has_external_subset",
399
+ ruby_xml_sax_parser_on_has_external_subset, -1);
400
+ rb_define_method(cXMLSaxParser, "on_start_document",
401
+ ruby_xml_sax_parser_on_start_document, -1);
402
+ rb_define_method(cXMLSaxParser, "on_end_document",
403
+ ruby_xml_sax_parser_on_end_document, -1);
404
+ rb_define_method(cXMLSaxParser, "on_start_element",
405
+ ruby_xml_sax_parser_on_start_element, -1);
406
+ rb_define_method(cXMLSaxParser, "on_end_element",
407
+ ruby_xml_sax_parser_on_end_element, -1);
408
+ rb_define_method(cXMLSaxParser, "on_reference",
409
+ ruby_xml_sax_parser_on_reference, -1);
410
+ rb_define_method(cXMLSaxParser, "on_characters",
411
+ ruby_xml_sax_parser_on_characters, -1);
412
+ rb_define_method(cXMLSaxParser, "on_processing_instruction",
413
+ ruby_xml_sax_parser_on_processing_instruction, -1);
414
+ rb_define_method(cXMLSaxParser, "on_comment",
415
+ ruby_xml_sax_parser_on_comment, -1);
416
+ rb_define_method(cXMLSaxParser, "on_parser_warning",
417
+ ruby_xml_sax_parser_on_parser_warning, -1);
418
+ rb_define_method(cXMLSaxParser, "on_parser_error",
419
+ ruby_xml_sax_parser_on_parser_error, -1);
420
+ rb_define_method(cXMLSaxParser, "on_parser_fatal_error",
421
+ ruby_xml_sax_parser_on_parser_fatal_error, -1);
422
+ rb_define_method(cXMLSaxParser, "on_cdata_block",
423
+ ruby_xml_sax_parser_on_cdata_block, -1);
424
+ rb_define_method(cXMLSaxParser, "on_external_subset",
425
+ ruby_xml_sax_parser_on_external_subset, -1);
181
426
  }