libxml-ruby 4.1.2 → 6.0.0

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 (172) hide show
  1. checksums.yaml +4 -4
  2. data/{HISTORY → CHANGELOG.md} +875 -887
  3. data/LICENSE +20 -20
  4. data/README.md +67 -0
  5. data/Rakefile +77 -98
  6. data/ext/libxml/extconf.rb +39 -20
  7. data/ext/libxml/libxml.c +67 -79
  8. data/ext/libxml/ruby_libxml.h +43 -44
  9. data/ext/libxml/ruby_xml.c +556 -899
  10. data/ext/libxml/ruby_xml.h +9 -10
  11. data/ext/libxml/ruby_xml_attr.c +338 -333
  12. data/ext/libxml/ruby_xml_attr.h +13 -12
  13. data/ext/libxml/ruby_xml_attr_decl.c +19 -12
  14. data/ext/libxml/ruby_xml_attr_decl.h +11 -11
  15. data/ext/libxml/ruby_xml_attributes.c +18 -9
  16. data/ext/libxml/ruby_xml_attributes.h +17 -15
  17. data/ext/libxml/ruby_xml_document.c +1142 -1129
  18. data/ext/libxml/ruby_xml_document.h +12 -11
  19. data/ext/libxml/ruby_xml_dtd.c +287 -248
  20. data/ext/libxml/ruby_xml_dtd.h +10 -9
  21. data/ext/libxml/ruby_xml_encoding.c +250 -250
  22. data/ext/libxml/ruby_xml_encoding.h +20 -18
  23. data/ext/libxml/ruby_xml_error.c +1003 -996
  24. data/ext/libxml/ruby_xml_error.h +14 -14
  25. data/ext/libxml/ruby_xml_html_parser.c +91 -91
  26. data/ext/libxml/ruby_xml_html_parser.h +10 -10
  27. data/ext/libxml/ruby_xml_html_parser_context.c +364 -337
  28. data/ext/libxml/ruby_xml_html_parser_context.h +11 -10
  29. data/ext/libxml/ruby_xml_html_parser_options.c +48 -48
  30. data/ext/libxml/ruby_xml_html_parser_options.h +10 -10
  31. data/ext/libxml/ruby_xml_input_cbg.c +216 -188
  32. data/ext/libxml/ruby_xml_input_cbg.h +20 -20
  33. data/ext/libxml/ruby_xml_io.c +49 -47
  34. data/ext/libxml/ruby_xml_io.h +10 -10
  35. data/ext/libxml/ruby_xml_namespace.c +159 -154
  36. data/ext/libxml/ruby_xml_namespace.h +11 -10
  37. data/ext/libxml/ruby_xml_namespaces.c +313 -293
  38. data/ext/libxml/ruby_xml_namespaces.h +9 -9
  39. data/ext/libxml/ruby_xml_node.c +1433 -1398
  40. data/ext/libxml/ruby_xml_node.h +15 -13
  41. data/ext/libxml/ruby_xml_parser.c +91 -91
  42. data/ext/libxml/ruby_xml_parser.h +10 -10
  43. data/ext/libxml/ruby_xml_parser_context.c +1016 -1001
  44. data/ext/libxml/ruby_xml_parser_context.h +11 -10
  45. data/ext/libxml/ruby_xml_parser_options.c +74 -66
  46. data/ext/libxml/ruby_xml_parser_options.h +10 -10
  47. data/ext/libxml/ruby_xml_reader.c +40 -31
  48. data/ext/libxml/ruby_xml_reader.h +14 -14
  49. data/ext/libxml/ruby_xml_registry.c +31 -0
  50. data/ext/libxml/ruby_xml_registry.h +22 -0
  51. data/ext/libxml/ruby_xml_relaxng.c +21 -5
  52. data/ext/libxml/ruby_xml_relaxng.h +9 -8
  53. data/ext/libxml/ruby_xml_sax2_handler.c +326 -326
  54. data/ext/libxml/ruby_xml_sax2_handler.h +10 -10
  55. data/ext/libxml/ruby_xml_sax_parser.c +108 -116
  56. data/ext/libxml/ruby_xml_sax_parser.h +10 -10
  57. data/ext/libxml/ruby_xml_schema.c +22 -15
  58. data/ext/libxml/ruby_xml_schema.h +26 -25
  59. data/ext/libxml/ruby_xml_schema_attribute.c +7 -7
  60. data/ext/libxml/ruby_xml_schema_attribute.h +37 -37
  61. data/ext/libxml/ruby_xml_schema_element.c +8 -8
  62. data/ext/libxml/ruby_xml_schema_element.h +11 -11
  63. data/ext/libxml/ruby_xml_schema_facet.c +50 -50
  64. data/ext/libxml/ruby_xml_schema_facet.h +9 -9
  65. data/ext/libxml/ruby_xml_schema_type.c +12 -19
  66. data/ext/libxml/ruby_xml_schema_type.h +9 -9
  67. data/ext/libxml/ruby_xml_version.h +9 -9
  68. data/ext/libxml/ruby_xml_writer.c +183 -185
  69. data/ext/libxml/ruby_xml_writer.h +6 -6
  70. data/ext/libxml/ruby_xml_xinclude.c +20 -20
  71. data/ext/libxml/ruby_xml_xinclude.h +11 -11
  72. data/ext/libxml/ruby_xml_xpath.c +195 -195
  73. data/ext/libxml/ruby_xml_xpath.h +15 -15
  74. data/ext/libxml/ruby_xml_xpath_context.c +408 -362
  75. data/ext/libxml/ruby_xml_xpath_context.h +9 -9
  76. data/ext/libxml/ruby_xml_xpath_expression.c +12 -6
  77. data/ext/libxml/ruby_xml_xpath_expression.h +11 -10
  78. data/ext/libxml/ruby_xml_xpath_object.c +69 -54
  79. data/ext/libxml/ruby_xml_xpath_object.h +19 -17
  80. data/ext/vc/libxml_ruby/libxml_ruby.vcxproj +271 -0
  81. data/ext/xcode/libxml-ruby.xcodeproj/project.pbxproj +633 -0
  82. data/ext/xcode/libxml-ruby.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  83. data/ext/xcode/libxml-ruby.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  84. data/ext/xcode/libxml-ruby.xcodeproj/xcshareddata/xcschemes/libxml-ruby.xcscheme +80 -0
  85. data/lib/libxml/attr.rb +122 -122
  86. data/lib/libxml/attr_decl.rb +80 -80
  87. data/lib/libxml/attributes.rb +13 -13
  88. data/lib/libxml/document.rb +165 -194
  89. data/lib/libxml/error.rb +122 -95
  90. data/lib/libxml/html_parser.rb +80 -96
  91. data/lib/libxml/namespace.rb +61 -61
  92. data/lib/libxml/namespaces.rb +37 -37
  93. data/lib/libxml/node.rb +321 -323
  94. data/lib/libxml/parser.rb +94 -100
  95. data/lib/libxml/sax_callbacks.rb +179 -179
  96. data/lib/libxml/sax_parser.rb +40 -40
  97. data/lib/libxml/schema/attribute.rb +27 -19
  98. data/lib/libxml/schema/element.rb +20 -0
  99. data/lib/libxml/schema/type.rb +44 -21
  100. data/lib/libxml/schema.rb +47 -47
  101. data/lib/libxml/tree.rb +28 -28
  102. data/lib/libxml-ruby.rb +30 -30
  103. data/libxml-ruby.gemspec +46 -48
  104. data/test/c14n/result/1-1-without-comments/example-1 +3 -3
  105. data/test/c14n/result/1-1-without-comments/example-2 +10 -10
  106. data/test/c14n/result/1-1-without-comments/example-3 +13 -13
  107. data/test/c14n/result/1-1-without-comments/example-4 +8 -8
  108. data/test/c14n/result/1-1-without-comments/example-5 +2 -2
  109. data/test/c14n/result/with-comments/example-1 +5 -5
  110. data/test/c14n/result/with-comments/example-2 +10 -10
  111. data/test/c14n/result/with-comments/example-3 +13 -13
  112. data/test/c14n/result/with-comments/example-4 +8 -8
  113. data/test/c14n/result/with-comments/example-5 +3 -3
  114. data/test/c14n/result/without-comments/example-1 +3 -3
  115. data/test/c14n/result/without-comments/example-2 +10 -10
  116. data/test/c14n/result/without-comments/example-3 +13 -13
  117. data/test/c14n/result/without-comments/example-4 +8 -8
  118. data/test/c14n/result/without-comments/example-5 +2 -2
  119. data/test/test_attr.rb +179 -180
  120. data/test/test_attr_decl.rb +131 -131
  121. data/test/test_attributes.rb +135 -135
  122. data/test/test_canonicalize.rb +122 -120
  123. data/test/test_document.rb +138 -132
  124. data/test/test_document_write.rb +142 -145
  125. data/test/test_dtd.rb +134 -129
  126. data/test/test_encoding.rb +126 -129
  127. data/test/test_encoding_sax.rb +114 -114
  128. data/test/test_error.rb +197 -194
  129. data/test/test_helper.rb +21 -13
  130. data/test/test_html_parser.rb +166 -162
  131. data/test/test_html_parser_context.rb +22 -22
  132. data/test/test_input_callbacks.rb +36 -0
  133. data/test/test_namespace.rb +58 -60
  134. data/test/test_namespaces.rb +200 -200
  135. data/test/test_node.rb +251 -237
  136. data/test/test_node_cdata.rb +50 -50
  137. data/test/test_node_comment.rb +32 -32
  138. data/test/test_node_copy.rb +40 -40
  139. data/test/test_node_edit.rb +176 -158
  140. data/test/test_node_pi.rb +37 -37
  141. data/test/test_node_text.rb +69 -69
  142. data/test/test_node_write.rb +93 -96
  143. data/test/test_node_xlink.rb +28 -28
  144. data/test/test_parser.rb +297 -324
  145. data/test/test_parser_context.rb +198 -198
  146. data/test/test_properties.rb +38 -38
  147. data/test/test_reader.rb +413 -364
  148. data/test/test_relaxng.rb +59 -53
  149. data/test/test_sax_parser.rb +345 -326
  150. data/test/test_schema.rb +28 -0
  151. data/test/test_traversal.rb +152 -152
  152. data/test/test_writer.rb +469 -468
  153. data/test/test_xinclude.rb +20 -20
  154. data/test/test_xml.rb +164 -267
  155. data/test/test_xpath.rb +244 -244
  156. data/test/test_xpath_context.rb +87 -87
  157. data/test/test_xpath_expression.rb +37 -37
  158. metadata +49 -31
  159. data/README.rdoc +0 -217
  160. data/ext/libxml/extconf.h +0 -3
  161. data/ext/libxml/ruby_xml_cbg.c +0 -85
  162. data/lib/libxml/hpricot.rb +0 -78
  163. data/lib/libxml.rb +0 -5
  164. data/lib/xml/libxml.rb +0 -10
  165. data/lib/xml.rb +0 -14
  166. data/script/benchmark/depixelate +0 -634
  167. data/script/benchmark/hamlet.xml +0 -9055
  168. data/script/benchmark/parsecount +0 -170
  169. data/script/benchmark/sock_entries.xml +0 -507
  170. data/script/benchmark/throughput +0 -41
  171. data/script/test +0 -6
  172. data/test/test_deprecated_require.rb +0 -12
