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