File: ruby_xml_dtd.c

package info (click to toggle)
ruby-mkrf 0.2.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,688 kB
  • sloc: ansic: 12,494; ruby: 6,998; sh: 790; yacc: 374; makefile: 57; cpp: 10
file content (168 lines) | stat: -rw-r--r-- 4,658 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "libxml.h"
#include "ruby_xml_dtd.h"

VALUE cXMLDtd;

void
ruby_xml_dtd_free(ruby_xml_dtd *rxdtd) {
  if (rxdtd->dtd != NULL) {
    xmlFreeDtd(rxdtd->dtd);
    rxdtd->dtd = NULL;
  }

  free(rxdtd);
}

static void
ruby_xml_dtd_mark(ruby_xml_dtd *rxdtd) {
  return;
  //if (rxdtd == NULL) return;
  //if (!NIL_P(rxd->xmlver)) rb_gc_mark(rxd->xmlver);
}

/*
 * call-seq:
 *    XML::Dtd.new("public system") => dtd
 *    XML::Dtd.new("public", "system") => dtd
 * 
 * Create a new Dtd from the specified public and system
 * identifiers.
 */
VALUE
ruby_xml_dtd_initialize(int argc, VALUE *argv, VALUE class) {
  ruby_xml_dtd *rxdtd;
  VALUE external, system, dtd_string;
  xmlParserInputBufferPtr buffer;
  xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
  xmlChar *new_string;

  // 1 argument -- string               --> parsujeme jako dtd
  // 2 argumenty -- public, system      --> bude se hledat
  switch (argc) {
  case 2:
    rb_scan_args(argc, argv, "20", &external, &system);

    Check_Type(external, T_STRING);
    Check_Type(system,   T_STRING);
    rxdtd = ALLOC(ruby_xml_dtd);
    rxdtd->dtd = xmlParseDTD( (xmlChar*)StringValuePtr(external),
                              (xmlChar*)StringValuePtr(system) );
    if (rxdtd->dtd == NULL) {
      free(rxdtd);
      return(Qfalse);
    }

    xmlSetTreeDoc( (xmlNodePtr)rxdtd->dtd, NULL );
    return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
    break;

/*
SV *
new(CLASS, external, system)
        char * CLASS
        char * external
        char * system
    ALIAS:
        parse_uri = 1
    PREINIT:
        xmlDtdPtr dtd = NULL;
    CODE:
        LibXML_error = sv_2mortal(newSVpv("", 0));
        dtd = xmlParseDTD((const xmlChar*)external, (const xmlChar*)system);
        if ( dtd == NULL ) {
            XSRETURN_UNDEF;
        }
        xmlSetTreeDoc((xmlNodePtr)dtd, NULL);
        RETVAL = PmmNodeToSv( (xmlNodePtr) dtd, NULL );
    OUTPUT:
        RETVAL
*/

  case 1:

    rb_scan_args(argc, argv, "10", &dtd_string);
    buffer = xmlAllocParserInputBuffer(enc);
    //if ( !buffer) return Qnil
    new_string = xmlStrdup((xmlChar*)StringValuePtr(dtd_string));
    xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);

    rxdtd = ALLOC(ruby_xml_dtd);
    rxdtd->dtd = xmlIOParseDTD(NULL, buffer, enc);

    // NOTE: For some reason freeing this InputBuffer causes a segfault! 
    // xmlFreeParserInputBuffer(buffer); 
    xmlFree(new_string);

    return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );

    break;
/*
SV * parse_string(CLASS, str, ...)
        char * CLASS
        char * str
    PREINIT:
        STRLEN n_a;
        xmlDtdPtr res;
        SV * encoding_sv;
        xmlParserInputBufferPtr buffer;
        xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
        xmlChar * new_string;
        STRLEN len;
    CODE:
        LibXML_init_error();
        if (items > 2) {
            encoding_sv = ST(2);
            if (items > 3) {
                croak("parse_string: too many parameters");
            }
            // warn("getting encoding...\n"); 
            enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
            if (enc == XML_CHAR_ENCODING_ERROR) {
                croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
            }
        }
        buffer = xmlAllocParserInputBuffer(enc);
        // buffer = xmlParserInputBufferCreateMem(str, xmlStrlen(str), enc); 
        if ( !buffer)
            croak("cant create buffer!\n" );

        new_string = xmlStrdup((const xmlChar*)str);
        xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);

        res = xmlIOParseDTD(NULL, buffer, enc);

        // NOTE: For some reason freeing this InputBuffer causes a segfault! 
        // xmlFreeParserInputBuffer(buffer); 
        xmlFree(new_string);

        sv_2mortal( LibXML_error );
        LibXML_croak_error();

        if (res == NULL) {
            croak("no DTD parsed!");
        }
        RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
    OUTPUT:
        RETVAL
 */
    
  default:
    rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
  }

  //docobj = ruby_xml_document_new2(cXMLDocument, xmlver);
  return Qnil;
}

// Rdoc needs to know 
#ifdef RDOC_NEVER_DEFINED
  mXML = rb_define_module("XML");
#endif

void
ruby_init_xml_dtd(void) {
  cXMLDtd = rb_define_class_under(mXML, "Dtd", rb_cObject);
  rb_define_singleton_method(cXMLDtd, "new", ruby_xml_dtd_initialize, -1);
  //rb_define_method(cXMLDocument, "xinclude", ruby_xml_document_xinclude, 0);
}