Blame doc/examples/parse4.c

Packit 423ecb
/**
Packit 423ecb
 * section: Parsing
Packit 423ecb
 * synopsis: Parse an XML document chunk by chunk to a tree and free it
Packit 423ecb
 * purpose: Demonstrate the use of xmlCreatePushParserCtxt() and
Packit 423ecb
 *          xmlParseChunk() to read an XML file progressively
Packit 423ecb
 *          into a tree and and xmlFreeDoc() to free the resulting tree
Packit 423ecb
 * usage: parse4 test3.xml
Packit 423ecb
 * test: parse4 test3.xml
Packit 423ecb
 * author: Daniel Veillard
Packit 423ecb
 * copy: see Copyright for the status of this software.
Packit 423ecb
 */
Packit 423ecb
Packit 423ecb
#include <stdio.h>
Packit 423ecb
#include <libxml/parser.h>
Packit 423ecb
#include <libxml/tree.h>
Packit 423ecb
Packit 423ecb
#ifdef LIBXML_PUSH_ENABLED
Packit 423ecb
static FILE *desc;
Packit 423ecb
Packit 423ecb
/**
Packit 423ecb
 * readPacket:
Packit 423ecb
 * @mem: array to store the packet
Packit 423ecb
 * @size: the packet size
Packit 423ecb
 *
Packit 423ecb
 * read at most @size bytes from the document and store it in @mem
Packit 423ecb
 *
Packit 423ecb
 * Returns the number of bytes read
Packit 423ecb
 */
Packit 423ecb
static int
Packit 423ecb
readPacket(char *mem, int size) {
Packit 423ecb
    int res;
Packit 423ecb
Packit 423ecb
    res = fread(mem, 1, size, desc);
Packit 423ecb
    return(res);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
/**
Packit 423ecb
 * example4Func:
Packit 423ecb
 * @filename: a filename or an URL
Packit 423ecb
 *
Packit 423ecb
 * Parse the resource and free the resulting tree
Packit 423ecb
 */
Packit 423ecb
static void
Packit 423ecb
example4Func(const char *filename) {
Packit 423ecb
    xmlParserCtxtPtr ctxt;
Packit 423ecb
    char chars[4];
Packit 423ecb
    xmlDocPtr doc; /* the resulting document tree */
Packit 423ecb
    int res;
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Read a few first byte to check the input used for the
Packit 423ecb
     * encoding detection at the parser level.
Packit 423ecb
     */
Packit 423ecb
    res = readPacket(chars, 4);
Packit 423ecb
    if (res <= 0) {
Packit 423ecb
        fprintf(stderr, "Failed to parse %s\n", filename);
Packit 423ecb
	return;
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Create a progressive parsing context, the 2 first arguments
Packit 423ecb
     * are not used since we want to build a tree and not use a SAX
Packit 423ecb
     * parsing interface. We also pass the first bytes of the document
Packit 423ecb
     * to allow encoding detection when creating the parser but this
Packit 423ecb
     * is optional.
Packit 423ecb
     */
Packit 423ecb
    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
Packit 423ecb
                                   chars, res, filename);
Packit 423ecb
    if (ctxt == NULL) {
Packit 423ecb
        fprintf(stderr, "Failed to create parser context !\n");
Packit 423ecb
	return;
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * loop on the input getting the document data, of course 4 bytes
Packit 423ecb
     * at a time is not realistic but allows to verify testing on small
Packit 423ecb
     * documents.
Packit 423ecb
     */
Packit 423ecb
    while ((res = readPacket(chars, 4)) > 0) {
Packit 423ecb
        xmlParseChunk(ctxt, chars, res, 0);
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * there is no more input, indicate the parsing is finished.
Packit 423ecb
     */
Packit 423ecb
    xmlParseChunk(ctxt, chars, 0, 1);
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * collect the document back and if it was wellformed
Packit 423ecb
     * and destroy the parser context.
Packit 423ecb
     */
Packit 423ecb
    doc = ctxt->myDoc;
Packit 423ecb
    res = ctxt->wellFormed;
Packit 423ecb
    xmlFreeParserCtxt(ctxt);
Packit 423ecb
Packit 423ecb
    if (!res) {
Packit 423ecb
        fprintf(stderr, "Failed to parse %s\n", filename);
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * since we don't use the document, destroy it now.
Packit 423ecb
     */
Packit 423ecb
    xmlFreeDoc(doc);
Packit 423ecb
}
Packit 423ecb
Packit 423ecb
int main(int argc, char **argv) {
Packit 423ecb
    if (argc != 2)
Packit 423ecb
        return(1);
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * this initialize the library and check potential ABI mismatches
Packit 423ecb
     * between the version it was compiled for and the actual shared
Packit 423ecb
     * library used.
Packit 423ecb
     */
Packit 423ecb
    LIBXML_TEST_VERSION
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * simulate a progressive parsing using the input file.
Packit 423ecb
     */
Packit 423ecb
    desc = fopen(argv[1], "rb");
Packit 423ecb
    if (desc != NULL) {
Packit 423ecb
	example4Func(argv[1]);
Packit 423ecb
	fclose(desc);
Packit 423ecb
    } else {
Packit 423ecb
        fprintf(stderr, "Failed to parse %s\n", argv[1]);
Packit 423ecb
    }
Packit 423ecb
Packit 423ecb
    /*
Packit 423ecb
     * Cleanup function for the XML library.
Packit 423ecb
     */
Packit 423ecb
    xmlCleanupParser();
Packit 423ecb
    /*
Packit 423ecb
     * this is to debug memory for regression tests
Packit 423ecb
     */
Packit 423ecb
    xmlMemoryDump();
Packit 423ecb
    return(0);
Packit 423ecb
}
Packit 423ecb
#else /* ! LIBXML_PUSH_ENABLED */
Packit 423ecb
int main(int argc, char **argv) {
Packit 423ecb
    fprintf(stderr, "Library not compiled with push parser support\n");
Packit 423ecb
    return(1);
Packit 423ecb
}
Packit 423ecb
#endif