xref: /aosp_15_r20/external/libxml2/example/io1.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /**
2*7c568831SAndroid Build Coastguard Worker  * section: InputOutput
3*7c568831SAndroid Build Coastguard Worker  * synopsis: Example of custom Input/Output
4*7c568831SAndroid Build Coastguard Worker  * purpose: Demonstrate the use of xmlRegisterInputCallbacks
5*7c568831SAndroid Build Coastguard Worker  *          to build a custom I/O layer, this is used in an
6*7c568831SAndroid Build Coastguard Worker  *          XInclude method context to show how dynamic document can
7*7c568831SAndroid Build Coastguard Worker  *          be built in a clean way.
8*7c568831SAndroid Build Coastguard Worker  * usage: io1
9*7c568831SAndroid Build Coastguard Worker  * test: io1 > io1.tmp && diff io1.tmp $(srcdir)/io1.res
10*7c568831SAndroid Build Coastguard Worker  * author: Daniel Veillard
11*7c568831SAndroid Build Coastguard Worker  * copy: see Copyright for the status of this software.
12*7c568831SAndroid Build Coastguard Worker  */
13*7c568831SAndroid Build Coastguard Worker 
14*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
15*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
16*7c568831SAndroid Build Coastguard Worker #include <string.h>
17*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
18*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
19*7c568831SAndroid Build Coastguard Worker #include <libxml/xinclude.h>
20*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlIO.h>
21*7c568831SAndroid Build Coastguard Worker 
22*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_XINCLUDE_ENABLED
23*7c568831SAndroid Build Coastguard Worker static const char *result = "<list><people>a</people><people>b</people></list>";
24*7c568831SAndroid Build Coastguard Worker static const char *cur = NULL;
25*7c568831SAndroid Build Coastguard Worker static int rlen;
26*7c568831SAndroid Build Coastguard Worker 
27*7c568831SAndroid Build Coastguard Worker /**
28*7c568831SAndroid Build Coastguard Worker  * sqlMatch:
29*7c568831SAndroid Build Coastguard Worker  * @URI: an URI to test
30*7c568831SAndroid Build Coastguard Worker  *
31*7c568831SAndroid Build Coastguard Worker  * Check for an sql: query
32*7c568831SAndroid Build Coastguard Worker  *
33*7c568831SAndroid Build Coastguard Worker  * Returns 1 if yes and 0 if another Input module should be used
34*7c568831SAndroid Build Coastguard Worker  */
35*7c568831SAndroid Build Coastguard Worker static int
sqlMatch(const char * URI)36*7c568831SAndroid Build Coastguard Worker sqlMatch(const char * URI) {
37*7c568831SAndroid Build Coastguard Worker     if ((URI != NULL) && (!strncmp(URI, "sql:", 4)))
38*7c568831SAndroid Build Coastguard Worker         return(1);
39*7c568831SAndroid Build Coastguard Worker     return(0);
40*7c568831SAndroid Build Coastguard Worker }
41*7c568831SAndroid Build Coastguard Worker 
42*7c568831SAndroid Build Coastguard Worker /**
43*7c568831SAndroid Build Coastguard Worker  * sqlOpen:
44*7c568831SAndroid Build Coastguard Worker  * @URI: an URI to test
45*7c568831SAndroid Build Coastguard Worker  *
46*7c568831SAndroid Build Coastguard Worker  * Return a pointer to the sql: query handler, in this example simply
47*7c568831SAndroid Build Coastguard Worker  * the current pointer...
48*7c568831SAndroid Build Coastguard Worker  *
49*7c568831SAndroid Build Coastguard Worker  * Returns an Input context or NULL in case or error
50*7c568831SAndroid Build Coastguard Worker  */
51*7c568831SAndroid Build Coastguard Worker static void *
sqlOpen(const char * URI)52*7c568831SAndroid Build Coastguard Worker sqlOpen(const char * URI) {
53*7c568831SAndroid Build Coastguard Worker     if ((URI == NULL) || (strncmp(URI, "sql:", 4)))
54*7c568831SAndroid Build Coastguard Worker         return(NULL);
55*7c568831SAndroid Build Coastguard Worker     cur = result;
56*7c568831SAndroid Build Coastguard Worker     rlen = strlen(result);
57*7c568831SAndroid Build Coastguard Worker     return((void *) cur);
58*7c568831SAndroid Build Coastguard Worker }
59*7c568831SAndroid Build Coastguard Worker 
60*7c568831SAndroid Build Coastguard Worker /**
61*7c568831SAndroid Build Coastguard Worker  * sqlClose:
62*7c568831SAndroid Build Coastguard Worker  * @context: the read context
63*7c568831SAndroid Build Coastguard Worker  *
64*7c568831SAndroid Build Coastguard Worker  * Close the sql: query handler
65*7c568831SAndroid Build Coastguard Worker  *
66*7c568831SAndroid Build Coastguard Worker  * Returns 0 or -1 in case of error
67*7c568831SAndroid Build Coastguard Worker  */
68*7c568831SAndroid Build Coastguard Worker static int
sqlClose(void * context)69*7c568831SAndroid Build Coastguard Worker sqlClose(void * context) {
70*7c568831SAndroid Build Coastguard Worker     if (context == NULL) return(-1);
71*7c568831SAndroid Build Coastguard Worker     cur = NULL;
72*7c568831SAndroid Build Coastguard Worker     rlen = 0;
73*7c568831SAndroid Build Coastguard Worker     return(0);
74*7c568831SAndroid Build Coastguard Worker }
75*7c568831SAndroid Build Coastguard Worker 
76*7c568831SAndroid Build Coastguard Worker /**
77*7c568831SAndroid Build Coastguard Worker  * sqlRead:
78*7c568831SAndroid Build Coastguard Worker  * @context: the read context
79*7c568831SAndroid Build Coastguard Worker  * @buffer: where to store data
80*7c568831SAndroid Build Coastguard Worker  * @len: number of bytes to read
81*7c568831SAndroid Build Coastguard Worker  *
82*7c568831SAndroid Build Coastguard Worker  * Implement an sql: query read.
83*7c568831SAndroid Build Coastguard Worker  *
84*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes read or -1 in case of error
85*7c568831SAndroid Build Coastguard Worker  */
86*7c568831SAndroid Build Coastguard Worker static int
sqlRead(void * context,char * buffer,int len)87*7c568831SAndroid Build Coastguard Worker sqlRead(void * context, char * buffer, int len) {
88*7c568831SAndroid Build Coastguard Worker    const char *ptr = (const char *) context;
89*7c568831SAndroid Build Coastguard Worker 
90*7c568831SAndroid Build Coastguard Worker    if ((context == NULL) || (buffer == NULL) || (len < 0))
91*7c568831SAndroid Build Coastguard Worker        return(-1);
92*7c568831SAndroid Build Coastguard Worker 
93*7c568831SAndroid Build Coastguard Worker    if (len > rlen) len = rlen;
94*7c568831SAndroid Build Coastguard Worker    memcpy(buffer, ptr, len);
95*7c568831SAndroid Build Coastguard Worker    rlen -= len;
96*7c568831SAndroid Build Coastguard Worker    return(len);
97*7c568831SAndroid Build Coastguard Worker }
98*7c568831SAndroid Build Coastguard Worker 
99*7c568831SAndroid Build Coastguard Worker const char *include = "<?xml version='1.0'?>\n\
100*7c568831SAndroid Build Coastguard Worker <document xmlns:xi=\"http://www.w3.org/2003/XInclude\">\n\
101*7c568831SAndroid Build Coastguard Worker   <p>List of people:</p>\n\
102*7c568831SAndroid Build Coastguard Worker   <xi:include href=\"sql:select_name_from_people\"/>\n\
103*7c568831SAndroid Build Coastguard Worker </document>\n";
104*7c568831SAndroid Build Coastguard Worker 
main(void)105*7c568831SAndroid Build Coastguard Worker int main(void) {
106*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
107*7c568831SAndroid Build Coastguard Worker 
108*7c568831SAndroid Build Coastguard Worker     /*
109*7c568831SAndroid Build Coastguard Worker      * this initialize the library and check potential ABI mismatches
110*7c568831SAndroid Build Coastguard Worker      * between the version it was compiled for and the actual shared
111*7c568831SAndroid Build Coastguard Worker      * library used.
112*7c568831SAndroid Build Coastguard Worker      */
113*7c568831SAndroid Build Coastguard Worker     LIBXML_TEST_VERSION
114*7c568831SAndroid Build Coastguard Worker 
115*7c568831SAndroid Build Coastguard Worker     /*
116*7c568831SAndroid Build Coastguard Worker      * register the new I/O handlers
117*7c568831SAndroid Build Coastguard Worker      */
118*7c568831SAndroid Build Coastguard Worker     if (xmlRegisterInputCallbacks(sqlMatch, sqlOpen, sqlRead, sqlClose) < 0) {
119*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "failed to register SQL handler\n");
120*7c568831SAndroid Build Coastguard Worker 	exit(1);
121*7c568831SAndroid Build Coastguard Worker     }
122*7c568831SAndroid Build Coastguard Worker     /*
123*7c568831SAndroid Build Coastguard Worker      * parse include into a document
124*7c568831SAndroid Build Coastguard Worker      */
125*7c568831SAndroid Build Coastguard Worker     doc = xmlReadMemory(include, strlen(include), "include.xml", NULL, 0);
126*7c568831SAndroid Build Coastguard Worker     if (doc == NULL) {
127*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "failed to parse the including file\n");
128*7c568831SAndroid Build Coastguard Worker 	exit(1);
129*7c568831SAndroid Build Coastguard Worker     }
130*7c568831SAndroid Build Coastguard Worker 
131*7c568831SAndroid Build Coastguard Worker     /*
132*7c568831SAndroid Build Coastguard Worker      * apply the XInclude process, this should trigger the I/O just
133*7c568831SAndroid Build Coastguard Worker      * registered.
134*7c568831SAndroid Build Coastguard Worker      */
135*7c568831SAndroid Build Coastguard Worker     if (xmlXIncludeProcess(doc) <= 0) {
136*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "XInclude processing failed\n");
137*7c568831SAndroid Build Coastguard Worker 	exit(1);
138*7c568831SAndroid Build Coastguard Worker     }
139*7c568831SAndroid Build Coastguard Worker 
140*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
141*7c568831SAndroid Build Coastguard Worker     /*
142*7c568831SAndroid Build Coastguard Worker      * save the output for checking to stdout
143*7c568831SAndroid Build Coastguard Worker      */
144*7c568831SAndroid Build Coastguard Worker     xmlDocDump(stdout, doc);
145*7c568831SAndroid Build Coastguard Worker #endif
146*7c568831SAndroid Build Coastguard Worker 
147*7c568831SAndroid Build Coastguard Worker     /*
148*7c568831SAndroid Build Coastguard Worker      * Free the document
149*7c568831SAndroid Build Coastguard Worker      */
150*7c568831SAndroid Build Coastguard Worker     xmlFreeDoc(doc);
151*7c568831SAndroid Build Coastguard Worker 
152*7c568831SAndroid Build Coastguard Worker     return(0);
153*7c568831SAndroid Build Coastguard Worker }
154*7c568831SAndroid Build Coastguard Worker #else
main(void)155*7c568831SAndroid Build Coastguard Worker int main(void) {
156*7c568831SAndroid Build Coastguard Worker     fprintf(stderr, "XInclude support not compiled in\n");
157*7c568831SAndroid Build Coastguard Worker     return(0);
158*7c568831SAndroid Build Coastguard Worker }
159*7c568831SAndroid Build Coastguard Worker #endif
160