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