libxml-ruby 5.0.4 → 5.0.5

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