xref: /aosp_15_r20/external/libxml2/example/parse4.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /**
2*7c568831SAndroid Build Coastguard Worker  * section: Parsing
3*7c568831SAndroid Build Coastguard Worker  * synopsis: Parse an XML document chunk by chunk to a tree and free it
4*7c568831SAndroid Build Coastguard Worker  * purpose: Demonstrate the use of xmlCreatePushParserCtxt() and
5*7c568831SAndroid Build Coastguard Worker  *          xmlParseChunk() to read an XML file progressively
6*7c568831SAndroid Build Coastguard Worker  *          into a tree and xmlFreeDoc() to free the resulting tree
7*7c568831SAndroid Build Coastguard Worker  * usage: parse4 test3.xml
8*7c568831SAndroid Build Coastguard Worker  * test: parse4 test3.xml
9*7c568831SAndroid Build Coastguard Worker  * author: Daniel Veillard
10*7c568831SAndroid Build Coastguard Worker  * copy: see Copyright for the status of this software.
11*7c568831SAndroid Build Coastguard Worker  */
12*7c568831SAndroid Build Coastguard Worker 
13*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
14*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
15*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
16*7c568831SAndroid Build Coastguard Worker 
17*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
18*7c568831SAndroid Build Coastguard Worker static FILE *desc;
19*7c568831SAndroid Build Coastguard Worker 
20*7c568831SAndroid Build Coastguard Worker /**
21*7c568831SAndroid Build Coastguard Worker  * readPacket:
22*7c568831SAndroid Build Coastguard Worker  * @mem: array to store the packet
23*7c568831SAndroid Build Coastguard Worker  * @size: the packet size
24*7c568831SAndroid Build Coastguard Worker  *
25*7c568831SAndroid Build Coastguard Worker  * read at most @size bytes from the document and store it in @mem
26*7c568831SAndroid Build Coastguard Worker  *
27*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes read
28*7c568831SAndroid Build Coastguard Worker  */
29*7c568831SAndroid Build Coastguard Worker static int
readPacket(char * mem,int size)30*7c568831SAndroid Build Coastguard Worker readPacket(char *mem, int size) {
31*7c568831SAndroid Build Coastguard Worker     int res;
32*7c568831SAndroid Build Coastguard Worker 
33*7c568831SAndroid Build Coastguard Worker     res = fread(mem, 1, size, desc);
34*7c568831SAndroid Build Coastguard Worker     return(res);
35*7c568831SAndroid Build Coastguard Worker }
36*7c568831SAndroid Build Coastguard Worker 
37*7c568831SAndroid Build Coastguard Worker /**
38*7c568831SAndroid Build Coastguard Worker  * example4Func:
39*7c568831SAndroid Build Coastguard Worker  * @filename: a filename or an URL
40*7c568831SAndroid Build Coastguard Worker  *
41*7c568831SAndroid Build Coastguard Worker  * Parse the resource and free the resulting tree
42*7c568831SAndroid Build Coastguard Worker  */
43*7c568831SAndroid Build Coastguard Worker static void
example4Func(const char * filename)44*7c568831SAndroid Build Coastguard Worker example4Func(const char *filename) {
45*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
46*7c568831SAndroid Build Coastguard Worker     char chars[4];
47*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc; /* the resulting document tree */
48*7c568831SAndroid Build Coastguard Worker     int res;
49*7c568831SAndroid Build Coastguard Worker 
50*7c568831SAndroid Build Coastguard Worker     /*
51*7c568831SAndroid Build Coastguard Worker      * Read a few first byte to check the input used for the
52*7c568831SAndroid Build Coastguard Worker      * encoding detection at the parser level.
53*7c568831SAndroid Build Coastguard Worker      */
54*7c568831SAndroid Build Coastguard Worker     res = readPacket(chars, 4);
55*7c568831SAndroid Build Coastguard Worker     if (res <= 0) {
56*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to parse %s\n", filename);
57*7c568831SAndroid Build Coastguard Worker 	return;
58*7c568831SAndroid Build Coastguard Worker     }
59*7c568831SAndroid Build Coastguard Worker 
60*7c568831SAndroid Build Coastguard Worker     /*
61*7c568831SAndroid Build Coastguard Worker      * Create a progressive parsing context, the 2 first arguments
62*7c568831SAndroid Build Coastguard Worker      * are not used since we want to build a tree and not use a SAX
63*7c568831SAndroid Build Coastguard Worker      * parsing interface. We also pass the first bytes of the document
64*7c568831SAndroid Build Coastguard Worker      * to allow encoding detection when creating the parser but this
65*7c568831SAndroid Build Coastguard Worker      * is optional.
66*7c568831SAndroid Build Coastguard Worker      */
67*7c568831SAndroid Build Coastguard Worker     ctxt = xmlCreatePushParserCtxt(NULL, NULL,
68*7c568831SAndroid Build Coastguard Worker                                    chars, res, filename);
69*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) {
70*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to create parser context !\n");
71*7c568831SAndroid Build Coastguard Worker 	return;
72*7c568831SAndroid Build Coastguard Worker     }
73*7c568831SAndroid Build Coastguard Worker 
74*7c568831SAndroid Build Coastguard Worker     /*
75*7c568831SAndroid Build Coastguard Worker      * loop on the input getting the document data, of course 4 bytes
76*7c568831SAndroid Build Coastguard Worker      * at a time is not realistic but allows to verify testing on small
77*7c568831SAndroid Build Coastguard Worker      * documents.
78*7c568831SAndroid Build Coastguard Worker      */
79*7c568831SAndroid Build Coastguard Worker     while ((res = readPacket(chars, 4)) > 0) {
80*7c568831SAndroid Build Coastguard Worker         xmlParseChunk(ctxt, chars, res, 0);
81*7c568831SAndroid Build Coastguard Worker     }
82*7c568831SAndroid Build Coastguard Worker 
83*7c568831SAndroid Build Coastguard Worker     /*
84*7c568831SAndroid Build Coastguard Worker      * there is no more input, indicate the parsing is finished.
85*7c568831SAndroid Build Coastguard Worker      */
86*7c568831SAndroid Build Coastguard Worker     xmlParseChunk(ctxt, chars, 0, 1);
87*7c568831SAndroid Build Coastguard Worker 
88*7c568831SAndroid Build Coastguard Worker     /*
89*7c568831SAndroid Build Coastguard Worker      * collect the document back and if it was wellformed
90*7c568831SAndroid Build Coastguard Worker      * and destroy the parser context.
91*7c568831SAndroid Build Coastguard Worker      */
92*7c568831SAndroid Build Coastguard Worker     doc = ctxt->myDoc;
93*7c568831SAndroid Build Coastguard Worker     res = ctxt->wellFormed;
94*7c568831SAndroid Build Coastguard Worker     xmlFreeParserCtxt(ctxt);
95*7c568831SAndroid Build Coastguard Worker 
96*7c568831SAndroid Build Coastguard Worker     if (!res) {
97*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to parse %s\n", filename);
98*7c568831SAndroid Build Coastguard Worker     }
99*7c568831SAndroid Build Coastguard Worker 
100*7c568831SAndroid Build Coastguard Worker     /*
101*7c568831SAndroid Build Coastguard Worker      * since we don't use the document, destroy it now.
102*7c568831SAndroid Build Coastguard Worker      */
103*7c568831SAndroid Build Coastguard Worker     xmlFreeDoc(doc);
104*7c568831SAndroid Build Coastguard Worker }
105*7c568831SAndroid Build Coastguard Worker 
main(int argc,char ** argv)106*7c568831SAndroid Build Coastguard Worker int main(int argc, char **argv) {
107*7c568831SAndroid Build Coastguard Worker     if (argc != 2)
108*7c568831SAndroid Build Coastguard Worker         return(1);
109*7c568831SAndroid Build Coastguard Worker 
110*7c568831SAndroid Build Coastguard Worker     /*
111*7c568831SAndroid Build Coastguard Worker      * this initialize the library and check potential ABI mismatches
112*7c568831SAndroid Build Coastguard Worker      * between the version it was compiled for and the actual shared
113*7c568831SAndroid Build Coastguard Worker      * library used.
114*7c568831SAndroid Build Coastguard Worker      */
115*7c568831SAndroid Build Coastguard Worker     LIBXML_TEST_VERSION
116*7c568831SAndroid Build Coastguard Worker 
117*7c568831SAndroid Build Coastguard Worker     /*
118*7c568831SAndroid Build Coastguard Worker      * simulate a progressive parsing using the input file.
119*7c568831SAndroid Build Coastguard Worker      */
120*7c568831SAndroid Build Coastguard Worker     desc = fopen(argv[1], "rb");
121*7c568831SAndroid Build Coastguard Worker     if (desc != NULL) {
122*7c568831SAndroid Build Coastguard Worker 	example4Func(argv[1]);
123*7c568831SAndroid Build Coastguard Worker 	fclose(desc);
124*7c568831SAndroid Build Coastguard Worker     } else {
125*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to parse %s\n", argv[1]);
126*7c568831SAndroid Build Coastguard Worker     }
127*7c568831SAndroid Build Coastguard Worker 
128*7c568831SAndroid Build Coastguard Worker     return(0);
129*7c568831SAndroid Build Coastguard Worker }
130*7c568831SAndroid Build Coastguard Worker #else /* ! LIBXML_PUSH_ENABLED */
main(void)131*7c568831SAndroid Build Coastguard Worker int main(void) {
132*7c568831SAndroid Build Coastguard Worker     fprintf(stderr, "Library not compiled with push parser support\n");
133*7c568831SAndroid Build Coastguard Worker     return(0);
134*7c568831SAndroid Build Coastguard Worker }
135*7c568831SAndroid Build Coastguard Worker #endif
136