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