libxml-ruby 0.9.9-x86-mswin32-60 → 1.0.0-x86-mswin32-60

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