@@ -1,1001 +1,1016 @@
1
- /* Please see the LICENSE file for copyright and distribution information */
2
-
3
- #include "ruby_libxml.h"
4
- #include "ruby_xml_parser_context.h"
5
-
6
- #include <libxml/parserInternals.h>
7
-
8
- VALUE cXMLParserContext;
9
- static ID IO_ATTR;
10
-
11
- /*
12
- * Document-class: LibXML::XML::Parser::Context
13
- *
14
- * The XML::Parser::Context class provides in-depth control over how
15
- * a document is parsed.
16
- */
17
-
18
- static void rxml_parser_context_free(xmlParserCtxtPtr ctxt)
19
- {
20
- xmlFreeParserCtxt(ctxt);
21
- }
22
-
23
- static VALUE rxml_parser_context_wrap(xmlParserCtxtPtr ctxt)
24
- {
25
- return Data_Wrap_Struct(cXMLParserContext, NULL, rxml_parser_context_free, ctxt);
26
- }
27
-
28
-
29
- static VALUE rxml_parser_context_alloc(VALUE klass)
30
- {
31
- xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
32
- return Data_Wrap_Struct(klass, NULL, rxml_parser_context_free, ctxt);
33
- }
34
-
35
- /* call-seq:
36
- * XML::Parser::Context.document(document) -> XML::Parser::Context
37
- *
38
- * Creates a new parser context based on the specified document.
39
- *
40
- * Parameters:
41
- *
42
- * document - An XML::Document instance.
43
- */
44
- static VALUE rxml_parser_context_document(VALUE klass, VALUE document)
45
- {
46
- xmlParserCtxtPtr ctxt;
47
- xmlDocPtr xdoc;
48
- xmlChar *buffer;
49
- int length;
50
-
51
- if (rb_obj_is_kind_of(document, cXMLDocument) == Qfalse)
52
- rb_raise(rb_eTypeError, "Must pass an LibXML::XML::Document object");
53
-
54
- Data_Get_Struct(document, xmlDoc, xdoc);
55
- xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, (const char*)xdoc->encoding, 0);
56
-
57
- ctxt = xmlCreateDocParserCtxt(buffer);
58
-
59
- if (!ctxt)
60
- rxml_raise(&xmlLastError);
61
-
62
- /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
63
- xmlCtxtUseOptionsInternal (called below) initialize slightly different
64
- context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
65
- sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
66
- xmlCtxtUseOptions(ctxt, rxml_libxml_default_options());
67
-
68
- return rxml_parser_context_wrap(ctxt);
69
- }
70
-
71
- /* call-seq:
72
- * XML::Parser::Context.file(file) -> XML::Parser::Context
73
- *
74
- * Creates a new parser context based on the specified file or uri.
75
- *
76
- * Parameters:
77
- *
78
- * file - A filename or uri.
79
- */
80
- static VALUE rxml_parser_context_file(VALUE klass, VALUE file)
81
- {
82
- xmlParserCtxtPtr ctxt = xmlCreateURLParserCtxt(StringValuePtr(file), 0);
83
-
84
- if (!ctxt)
85
- rxml_raise(&xmlLastError);
86
-
87
- /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
88
- xmlCtxtUseOptionsInternal (called below) initialize slightly different
89
- context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
90
- sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
91
- xmlCtxtUseOptions(ctxt, rxml_libxml_default_options());
92
-
93
- return rxml_parser_context_wrap(ctxt);
94
- }
95
-
96
- /* call-seq:
97
- * XML::Parser::Context.string(string) -> XML::Parser::Context
98
- *
99
- * Creates a new parser context based on the specified string.
100
- *
101
- * Parameters:
102
- *
103
- * string - A string that contains the data to parse.
104
- */
105
- static VALUE rxml_parser_context_string(VALUE klass, VALUE string)
106
- {
107
- xmlParserCtxtPtr ctxt;
108
- Check_Type(string, T_STRING);
109
-
110
- if (RSTRING_LEN(string) == 0)
111
- rb_raise(rb_eArgError, "Must specify a string with one or more characters");
112
-
113
- ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(string), (int)RSTRING_LEN(string));
114
-
115
- if (!ctxt)
116
- rxml_raise(&xmlLastError);
117
-
118
- /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
119
- xmlCtxtUseOptionsInternal (called below) initialize slightly different
120
- context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
121
- sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
122
- xmlCtxtUseOptions(ctxt, rxml_libxml_default_options());
123
-
124
- return rxml_parser_context_wrap(ctxt);
125
- }
126
-
127
- /* call-seq:
128
- * XML::Parser::Context.io(io) -> XML::Parser::Context
129
- *
130
- * Creates a new parser context based on the specified io object.
131
- *
132
- * Parameters:
133
- *
134
- * io - A ruby IO object.
135
- */
136
- static VALUE rxml_parser_context_io(VALUE klass, VALUE io)
137
- {
138
- VALUE result;
139
- xmlParserCtxtPtr ctxt;
140
- xmlParserInputBufferPtr input;
141
- xmlParserInputPtr stream;
142
-
143
- if (NIL_P(io))
144
- rb_raise(rb_eTypeError, "Must pass in an IO object");
145
-
146
- input = xmlParserInputBufferCreateIO((xmlInputReadCallback) rxml_read_callback, NULL,
147
- (void*)io, XML_CHAR_ENCODING_NONE);
148
-
149
- ctxt = xmlNewParserCtxt();
150
-
151
- if (!ctxt)
152
- {
153
- xmlFreeParserInputBuffer(input);
154
- rxml_raise(&xmlLastError);
155
- }
156
-
157
- /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
158
- xmlCtxtUseOptionsInternal (called below) initialize slightly different
159
- context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
160
- sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
161
- xmlCtxtUseOptions(ctxt, rxml_libxml_default_options());
162
-
163
- stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
164
-
165
- if (!stream)
166
- {
167
- xmlFreeParserInputBuffer(input);
168
- xmlFreeParserCtxt(ctxt);
169
- rxml_raise(&xmlLastError);
170
- }
171
- inputPush(ctxt, stream);
172
- result = rxml_parser_context_wrap(ctxt);
173
-
174
- /* Attach io object to parser so it won't get freed.*/
175
- rb_ivar_set(result, IO_ATTR, io);
176
-
177
- return result;
178
- }
179
-
180
- /*
181
- * call-seq:
182
- * context.base_uri -> "http:://libxml.org"
183
- *
184
- * Obtain the base url for this parser context.
185
- */
186
- static VALUE rxml_parser_context_base_uri_get(VALUE self)
187
- {
188
- xmlParserCtxtPtr ctxt;
189
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
190
-
191
- if (ctxt->input && ctxt->input->filename)
192
- return rxml_new_cstr((const xmlChar*)ctxt->input->filename, ctxt->encoding);
193
- else
194
- return Qnil;
195
- }
196
-
197
- /*
198
- * call-seq:
199
- * context.base_uri = "http:://libxml.org"
200
- *
201
- * Sets the base url for this parser context.
202
- */
203
- static VALUE rxml_parser_context_base_uri_set(VALUE self, VALUE url)
204
- {
205
- xmlParserCtxtPtr ctxt;
206
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
207
-
208
- Check_Type(url, T_STRING);
209
-
210
- if (ctxt->input && !ctxt->input->filename)
211
- {
212
- const char* xurl = StringValuePtr(url);
213
- ctxt->input->filename = (const char*)xmlStrdup((const xmlChar*)xurl);
214
- }
215
- return self;
216
- }
217
-
218
- /*
219
- * call-seq:
220
- * context.close -> nil
221
- *
222
- * Closes the underlying input streams. This is useful when parsing a large amount of
223
- * files and you want to close the files without relying on Ruby's garbage collector
224
- * to run.
225
- */
226
- static VALUE rxml_parser_context_close(VALUE self)
227
- {
228
- xmlParserCtxtPtr ctxt;
229
- xmlParserInputPtr xinput;
230
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
231
-
232
- while ((xinput = inputPop(ctxt)) != NULL)
233
- {
234
- xmlFreeInputStream(xinput);
235
- }
236
- return Qnil;
237
- }
238
-
239
- /*
240
- * call-seq:
241
- * context.data_directory -> "dir"
242
- *
243
- * Obtain the data directory associated with this context.
244
- */
245
- static VALUE rxml_parser_context_data_directory_get(VALUE self)
246
- {
247
- xmlParserCtxtPtr ctxt;
248
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
249
-
250
- if (ctxt->directory == NULL)
251
- return (Qnil);
252
- else
253
- return (rxml_new_cstr((const xmlChar*)ctxt->directory, ctxt->encoding));
254
- }
255
-
256
- /*
257
- * call-seq:
258
- * context.depth -> num
259
- *
260
- * Obtain the depth of this context.
261
- */
262
- static VALUE rxml_parser_context_depth_get(VALUE self)
263
- {
264
- xmlParserCtxtPtr ctxt;
265
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
266
-
267
- return (INT2NUM(ctxt->depth));
268
- }
269
-
270
- /*
271
- * call-seq:
272
- * context.disable_cdata? -> (true|false)
273
- *
274
- * Determine whether CDATA nodes will be created in this context.
275
- */
276
- static VALUE rxml_parser_context_disable_cdata_q(VALUE self)
277
- {
278
- xmlParserCtxtPtr ctxt;
279
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
280
-
281
- /* LibXML controls this internally with the default SAX handler. */
282
- if (ctxt->sax && ctxt->sax->cdataBlock)
283
- return (Qfalse);
284
- else
285
- return (Qtrue);
286
- }
287
-
288
- /*
289
- * call-seq:
290
- * context.disable_cdata = (true|false)
291
- *
292
- * Control whether CDATA nodes will be created in this context.
293
- */
294
- static VALUE rxml_parser_context_disable_cdata_set(VALUE self, VALUE value)
295
- {
296
- xmlParserCtxtPtr ctxt;
297
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
298
-
299
- if (ctxt->sax == NULL)
300
- rb_raise(rb_eRuntimeError, "Sax handler is not yet set");
301
-
302
- /* LibXML controls this internally with the default SAX handler. */
303
- if (value)
304
- ctxt->sax->cdataBlock = NULL;
305
- else
306
- ctxt->sax->cdataBlock = xmlDefaultSAXHandler.cdataBlock;
307
-
308
- return value;
309
- }
310
-
311
- /*
312
- * call-seq:
313
- * context.disable_sax? -> (true|false)
314
- *
315
- * Determine whether SAX-based processing is disabled
316
- * in this context.
317
- */
318
- static VALUE rxml_parser_context_disable_sax_q(VALUE self)
319
- {
320
- xmlParserCtxtPtr ctxt;
321
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
322
-
323
- if (ctxt->disableSAX)
324
- return (Qtrue);
325
- else
326
- return (Qfalse);
327
- }
328
-
329
- /*
330
- * call-seq:
331
- * context.docbook? -> (true|false)
332
- *
333
- * Determine whether this is a docbook context.
334
- */
335
- static VALUE rxml_parser_context_docbook_q(VALUE self)
336
- {
337
- xmlParserCtxtPtr ctxt;
338
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
339
-
340
- if (ctxt->html == 2) // TODO check this
341
- return (Qtrue);
342
- else
343
- return (Qfalse);
344
- }
345
-
346
- /*
347
- * call-seq:
348
- * context.encoding -> XML::Encoding::UTF_8
349
- *
350
- * Obtain the character encoding identifier used in
351
- * this context.
352
- */
353
- static VALUE rxml_parser_context_encoding_get(VALUE self)
354
- {
355
- xmlParserCtxtPtr ctxt;
356
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
357
- return INT2NUM(xmlParseCharEncoding((const char*)ctxt->encoding));
358
- }
359
-
360
- /*
361
- * call-seq:
362
- * context.encoding = XML::Encoding::UTF_8
363
- *
364
- * Sets the character encoding for this context.
365
- */
366
- static VALUE rxml_parser_context_encoding_set(VALUE self, VALUE encoding)
367
- {
368
- xmlParserCtxtPtr ctxt;
369
- int result;
370
- const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
371
- xmlCharEncodingHandlerPtr hdlr = xmlFindCharEncodingHandler(xencoding);
372
-
373
- if (!hdlr)
374
- rb_raise(rb_eArgError, "Unknown encoding: %i", NUM2INT(encoding));
375
-
376
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
377
- result = xmlSwitchToEncoding(ctxt, hdlr);
378
-
379
- if (result != 0)
380
- rxml_raise(&xmlLastError);
381
-
382
- if (ctxt->encoding != NULL)
383
- xmlFree((xmlChar *) ctxt->encoding);
384
-
385
- ctxt->encoding = xmlStrdup((const xmlChar *) xencoding);
386
- return self;
387
- }
388
-
389
- /*
390
- * call-seq:
391
- * context.errno -> num
392
- *
393
- * Obtain the last-error number in this context.
394
- */
395
- static VALUE rxml_parser_context_errno_get(VALUE self)
396
- {
397
- xmlParserCtxtPtr ctxt;
398
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
399
-
400
- return (INT2NUM(ctxt->errNo));
401
- }
402
-
403
- /*
404
- * call-seq:
405
- * context.html? -> (true|false)
406
- *
407
- * Determine whether this is an html context.
408
- */
409
- static VALUE rxml_parser_context_html_q(VALUE self)
410
- {
411
- xmlParserCtxtPtr ctxt;
412
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
413
-
414
- if (ctxt->html == 1)
415
- return (Qtrue);
416
- else
417
- return (Qfalse);
418
- }
419
-
420
- /*
421
- * call-seq:
422
- * context.max_num_streams -> num
423
- *
424
- * Obtain the limit on the number of IO streams opened in
425
- * this context.
426
- */
427
- static VALUE rxml_parser_context_io_max_num_streams_get(VALUE self)
428
- {
429
- // TODO alias to max_streams and dep this?
430
- xmlParserCtxtPtr ctxt;
431
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
432
-
433
- return (INT2NUM(ctxt->inputMax));
434
- }
435
-
436
- /*
437
- * call-seq:
438
- * context.num_streams -> "dir"
439
- *
440
- * Obtain the actual number of IO streams in this
441
- * context.
442
- */
443
- static VALUE rxml_parser_context_io_num_streams_get(VALUE self)
444
- {
445
- xmlParserCtxtPtr ctxt;
446
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
447
-
448
- return (INT2NUM(ctxt->inputNr));
449
- }
450
-
451
- /*
452
- * call-seq:
453
- * context.keep_blanks? -> (true|false)
454
- *
455
- * Determine whether parsers in this context retain
456
- * whitespace.
457
- */
458
- static VALUE rxml_parser_context_keep_blanks_q(VALUE self)
459
- {
460
- xmlParserCtxtPtr ctxt;
461
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
462
-
463
- if (ctxt->keepBlanks)
464
- return (Qtrue);
465
- else
466
- return (Qfalse);
467
- }
468
-
469
- /*
470
- * call-seq:
471
- * context.name_depth -> num
472
- *
473
- * Obtain the name depth for this context.
474
- */
475
- static VALUE rxml_parser_context_name_depth_get(VALUE self)
476
- {
477
- xmlParserCtxtPtr ctxt;
478
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
479
-
480
- return (INT2NUM(ctxt->nameNr));
481
- }
482
-
483
- /*
484
- * call-seq:
485
- * context.name_depth_max -> num
486
- *
487
- * Obtain the maximum name depth for this context.
488
- */
489
- static VALUE rxml_parser_context_name_depth_max_get(VALUE self)
490
- {
491
- xmlParserCtxtPtr ctxt;
492
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
493
-
494
- return (INT2NUM(ctxt->nameMax));
495
- }
496
-
497
- /*
498
- * call-seq:
499
- * context.name_node -> "name"
500
- *
501
- * Obtain the name node for this context.
502
- */
503
- static VALUE rxml_parser_context_name_node_get(VALUE self)
504
- {
505
- xmlParserCtxtPtr ctxt;
506
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
507
-
508
- if (ctxt->name == NULL)
509
- return (Qnil);
510
- else
511
- return (rxml_new_cstr( ctxt->name, ctxt->encoding));
512
- }
513
-
514
- /*
515
- * call-seq:
516
- * context.name_tab -> ["name", ..., "name"]
517
- *
518
- * Obtain the name table for this context.
519
- */
520
- static VALUE rxml_parser_context_name_tab_get(VALUE self)
521
- {
522
- int i;
523
- xmlParserCtxtPtr ctxt;
524
- VALUE tab_ary;
525
-
526
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
527
-
528
- if (ctxt->nameTab == NULL)
529
- return (Qnil);
530
-
531
- tab_ary = rb_ary_new();
532
-
533
- for (i = (ctxt->nameNr - 1); i >= 0; i--)
534
- {
535
- if (ctxt->nameTab[i] == NULL)
536
- continue;
537
- else
538
- rb_ary_push(tab_ary, rxml_new_cstr( ctxt->nameTab[i], ctxt->encoding));
539
- }
540
-
541
- return (tab_ary);
542
- }
543
-
544
- /*
545
- * call-seq:
546
- * context.node_depth -> num
547
- *
548
- * Obtain the node depth for this context.
549
- */
550
- static VALUE rxml_parser_context_node_depth_get(VALUE self)
551
- {
552
- xmlParserCtxtPtr ctxt;
553
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
554
-
555
- return (INT2NUM(ctxt->nodeNr));
556
- }
557
-
558
- /*
559
- * call-seq:
560
- * context.node -> node
561
- *
562
- * Obtain the root node of this context.
563
- */
564
- static VALUE rxml_parser_context_node_get(VALUE self)
565
- {
566
- xmlParserCtxtPtr ctxt;
567
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
568
-
569
- if (ctxt->node == NULL)
570
- return (Qnil);
571
- else
572
- return (rxml_node_wrap(ctxt->node));
573
- }
574
-
575
- /*
576
- * call-seq:
577
- * context.node_depth_max -> num
578
- *
579
- * Obtain the maximum node depth for this context.
580
- */
581
- static VALUE rxml_parser_context_node_depth_max_get(VALUE self)
582
- {
583
- xmlParserCtxtPtr ctxt;
584
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
585
-
586
- return (INT2NUM(ctxt->nodeMax));
587
- }
588
-
589
- /*
590
- * call-seq:
591
- * context.num_chars -> num
592
- *
593
- * Obtain the number of characters in this context.
594
- */
595
- static VALUE rxml_parser_context_num_chars_get(VALUE self)
596
- {
597
- xmlParserCtxtPtr ctxt;
598
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
599
-
600
- return (LONG2NUM(ctxt->nbChars));
601
- }
602
-
603
-
604
- /*
605
- * call-seq:
606
- * context.options > XML::Parser::Options::NOENT
607
- *
608
- * Returns the parser options for this context. Multiple
609
- * options can be combined by using Bitwise OR (|).
610
- */
611
- static VALUE rxml_parser_context_options_get(VALUE self)
612
- {
613
- xmlParserCtxtPtr ctxt;
614
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
615
-
616
- return INT2NUM(ctxt->options);
617
- }
618
-
619
- /*
620
- * call-seq:
621
- * context.options = XML::Parser::Options::NOENT |
622
- XML::Parser::Options::NOCDATA
623
- *
624
- * Provides control over the execution of a parser. Valid values
625
- * are the constants defined on XML::Parser::Options. Multiple
626
- * options can be combined by using Bitwise OR (|).
627
- */
628
- static VALUE rxml_parser_context_options_set(VALUE self, VALUE options)
629
- {
630
- xmlParserCtxtPtr ctxt;
631
- Check_Type(options, T_FIXNUM);
632
-
633
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
634
- xmlCtxtUseOptions(ctxt, NUM2INT(options));
635
-
636
- return self;
637
- }
638
-
639
- /*
640
- * call-seq:
641
- * context.recovery? -> (true|false)
642
- *
643
- * Determine whether recovery mode is enabled in this
644
- * context.
645
- */
646
- static VALUE rxml_parser_context_recovery_q(VALUE self)
647
- {
648
- xmlParserCtxtPtr ctxt;
649
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
650
-
651
- if (ctxt->recovery)
652
- return (Qtrue);
653
- else
654
- return (Qfalse);
655
- }
656
-
657
- /*
658
- * call-seq:
659
- * context.recovery = true|false
660
- *
661
- * Control whether recovery mode is enabled in this
662
- * context.
663
- */
664
- static VALUE rxml_parser_context_recovery_set(VALUE self, VALUE value)
665
- {
666
- xmlParserCtxtPtr ctxt;
667
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
668
-
669
- if (value == Qfalse)
670
- {
671
- ctxt->recovery = 0;
672
- return (Qfalse);
673
- }
674
- else
675
- {
676
- ctxt->recovery = 1;
677
- return (Qtrue);
678
- }
679
- }
680
-
681
- /*
682
- * call-seq:
683
- * context.replace_entities? -> (true|false)
684
- *
685
- * Determine whether external entity replacement is enabled in this
686
- * context.
687
- */
688
- static VALUE rxml_parser_context_replace_entities_q(VALUE self)
689
- {
690
- xmlParserCtxtPtr ctxt;
691
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
692
-
693
- if (ctxt->replaceEntities)
694
- return (Qtrue);
695
- else
696
- return (Qfalse);
697
- }
698
-
699
- /*
700
- * call-seq:
701
- * context.replace_entities = true|false
702
- *
703
- * Control whether external entity replacement is enabled in this
704
- * context.
705
- */
706
- static VALUE rxml_parser_context_replace_entities_set(VALUE self, VALUE value)
707
- {
708
- xmlParserCtxtPtr ctxt;
709
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
710
-
711
- if (value == Qfalse)
712
- {
713
- ctxt->replaceEntities = 0;
714
- return (Qfalse);
715
- }
716
- else
717
- {
718
- ctxt->replaceEntities = 1;
719
- return (Qtrue);
720
- }
721
- }
722
-
723
- /*
724
- * call-seq:
725
- * context.space_depth -> num
726
- *
727
- * Obtain the space depth for this context.
728
- */
729
- static VALUE rxml_parser_context_space_depth_get(VALUE self)
730
- {
731
- xmlParserCtxtPtr ctxt;
732
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
733
-
734
- return (INT2NUM(ctxt->spaceNr));
735
- }
736
-
737
- /*
738
- * call-seq:
739
- * context.space_depth -> num
740
- *
741
- * Obtain the maximum space depth for this context.
742
- */
743
- static VALUE rxml_parser_context_space_depth_max_get(VALUE self)
744
- {
745
- xmlParserCtxtPtr ctxt;
746
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
747
-
748
- return (INT2NUM(ctxt->spaceMax));
749
- }
750
-
751
- /*
752
- * call-seq:
753
- * context.subset_external? -> (true|false)
754
- *
755
- * Determine whether this context is a subset of an
756
- * external context.
757
- */
758
- static VALUE rxml_parser_context_subset_external_q(VALUE self)
759
- {
760
- xmlParserCtxtPtr ctxt;
761
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
762
-
763
- if (ctxt->inSubset == 2)
764
- return (Qtrue);
765
- else
766
- return (Qfalse);
767
- }
768
-
769
- /*
770
- * call-seq:
771
- * context.subset_internal? -> (true|false)
772
- *
773
- * Determine whether this context is a subset of an
774
- * internal context.
775
- */
776
- static VALUE rxml_parser_context_subset_internal_q(VALUE self)
777
- {
778
- xmlParserCtxtPtr ctxt;
779
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
780
-
781
- if (ctxt->inSubset == 1)
782
- return (Qtrue);
783
- else
784
- return (Qfalse);
785
- }
786
-
787
- /*
788
- * call-seq:
789
- * context.subset_internal_name -> "name"
790
- *
791
- * Obtain this context's subset name (valid only if
792
- * either of subset_external? or subset_internal?
793
- * is true).
794
- */
795
- static VALUE rxml_parser_context_subset_name_get(VALUE self)
796
- {
797
- xmlParserCtxtPtr ctxt;
798
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
799
-
800
- if (ctxt->intSubName == NULL)
801
- return (Qnil);
802
- else
803
- return (rxml_new_cstr(ctxt->intSubName, ctxt->encoding));
804
- }
805
-
806
- /*
807
- * call-seq:
808
- * context.subset_external_uri -> "uri"
809
- *
810
- * Obtain this context's external subset URI. (valid only if
811
- * either of subset_external? or subset_internal?
812
- * is true).
813
- */
814
- static VALUE rxml_parser_context_subset_external_uri_get(VALUE self)
815
- {
816
- xmlParserCtxtPtr ctxt;
817
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
818
-
819
- if (ctxt->extSubURI == NULL)
820
- return (Qnil);
821
- else
822
- return (rxml_new_cstr( ctxt->extSubURI, ctxt->encoding));
823
- }
824
-
825
- /*
826
- * call-seq:
827
- * context.subset_external_system_id -> "system_id"
828
- *
829
- * Obtain this context's external subset system identifier.
830
- * (valid only if either of subset_external? or subset_internal?
831
- * is true).
832
- */
833
- static VALUE rxml_parser_context_subset_external_system_id_get(VALUE self)
834
- {
835
- xmlParserCtxtPtr ctxt;
836
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
837
-
838
- if (ctxt->extSubSystem == NULL)
839
- return (Qnil);
840
- else
841
- return (rxml_new_cstr( ctxt->extSubSystem, ctxt->encoding));
842
- }
843
-
844
- /*
845
- * call-seq:
846
- * context.standalone? -> (true|false)
847
- *
848
- * Determine whether this is a standalone context.
849
- */
850
- static VALUE rxml_parser_context_standalone_q(VALUE self)
851
- {
852
- xmlParserCtxtPtr ctxt;
853
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
854
-
855
- if (ctxt->standalone)
856
- return (Qtrue);
857
- else
858
- return (Qfalse);
859
- }
860
-
861
- /*
862
- * call-seq:
863
- * context.stats? -> (true|false)
864
- *
865
- * Determine whether this context maintains statistics.
866
- */
867
- static VALUE rxml_parser_context_stats_q(VALUE self)
868
- {
869
- xmlParserCtxtPtr ctxt;
870
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
871
-
872
- if (ctxt->record_info)
873
- return (Qtrue);
874
- else
875
- return (Qfalse);
876
- }
877
-
878
- /*
879
- * call-seq:
880
- * context.valid? -> (true|false)
881
- *
882
- * Determine whether this context is valid.
883
- */
884
- static VALUE rxml_parser_context_valid_q(VALUE self)
885
- {
886
- xmlParserCtxtPtr ctxt;
887
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
888
-
889
- if (ctxt->valid)
890
- return (Qtrue);
891
- else
892
- return (Qfalse);
893
- }
894
-
895
- /*
896
- * call-seq:
897
- * context.validate? -> (true|false)
898
- *
899
- * Determine whether validation is enabled in this context.
900
- */
901
- static VALUE rxml_parser_context_validate_q(VALUE self)
902
- {
903
- xmlParserCtxtPtr ctxt;
904
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
905
-
906
- if (ctxt->validate)
907
- return (Qtrue);
908
- else
909
- return (Qfalse);
910
- }
911
-
912
- /*
913
- * call-seq:
914
- * context.version -> "version"
915
- *
916
- * Obtain this context's version identifier.
917
- */
918
- static VALUE rxml_parser_context_version_get(VALUE self)
919
- {
920
- xmlParserCtxtPtr ctxt;
921
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
922
-
923
- if (ctxt->version == NULL)
924
- return (Qnil);
925
- else
926
- return (rxml_new_cstr( ctxt->version, ctxt->encoding));
927
- }
928
-
929
- /*
930
- * call-seq:
931
- * context.well_formed? -> (true|false)
932
- *
933
- * Determine whether this context contains well-formed XML.
934
- */
935
- static VALUE rxml_parser_context_well_formed_q(VALUE self)
936
- {
937
- xmlParserCtxtPtr ctxt;
938
- Data_Get_Struct(self, xmlParserCtxt, ctxt);
939
-
940
- if (ctxt->wellFormed)
941
- return (Qtrue);
942
- else
943
- return (Qfalse);
944
- }
945
-
946
- void rxml_init_parser_context(void)
947
- {
948
- IO_ATTR = ID2SYM(rb_intern("@io"));
949
-
950
- cXMLParserContext = rb_define_class_under(cXMLParser, "Context", rb_cObject);
951
- rb_define_alloc_func(cXMLParserContext, rxml_parser_context_alloc);
952
-
953
- rb_define_singleton_method(cXMLParserContext, "document", rxml_parser_context_document, 1);
954
- rb_define_singleton_method(cXMLParserContext, "file", rxml_parser_context_file, 1);
955
- rb_define_singleton_method(cXMLParserContext, "io", rxml_parser_context_io, 1);
956
- rb_define_singleton_method(cXMLParserContext, "string", rxml_parser_context_string, 1);
957
-
958
- rb_define_method(cXMLParserContext, "base_uri", rxml_parser_context_base_uri_get, 0);
959
- rb_define_method(cXMLParserContext, "base_uri=", rxml_parser_context_base_uri_set, 1);
960
- rb_define_method(cXMLParserContext, "close", rxml_parser_context_close, 0);
961
- rb_define_method(cXMLParserContext, "data_directory", rxml_parser_context_data_directory_get, 0);
962
- rb_define_method(cXMLParserContext, "depth", rxml_parser_context_depth_get, 0);
963
- rb_define_method(cXMLParserContext, "disable_cdata?", rxml_parser_context_disable_cdata_q, 0);
964
- rb_define_method(cXMLParserContext, "disable_cdata=", rxml_parser_context_disable_cdata_set, 1);
965
- rb_define_method(cXMLParserContext, "disable_sax?", rxml_parser_context_disable_sax_q, 0);
966
- rb_define_method(cXMLParserContext, "docbook?", rxml_parser_context_docbook_q, 0);
967
- rb_define_method(cXMLParserContext, "encoding", rxml_parser_context_encoding_get, 0);
968
- rb_define_method(cXMLParserContext, "encoding=", rxml_parser_context_encoding_set, 1);
969
- rb_define_method(cXMLParserContext, "errno", rxml_parser_context_errno_get, 0);
970
- rb_define_method(cXMLParserContext, "html?", rxml_parser_context_html_q, 0);
971
- rb_define_method(cXMLParserContext, "io_max_num_streams", rxml_parser_context_io_max_num_streams_get, 0);
972
- rb_define_method(cXMLParserContext, "io_num_streams", rxml_parser_context_io_num_streams_get, 0);
973
- rb_define_method(cXMLParserContext, "keep_blanks?", rxml_parser_context_keep_blanks_q, 0);
974
- rb_define_method(cXMLParserContext, "name_node", rxml_parser_context_name_node_get, 0);
975
- rb_define_method(cXMLParserContext, "name_depth", rxml_parser_context_name_depth_get, 0);
976
- rb_define_method(cXMLParserContext, "name_depth_max", rxml_parser_context_name_depth_max_get, 0);
977
- rb_define_method(cXMLParserContext, "name_tab", rxml_parser_context_name_tab_get, 0);
978
- rb_define_method(cXMLParserContext, "node", rxml_parser_context_node_get, 0);
979
- rb_define_method(cXMLParserContext, "node_depth", rxml_parser_context_node_depth_get, 0);
980
- rb_define_method(cXMLParserContext, "node_depth_max", rxml_parser_context_node_depth_max_get, 0);
981
- rb_define_method(cXMLParserContext, "num_chars", rxml_parser_context_num_chars_get, 0);
982
- rb_define_method(cXMLParserContext, "options", rxml_parser_context_options_get, 0);
983
- rb_define_method(cXMLParserContext, "options=", rxml_parser_context_options_set, 1);
984
- rb_define_method(cXMLParserContext, "recovery?", rxml_parser_context_recovery_q, 0);
985
- rb_define_method(cXMLParserContext, "recovery=", rxml_parser_context_recovery_set, 1);
986
- rb_define_method(cXMLParserContext, "replace_entities?", rxml_parser_context_replace_entities_q, 0);
987
- rb_define_method(cXMLParserContext, "replace_entities=", rxml_parser_context_replace_entities_set, 1);
988
- rb_define_method(cXMLParserContext, "space_depth", rxml_parser_context_space_depth_get, 0);
989
- rb_define_method(cXMLParserContext, "space_depth_max", rxml_parser_context_space_depth_max_get, 0);
990
- rb_define_method(cXMLParserContext, "subset_external?", rxml_parser_context_subset_external_q, 0);
991
- rb_define_method(cXMLParserContext, "subset_external_system_id", rxml_parser_context_subset_external_system_id_get, 0);
992
- rb_define_method(cXMLParserContext, "subset_external_uri", rxml_parser_context_subset_external_uri_get, 0);
993
- rb_define_method(cXMLParserContext, "subset_internal?", rxml_parser_context_subset_internal_q, 0);
994
- rb_define_method(cXMLParserContext, "subset_internal_name", rxml_parser_context_subset_name_get, 0);
995
- rb_define_method(cXMLParserContext, "stats?", rxml_parser_context_stats_q, 0);
996
- rb_define_method(cXMLParserContext, "standalone?", rxml_parser_context_standalone_q, 0);
997
- rb_define_method(cXMLParserContext, "valid", rxml_parser_context_valid_q, 0);
998
- rb_define_method(cXMLParserContext, "validate?", rxml_parser_context_validate_q, 0);
999
- rb_define_method(cXMLParserContext, "version", rxml_parser_context_version_get, 0);
1000
- rb_define_method(cXMLParserContext, "well_formed?", rxml_parser_context_well_formed_q, 0);
1001
- }
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #include "ruby_libxml.h"
4
+ #include "ruby_xml_parser_context.h"
5
+
6
+ #include <libxml/parserInternals.h>
7
+
8
+ VALUE cXMLParserContext;
9
+ static ID IO_ATTR;
10
+
11
+ /*
12
+ * Document-class: LibXML::XML::Parser::Context
13
+ *
14
+ * The XML::Parser::Context class provides in-depth control over how
15
+ * a document is parsed.
16
+ */
17
+
18
+ static void rxml_parser_context_free(void* data)
19
+ {
20
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)data;
21
+ xmlFreeParserCtxt(ctxt);
22
+ }
23
+
24
+ const rb_data_type_t rxml_parser_context_type = {
25
+ "LibXML::XML::Parser::Context",
26
+ {NULL, rxml_parser_context_free, NULL},
27
+ NULL, NULL, 0
28
+ };
29
+
30
+ static VALUE rxml_parser_context_wrap(xmlParserCtxtPtr ctxt)
31
+ {
32
+ return TypedData_Wrap_Struct(cXMLParserContext, &rxml_parser_context_type, ctxt);
33
+ }
34
+
35
+
36
+ static VALUE rxml_parser_context_alloc(VALUE klass)
37
+ {
38
+ xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
39
+ return TypedData_Wrap_Struct(klass, &rxml_parser_context_type, ctxt);
40
+ }
41
+
42
+ /* call-seq:
43
+ * XML::Parser::Context.document(document) -> XML::Parser::Context
44
+ *
45
+ * Creates a new parser context based on the specified document.
46
+ *
47
+ * Parameters:
48
+ *
49
+ * document - An XML::Document instance
50
+ * options - A or'ed together list of LibXML::XML::Parser::Options values
51
+ */
52
+ static VALUE rxml_parser_context_document(int argc, VALUE* argv, VALUE klass)
53
+ {
54
+ VALUE document, options;
55
+ rb_scan_args(argc, argv, "11", &document, &options);
56
+
57
+ if (rb_obj_is_kind_of(document, cXMLDocument) == Qfalse)
58
+ rb_raise(rb_eTypeError, "Must pass an LibXML::XML::Document object");
59
+
60
+ xmlDocPtr xdoc;
61
+ xmlChar *buffer;
62
+ int length;
63
+ TypedData_Get_Struct(document, xmlDoc, &rxml_document_data_type, xdoc);
64
+ xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, (const char*)xdoc->encoding, 0);
65
+
66
+ xmlParserCtxtPtr ctxt = xmlCreateDocParserCtxt(buffer);
67
+
68
+ if (!ctxt)
69
+ rxml_raise(xmlGetLastError());
70
+
71
+ /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
72
+ xmlCtxtUseOptionsInternal (called below) initialize slightly different
73
+ context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
74
+ sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
75
+ xmlCtxtUseOptions(ctxt, options == Qnil ? 0 : NUM2INT(options));
76
+
77
+ return rxml_parser_context_wrap(ctxt);
78
+ }
79
+
80
+ /* call-seq:
81
+ * XML::Parser::Context.file(file) -> XML::Parser::Context
82
+ *
83
+ * Creates a new parser context based on the specified file or uri.
84
+ *
85
+ * Parameters:
86
+ *
87
+ * file - A filename or uri
88
+ * options - A or'ed together list of LibXML::XML::Parser::Options values
89
+ */
90
+ static VALUE rxml_parser_context_file(int argc, VALUE* argv, VALUE klass)
91
+ {
92
+ VALUE file, options;
93
+ rb_scan_args(argc, argv, "11", &file, &options);
94
+
95
+ xmlParserCtxtPtr ctxt = xmlCreateURLParserCtxt(StringValuePtr(file), 0);
96
+
97
+ if (!ctxt)
98
+ rxml_raise(xmlGetLastError());
99
+
100
+ /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
101
+ xmlCtxtUseOptionsInternal (called below) initialize slightly different
102
+ context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
103
+ sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
104
+ xmlCtxtUseOptions(ctxt, options == Qnil ? 0 : NUM2INT(options));
105
+
106
+ return rxml_parser_context_wrap(ctxt);
107
+ }
108
+
109
+ /* call-seq:
110
+ * XML::Parser::Context.string(string) -> XML::Parser::Context
111
+ *
112
+ * Creates a new parser context based on the specified string.
113
+ *
114
+ * Parameters:
115
+ *
116
+ * string - A string that contains the data to parse
117
+ * options - A or'ed together list of LibXML::XML::Parser::Options values
118
+ */
119
+ static VALUE rxml_parser_context_string(int argc, VALUE* argv, VALUE klass)
120
+ {
121
+ VALUE string, options;
122
+ rb_scan_args(argc, argv, "11", &string, &options);
123
+
124
+ Check_Type(string, T_STRING);
125
+
126
+ if (RSTRING_LEN(string) == 0)
127
+ rb_raise(rb_eArgError, "Must specify a string with one or more characters");
128
+
129
+ xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(string), (int)RSTRING_LEN(string));
130
+
131
+ if (!ctxt)
132
+ rxml_raise(xmlGetLastError());
133
+
134
+ /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
135
+ xmlCtxtUseOptionsInternal (called below) initialize slightly different
136
+ context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
137
+ sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
138
+ xmlCtxtUseOptions(ctxt, options == Qnil ? 0 : NUM2INT(options));
139
+
140
+ return rxml_parser_context_wrap(ctxt);
141
+ }
142
+
143
+ /* call-seq:
144
+ * XML::Parser::Context.io(io) -> XML::Parser::Context
145
+ *
146
+ * Creates a new parser context based on the specified io object.
147
+ *
148
+ * Parameters:
149
+ *
150
+ * io - A ruby IO object
151
+ * options - A or'ed together list of LibXML::XML::Parser::Options values
152
+ */
153
+ static VALUE rxml_parser_context_io(int argc, VALUE* argv, VALUE klass)
154
+ {
155
+ VALUE io, options;
156
+ rb_scan_args(argc, argv, "11", &io, &options);
157
+
158
+ if (NIL_P(io))
159
+ rb_raise(rb_eTypeError, "Must pass in an IO object");
160
+
161
+ xmlParserInputBufferPtr input = xmlParserInputBufferCreateIO((xmlInputReadCallback) rxml_read_callback, NULL,
162
+ (void*)io, XML_CHAR_ENCODING_NONE);
163
+
164
+ xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
165
+
166
+ if (!ctxt)
167
+ {
168
+ xmlFreeParserInputBuffer(input);
169
+ rxml_raise(xmlGetLastError());
170
+ }
171
+
172
+ /* This is annoying, but xmlInitParserCtxt (called indirectly above) and
173
+ xmlCtxtUseOptionsInternal (called below) initialize slightly different
174
+ context options, in particular XML_PARSE_NODICT which xmlInitParserCtxt
175
+ sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
176
+ xmlCtxtUseOptions(ctxt, options == Qnil ? 0 : NUM2INT(options));
177
+
178
+ xmlParserInputPtr stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
179
+
180
+ if (!stream)
181
+ {
182
+ xmlFreeParserInputBuffer(input);
183
+ xmlFreeParserCtxt(ctxt);
184
+ rxml_raise(xmlGetLastError());
185
+ }
186
+ inputPush(ctxt, stream);
187
+ VALUE result = rxml_parser_context_wrap(ctxt);
188
+
189
+ /* Attach io object to parser so it won't get freed.*/
190
+ rb_ivar_set(result, IO_ATTR, io);
191
+
192
+ return result;
193
+ }
194
+
195
+ /*
196
+ * call-seq:
197
+ * context.base_uri -> "http:://libxml.org"
198
+ *
199
+ * Obtain the base url for this parser context.
200
+ */
201
+ static VALUE rxml_parser_context_base_uri_get(VALUE self)
202
+ {
203
+ xmlParserCtxtPtr ctxt;
204
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
205
+
206
+ if (ctxt->input && ctxt->input->filename)
207
+ return rxml_new_cstr((const xmlChar*)ctxt->input->filename, ctxt->encoding);
208
+ else
209
+ return Qnil;
210
+ }
211
+
212
+ /*
213
+ * call-seq:
214
+ * context.base_uri = "http:://libxml.org"
215
+ *
216
+ * Sets the base url for this parser context.
217
+ */
218
+ static VALUE rxml_parser_context_base_uri_set(VALUE self, VALUE url)
219
+ {
220
+ xmlParserCtxtPtr ctxt;
221
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
222
+
223
+ Check_Type(url, T_STRING);
224
+
225
+ if (ctxt->input && !ctxt->input->filename)
226
+ {
227
+ const char* xurl = StringValuePtr(url);
228
+ ctxt->input->filename = (const char*)xmlStrdup((const xmlChar*)xurl);
229
+ }
230
+ return self;
231
+ }
232
+
233
+ /*
234
+ * call-seq:
235
+ * context.close -> nil
236
+ *
237
+ * Closes the underlying input streams. This is useful when parsing a large amount of
238
+ * files and you want to close the files without relying on Ruby's garbage collector
239
+ * to run.
240
+ */
241
+ static VALUE rxml_parser_context_close(VALUE self)
242
+ {
243
+ xmlParserCtxtPtr ctxt;
244
+ xmlParserInputPtr xinput;
245
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
246
+
247
+ while ((xinput = inputPop(ctxt)) != NULL)
248
+ {
249
+ xmlFreeInputStream(xinput);
250
+ }
251
+ return Qnil;
252
+ }
253
+
254
+ /*
255
+ * call-seq:
256
+ * context.data_directory -> "dir"
257
+ *
258
+ * Obtain the data directory associated with this context.
259
+ */
260
+ static VALUE rxml_parser_context_data_directory_get(VALUE self)
261
+ {
262
+ xmlParserCtxtPtr ctxt;
263
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
264
+
265
+ if (ctxt->directory == NULL)
266
+ return (Qnil);
267
+ else
268
+ return (rxml_new_cstr((const xmlChar*)ctxt->directory, ctxt->encoding));
269
+ }
270
+
271
+ /*
272
+ * call-seq:
273
+ * context.depth -> num
274
+ *
275
+ * Obtain the depth of this context.
276
+ */
277
+ static VALUE rxml_parser_context_depth_get(VALUE self)
278
+ {
279
+ xmlParserCtxtPtr ctxt;
280
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
281
+
282
+ return (INT2NUM(ctxt->depth));
283
+ }
284
+
285
+ /*
286
+ * call-seq:
287
+ * context.disable_cdata? -> (true|false)
288
+ *
289
+ * Determine whether CDATA nodes will be created in this context.
290
+ */
291
+ static VALUE rxml_parser_context_disable_cdata_q(VALUE self)
292
+ {
293
+ xmlParserCtxtPtr ctxt;
294
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
295
+
296
+ /* LibXML controls this internally with the default SAX handler. */
297
+ if (ctxt->sax && ctxt->sax->cdataBlock)
298
+ return (Qfalse);
299
+ else
300
+ return (Qtrue);
301
+ }
302
+
303
+ /*
304
+ * call-seq:
305
+ * context.disable_cdata = (true|false)
306
+ *
307
+ * Control whether CDATA nodes will be created in this context.
308
+ */
309
+ static VALUE rxml_parser_context_disable_cdata_set(VALUE self, VALUE value)
310
+ {
311
+ xmlParserCtxtPtr ctxt;
312
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
313
+
314
+ if (ctxt->sax == NULL)
315
+ rb_raise(rb_eRuntimeError, "Sax handler is not yet set");
316
+
317
+ /* LibXML controls this internally with the default SAX handler. */
318
+ if (value)
319
+ ctxt->sax->cdataBlock = NULL;
320
+ else
321
+ ctxt->sax->cdataBlock = xmlSAX2CDataBlock;
322
+
323
+ return value;
324
+ }
325
+
326
+ /*
327
+ * call-seq:
328
+ * context.disable_sax? -> (true|false)
329
+ *
330
+ * Determine whether SAX-based processing is disabled
331
+ * in this context.
332
+ */
333
+ static VALUE rxml_parser_context_disable_sax_q(VALUE self)
334
+ {
335
+ xmlParserCtxtPtr ctxt;
336
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
337
+
338
+ if (ctxt->disableSAX)
339
+ return (Qtrue);
340
+ else
341
+ return (Qfalse);
342
+ }
343
+
344
+ /*
345
+ * call-seq:
346
+ * context.docbook? -> (true|false)
347
+ *
348
+ * Determine whether this is a docbook context.
349
+ */
350
+ static VALUE rxml_parser_context_docbook_q(VALUE self)
351
+ {
352
+ xmlParserCtxtPtr ctxt;
353
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
354
+
355
+ if (ctxt->html == 2) // TODO check this
356
+ return (Qtrue);
357
+ else
358
+ return (Qfalse);
359
+ }
360
+
361
+ /*
362
+ * call-seq:
363
+ * context.encoding -> XML::Encoding::UTF_8
364
+ *
365
+ * Obtain the character encoding identifier used in
366
+ * this context.
367
+ */
368
+ static VALUE rxml_parser_context_encoding_get(VALUE self)
369
+ {
370
+ xmlParserCtxtPtr ctxt;
371
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
372
+ return INT2NUM(xmlParseCharEncoding((const char*)ctxt->encoding));
373
+ }
374
+
375
+ /*
376
+ * call-seq:
377
+ * context.encoding = XML::Encoding::UTF_8
378
+ *
379
+ * Sets the character encoding for this context.
380
+ */
381
+ static VALUE rxml_parser_context_encoding_set(VALUE self, VALUE encoding)
382
+ {
383
+ xmlParserCtxtPtr ctxt;
384
+ int result;
385
+ const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
386
+ xmlCharEncodingHandlerPtr hdlr = xmlFindCharEncodingHandler(xencoding);
387
+
388
+ if (!hdlr)
389
+ rb_raise(rb_eArgError, "Unknown encoding: %i", NUM2INT(encoding));
390
+
391
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
392
+ result = xmlSwitchToEncoding(ctxt, hdlr);
393
+
394
+ if (result != 0)
395
+ rxml_raise(xmlGetLastError());
396
+
397
+ if (ctxt->encoding != NULL)
398
+ xmlFree((xmlChar *) ctxt->encoding);
399
+
400
+ ctxt->encoding = xmlStrdup((const xmlChar *) xencoding);
401
+ return self;
402
+ }
403
+
404
+ /*
405
+ * call-seq:
406
+ * context.errno -> num
407
+ *
408
+ * Obtain the last-error number in this context.
409
+ */
410
+ static VALUE rxml_parser_context_errno_get(VALUE self)
411
+ {
412
+ xmlParserCtxtPtr ctxt;
413
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
414
+
415
+ return (INT2NUM(ctxt->errNo));
416
+ }
417
+
418
+ /*
419
+ * call-seq:
420
+ * context.html? -> (true|false)
421
+ *
422
+ * Determine whether this is an html context.
423
+ */
424
+ static VALUE rxml_parser_context_html_q(VALUE self)
425
+ {
426
+ xmlParserCtxtPtr ctxt;
427
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
428
+
429
+ if (ctxt->html == 1)
430
+ return (Qtrue);
431
+ else
432
+ return (Qfalse);
433
+ }
434
+
435
+ /*
436
+ * call-seq:
437
+ * context.max_num_streams -> num
438
+ *
439
+ * Obtain the limit on the number of IO streams opened in
440
+ * this context.
441
+ */
442
+ static VALUE rxml_parser_context_io_max_num_streams_get(VALUE self)
443
+ {
444
+ // TODO alias to max_streams and dep this?
445
+ xmlParserCtxtPtr ctxt;
446
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
447
+
448
+ return (INT2NUM(ctxt->inputMax));
449
+ }
450
+
451
+ /*
452
+ * call-seq:
453
+ * context.num_streams -> "dir"
454
+ *
455
+ * Obtain the actual number of IO streams in this
456
+ * context.
457
+ */
458
+ static VALUE rxml_parser_context_io_num_streams_get(VALUE self)
459
+ {
460
+ xmlParserCtxtPtr ctxt;
461
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
462
+
463
+ return (INT2NUM(ctxt->inputNr));
464
+ }
465
+
466
+ /*
467
+ * call-seq:
468
+ * context.keep_blanks? -> (true|false)
469
+ *
470
+ * Determine whether parsers in this context retain
471
+ * whitespace.
472
+ */
473
+ static VALUE rxml_parser_context_keep_blanks_q(VALUE self)
474
+ {
475
+ xmlParserCtxtPtr ctxt;
476
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
477
+
478
+ if (ctxt->keepBlanks)
479
+ return (Qtrue);
480
+ else
481
+ return (Qfalse);
482
+ }
483
+
484
+ /*
485
+ * call-seq:
486
+ * context.name_depth -> num
487
+ *
488
+ * Obtain the name depth for this context.
489
+ */
490
+ static VALUE rxml_parser_context_name_depth_get(VALUE self)
491
+ {
492
+ xmlParserCtxtPtr ctxt;
493
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
494
+
495
+ return (INT2NUM(ctxt->nameNr));
496
+ }
497
+
498
+ /*
499
+ * call-seq:
500
+ * context.name_depth_max -> num
501
+ *
502
+ * Obtain the maximum name depth for this context.
503
+ */
504
+ static VALUE rxml_parser_context_name_depth_max_get(VALUE self)
505
+ {
506
+ xmlParserCtxtPtr ctxt;
507
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
508
+
509
+ return (INT2NUM(ctxt->nameMax));
510
+ }
511
+
512
+ /*
513
+ * call-seq:
514
+ * context.name_node -> "name"
515
+ *
516
+ * Obtain the name node for this context.
517
+ */
518
+ static VALUE rxml_parser_context_name_node_get(VALUE self)
519
+ {
520
+ xmlParserCtxtPtr ctxt;
521
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
522
+
523
+ if (ctxt->name == NULL)
524
+ return (Qnil);
525
+ else
526
+ return (rxml_new_cstr( ctxt->name, ctxt->encoding));
527
+ }
528
+
529
+ /*
530
+ * call-seq:
531
+ * context.name_tab -> ["name", ..., "name"]
532
+ *
533
+ * Obtain the name table for this context.
534
+ */
535
+ static VALUE rxml_parser_context_name_tab_get(VALUE self)
536
+ {
537
+ int i;
538
+ xmlParserCtxtPtr ctxt;
539
+ VALUE tab_ary;
540
+
541
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
542
+
543
+ if (ctxt->nameTab == NULL)
544
+ return (Qnil);
545
+
546
+ tab_ary = rb_ary_new();
547
+
548
+ for (i = (ctxt->nameNr - 1); i >= 0; i--)
549
+ {
550
+ if (ctxt->nameTab[i] == NULL)
551
+ continue;
552
+ else
553
+ rb_ary_push(tab_ary, rxml_new_cstr( ctxt->nameTab[i], ctxt->encoding));
554
+ }
555
+
556
+ return (tab_ary);
557
+ }
558
+
559
+ /*
560
+ * call-seq:
561
+ * context.node_depth -> num
562
+ *
563
+ * Obtain the node depth for this context.
564
+ */
565
+ static VALUE rxml_parser_context_node_depth_get(VALUE self)
566
+ {
567
+ xmlParserCtxtPtr ctxt;
568
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
569
+
570
+ return (INT2NUM(ctxt->nodeNr));
571
+ }
572
+
573
+ /*
574
+ * call-seq:
575
+ * context.node -> node
576
+ *
577
+ * Obtain the root node of this context.
578
+ */
579
+ static VALUE rxml_parser_context_node_get(VALUE self)
580
+ {
581
+ xmlParserCtxtPtr ctxt;
582
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
583
+
584
+ if (ctxt->node == NULL)
585
+ return (Qnil);
586
+ else
587
+ return (rxml_node_wrap(ctxt->node));
588
+ }
589
+
590
+ /*
591
+ * call-seq:
592
+ * context.node_depth_max -> num
593
+ *
594
+ * Obtain the maximum node depth for this context.
595
+ */
596
+ static VALUE rxml_parser_context_node_depth_max_get(VALUE self)
597
+ {
598
+ xmlParserCtxtPtr ctxt;
599
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
600
+
601
+ return (INT2NUM(ctxt->nodeMax));
602
+ }
603
+
604
+ /*
605
+ * call-seq:
606
+ * context.num_chars -> num
607
+ *
608
+ * Obtain the number of characters in this context.
609
+ */
610
+ static VALUE rxml_parser_context_num_chars_get(VALUE self)
611
+ {
612
+ xmlParserCtxtPtr ctxt;
613
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
614
+
615
+ return (LONG2NUM(ctxt->nbChars));
616
+ }
617
+
618
+
619
+ /*
620
+ * call-seq:
621
+ * context.options > XML::Parser::Options::NOENT
622
+ *
623
+ * Returns the parser options for this context. Multiple
624
+ * options can be combined by using Bitwise OR (|).
625
+ */
626
+ static VALUE rxml_parser_context_options_get(VALUE self)
627
+ {
628
+ xmlParserCtxtPtr ctxt;
629
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
630
+
631
+ return INT2NUM(ctxt->options);
632
+ }
633
+
634
+ /*
635
+ * call-seq:
636
+ * context.options = XML::Parser::Options::NOENT |
637
+ XML::Parser::Options::NOCDATA
638
+ *
639
+ * Provides control over the execution of a parser. Valid values
640
+ * are the constants defined on XML::Parser::Options. Multiple
641
+ * options can be combined by using Bitwise OR (|).
642
+ */
643
+ static VALUE rxml_parser_context_options_set(VALUE self, VALUE options)
644
+ {
645
+ xmlParserCtxtPtr ctxt;
646
+ Check_Type(options, T_FIXNUM);
647
+
648
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
649
+ xmlCtxtUseOptions(ctxt, NUM2INT(options));
650
+
651
+ return self;
652
+ }
653
+
654
+ /*
655
+ * call-seq:
656
+ * context.recovery? -> (true|false)
657
+ *
658
+ * Determine whether recovery mode is enabled in this
659
+ * context.
660
+ */
661
+ static VALUE rxml_parser_context_recovery_q(VALUE self)
662
+ {
663
+ xmlParserCtxtPtr ctxt;
664
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
665
+
666
+ if (ctxt->recovery)
667
+ return (Qtrue);
668
+ else
669
+ return (Qfalse);
670
+ }
671
+
672
+ /*
673
+ * call-seq:
674
+ * context.recovery = true|false
675
+ *
676
+ * Control whether recovery mode is enabled in this
677
+ * context.
678
+ */
679
+ static VALUE rxml_parser_context_recovery_set(VALUE self, VALUE value)
680
+ {
681
+ xmlParserCtxtPtr ctxt;
682
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
683
+
684
+ if (value == Qfalse)
685
+ {
686
+ ctxt->recovery = 0;
687
+ return (Qfalse);
688
+ }
689
+ else
690
+ {
691
+ ctxt->recovery = 1;
692
+ return (Qtrue);
693
+ }
694
+ }
695
+
696
+ /*
697
+ * call-seq:
698
+ * context.replace_entities? -> (true|false)
699
+ *
700
+ * Determine whether external entity replacement is enabled in this
701
+ * context.
702
+ */
703
+ static VALUE rxml_parser_context_replace_entities_q(VALUE self)
704
+ {
705
+ xmlParserCtxtPtr ctxt;
706
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
707
+
708
+ if (ctxt->replaceEntities)
709
+ return (Qtrue);
710
+ else
711
+ return (Qfalse);
712
+ }
713
+
714
+ /*
715
+ * call-seq:
716
+ * context.replace_entities = true|false
717
+ *
718
+ * Control whether external entity replacement is enabled in this
719
+ * context.
720
+ */
721
+ static VALUE rxml_parser_context_replace_entities_set(VALUE self, VALUE value)
722
+ {
723
+ xmlParserCtxtPtr ctxt;
724
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
725
+
726
+ if (value == Qfalse)
727
+ {
728
+ ctxt->replaceEntities = 0;
729
+ return (Qfalse);
730
+ }
731
+ else
732
+ {
733
+ ctxt->replaceEntities = 1;
734
+ return (Qtrue);
735
+ }
736
+ }
737
+
738
+ /*
739
+ * call-seq:
740
+ * context.space_depth -> num
741
+ *
742
+ * Obtain the space depth for this context.
743
+ */
744
+ static VALUE rxml_parser_context_space_depth_get(VALUE self)
745
+ {
746
+ xmlParserCtxtPtr ctxt;
747
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
748
+
749
+ return (INT2NUM(ctxt->spaceNr));
750
+ }
751
+
752
+ /*
753
+ * call-seq:
754
+ * context.space_depth -> num
755
+ *
756
+ * Obtain the maximum space depth for this context.
757
+ */
758
+ static VALUE rxml_parser_context_space_depth_max_get(VALUE self)
759
+ {
760
+ xmlParserCtxtPtr ctxt;
761
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
762
+
763
+ return (INT2NUM(ctxt->spaceMax));
764
+ }
765
+
766
+ /*
767
+ * call-seq:
768
+ * context.subset_external? -> (true|false)
769
+ *
770
+ * Determine whether this context is a subset of an
771
+ * external context.
772
+ */
773
+ static VALUE rxml_parser_context_subset_external_q(VALUE self)
774
+ {
775
+ xmlParserCtxtPtr ctxt;
776
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
777
+
778
+ if (ctxt->inSubset == 2)
779
+ return (Qtrue);
780
+ else
781
+ return (Qfalse);
782
+ }
783
+
784
+ /*
785
+ * call-seq:
786
+ * context.subset_internal? -> (true|false)
787
+ *
788
+ * Determine whether this context is a subset of an
789
+ * internal context.
790
+ */
791
+ static VALUE rxml_parser_context_subset_internal_q(VALUE self)
792
+ {
793
+ xmlParserCtxtPtr ctxt;
794
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
795
+
796
+ if (ctxt->inSubset == 1)
797
+ return (Qtrue);
798
+ else
799
+ return (Qfalse);
800
+ }
801
+
802
+ /*
803
+ * call-seq:
804
+ * context.subset_internal_name -> "name"
805
+ *
806
+ * Obtain this context's subset name (valid only if
807
+ * either of subset_external? or subset_internal?
808
+ * is true).
809
+ */
810
+ static VALUE rxml_parser_context_subset_name_get(VALUE self)
811
+ {
812
+ xmlParserCtxtPtr ctxt;
813
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
814
+
815
+ if (ctxt->intSubName == NULL)
816
+ return (Qnil);
817
+ else
818
+ return (rxml_new_cstr(ctxt->intSubName, ctxt->encoding));
819
+ }
820
+
821
+ /*
822
+ * call-seq:
823
+ * context.subset_external_uri -> "uri"
824
+ *
825
+ * Obtain this context's external subset URI. (valid only if
826
+ * either of subset_external? or subset_internal?
827
+ * is true).
828
+ */
829
+ static VALUE rxml_parser_context_subset_external_uri_get(VALUE self)
830
+ {
831
+ xmlParserCtxtPtr ctxt;
832
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
833
+
834
+ if (ctxt->extSubURI == NULL)
835
+ return (Qnil);
836
+ else
837
+ return (rxml_new_cstr( ctxt->extSubURI, ctxt->encoding));
838
+ }
839
+
840
+ /*
841
+ * call-seq:
842
+ * context.subset_external_system_id -> "system_id"
843
+ *
844
+ * Obtain this context's external subset system identifier.
845
+ * (valid only if either of subset_external? or subset_internal?
846
+ * is true).
847
+ */
848
+ static VALUE rxml_parser_context_subset_external_system_id_get(VALUE self)
849
+ {
850
+ xmlParserCtxtPtr ctxt;
851
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
852
+
853
+ if (ctxt->extSubSystem == NULL)
854
+ return (Qnil);
855
+ else
856
+ return (rxml_new_cstr( ctxt->extSubSystem, ctxt->encoding));
857
+ }
858
+
859
+ /*
860
+ * call-seq:
861
+ * context.standalone? -> (true|false)
862
+ *
863
+ * Determine whether this is a standalone context.
864
+ */
865
+ static VALUE rxml_parser_context_standalone_q(VALUE self)
866
+ {
867
+ xmlParserCtxtPtr ctxt;
868
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
869
+
870
+ if (ctxt->standalone)
871
+ return (Qtrue);
872
+ else
873
+ return (Qfalse);
874
+ }
875
+
876
+ /*
877
+ * call-seq:
878
+ * context.stats? -> (true|false)
879
+ *
880
+ * Determine whether this context maintains statistics.
881
+ */
882
+ static VALUE rxml_parser_context_stats_q(VALUE self)
883
+ {
884
+ xmlParserCtxtPtr ctxt;
885
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
886
+
887
+ if (ctxt->record_info)
888
+ return (Qtrue);
889
+ else
890
+ return (Qfalse);
891
+ }
892
+
893
+ /*
894
+ * call-seq:
895
+ * context.valid? -> (true|false)
896
+ *
897
+ * Determine whether this context is valid.
898
+ */
899
+ static VALUE rxml_parser_context_valid_q(VALUE self)
900
+ {
901
+ xmlParserCtxtPtr ctxt;
902
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
903
+
904
+ if (ctxt->valid)
905
+ return (Qtrue);
906
+ else
907
+ return (Qfalse);
908
+ }
909
+
910
+ /*
911
+ * call-seq:
912
+ * context.validate? -> (true|false)
913
+ *
914
+ * Determine whether validation is enabled in this context.
915
+ */
916
+ static VALUE rxml_parser_context_validate_q(VALUE self)
917
+ {
918
+ xmlParserCtxtPtr ctxt;
919
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
920
+
921
+ if (ctxt->validate)
922
+ return (Qtrue);
923
+ else
924
+ return (Qfalse);
925
+ }
926
+
927
+ /*
928
+ * call-seq:
929
+ * context.version -> "version"
930
+ *
931
+ * Obtain this context's version identifier.
932
+ */
933
+ static VALUE rxml_parser_context_version_get(VALUE self)
934
+ {
935
+ xmlParserCtxtPtr ctxt;
936
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
937
+
938
+ if (ctxt->version == NULL)
939
+ return (Qnil);
940
+ else
941
+ return (rxml_new_cstr( ctxt->version, ctxt->encoding));
942
+ }
943
+
944
+ /*
945
+ * call-seq:
946
+ * context.well_formed? -> (true|false)
947
+ *
948
+ * Determine whether this context contains well-formed XML.
949
+ */
950
+ static VALUE rxml_parser_context_well_formed_q(VALUE self)
951
+ {
952
+ xmlParserCtxtPtr ctxt;
953
+ TypedData_Get_Struct(self, xmlParserCtxt, &rxml_parser_context_type, ctxt);
954
+
955
+ if (ctxt->wellFormed)
956
+ return (Qtrue);
957
+ else
958
+ return (Qfalse);
959
+ }
960
+
961
+ void rxml_init_parser_context(void)
962
+ {
963
+ IO_ATTR = ID2SYM(rb_intern("@io"));
964
+
965
+ cXMLParserContext = rb_define_class_under(cXMLParser, "Context", rb_cObject);
966
+ rb_define_alloc_func(cXMLParserContext, rxml_parser_context_alloc);
967
+
968
+ rb_define_singleton_method(cXMLParserContext, "document", rxml_parser_context_document, -1);
969
+ rb_define_singleton_method(cXMLParserContext, "file", rxml_parser_context_file, -1);
970
+ rb_define_singleton_method(cXMLParserContext, "io", rxml_parser_context_io, -1);
971
+ rb_define_singleton_method(cXMLParserContext, "string", rxml_parser_context_string, -1);
972
+
973
+ rb_define_method(cXMLParserContext, "base_uri", rxml_parser_context_base_uri_get, 0);
974
+ rb_define_method(cXMLParserContext, "base_uri=", rxml_parser_context_base_uri_set, 1);
975
+ rb_define_method(cXMLParserContext, "close", rxml_parser_context_close, 0);
976
+ rb_define_method(cXMLParserContext, "data_directory", rxml_parser_context_data_directory_get, 0);
977
+ rb_define_method(cXMLParserContext, "depth", rxml_parser_context_depth_get, 0);
978
+ rb_define_method(cXMLParserContext, "disable_cdata?", rxml_parser_context_disable_cdata_q, 0);
979
+ rb_define_method(cXMLParserContext, "disable_cdata=", rxml_parser_context_disable_cdata_set, 1);
980
+ rb_define_method(cXMLParserContext, "disable_sax?", rxml_parser_context_disable_sax_q, 0);
981
+ rb_define_method(cXMLParserContext, "docbook?", rxml_parser_context_docbook_q, 0);
982
+ rb_define_method(cXMLParserContext, "encoding", rxml_parser_context_encoding_get, 0);
983
+ rb_define_method(cXMLParserContext, "encoding=", rxml_parser_context_encoding_set, 1);
984
+ rb_define_method(cXMLParserContext, "errno", rxml_parser_context_errno_get, 0);
985
+ rb_define_method(cXMLParserContext, "html?", rxml_parser_context_html_q, 0);
986
+ rb_define_method(cXMLParserContext, "io_max_num_streams", rxml_parser_context_io_max_num_streams_get, 0);
987
+ rb_define_method(cXMLParserContext, "io_num_streams", rxml_parser_context_io_num_streams_get, 0);
988
+ rb_define_method(cXMLParserContext, "keep_blanks?", rxml_parser_context_keep_blanks_q, 0);
989
+ rb_define_method(cXMLParserContext, "name_node", rxml_parser_context_name_node_get, 0);
990
+ rb_define_method(cXMLParserContext, "name_depth", rxml_parser_context_name_depth_get, 0);
991
+ rb_define_method(cXMLParserContext, "name_depth_max", rxml_parser_context_name_depth_max_get, 0);
992
+ rb_define_method(cXMLParserContext, "name_tab", rxml_parser_context_name_tab_get, 0);
993
+ rb_define_method(cXMLParserContext, "node", rxml_parser_context_node_get, 0);
994
+ rb_define_method(cXMLParserContext, "node_depth", rxml_parser_context_node_depth_get, 0);
995
+ rb_define_method(cXMLParserContext, "node_depth_max", rxml_parser_context_node_depth_max_get, 0);
996
+ rb_define_method(cXMLParserContext, "num_chars", rxml_parser_context_num_chars_get, 0);
997
+ rb_define_method(cXMLParserContext, "options", rxml_parser_context_options_get, 0);
998
+ rb_define_method(cXMLParserContext, "options=", rxml_parser_context_options_set, 1);
999
+ rb_define_method(cXMLParserContext, "recovery?", rxml_parser_context_recovery_q, 0);
1000
+ rb_define_method(cXMLParserContext, "recovery=", rxml_parser_context_recovery_set, 1);
1001
+ rb_define_method(cXMLParserContext, "replace_entities?", rxml_parser_context_replace_entities_q, 0);
1002
+ rb_define_method(cXMLParserContext, "replace_entities=", rxml_parser_context_replace_entities_set, 1);
1003
+ rb_define_method(cXMLParserContext, "space_depth", rxml_parser_context_space_depth_get, 0);
1004
+ rb_define_method(cXMLParserContext, "space_depth_max", rxml_parser_context_space_depth_max_get, 0);
1005
+ rb_define_method(cXMLParserContext, "subset_external?", rxml_parser_context_subset_external_q, 0);
1006
+ rb_define_method(cXMLParserContext, "subset_external_system_id", rxml_parser_context_subset_external_system_id_get, 0);
1007
+ rb_define_method(cXMLParserContext, "subset_external_uri", rxml_parser_context_subset_external_uri_get, 0);
1008
+ rb_define_method(cXMLParserContext, "subset_internal?", rxml_parser_context_subset_internal_q, 0);
1009
+ rb_define_method(cXMLParserContext, "subset_internal_name", rxml_parser_context_subset_name_get, 0);
1010
+ rb_define_method(cXMLParserContext, "stats?", rxml_parser_context_stats_q, 0);
1011
+ rb_define_method(cXMLParserContext, "standalone?", rxml_parser_context_standalone_q, 0);
1012
+ rb_define_method(cXMLParserContext, "valid", rxml_parser_context_valid_q, 0);
1013
+ rb_define_method(cXMLParserContext, "validate?", rxml_parser_context_validate_q, 0);
1014
+ rb_define_method(cXMLParserContext, "version", rxml_parser_context_version_get, 0);
1015
+ rb_define_method(cXMLParserContext, "well_formed?", rxml_parser_context_well_formed_q, 0);
1016
+ }