I'd really like to get this into the next beta.
so if someone could review/commit it that would
be great.

Cheers
Ian

Index: apr_xml.c
===================================================================
RCS file: /home/cvspublic/apr-util/xml/apr_xml.c,v
retrieving revision 1.21
diff -u -r1.21 apr_xml.c
--- apr_xml.c   2001/04/26 21:29:00     1.21
+++ apr_xml.c   2001/08/07 19:54:48
@@ -60,6 +60,7 @@
 #include "apr_want.h"
 
 #include "apr_xml.h"
+#include "apr_file_io.h"
 
 #include "apu_config.h"
 
@@ -479,7 +480,38 @@
     return errbuf;
 }
 
+APU_DECLARE(apr_status_t) apr_xml_parse_file(apr_pool_t *p,
apr_xml_parser**parser,apr_xml_doc **ppdoc, apr_file_t *xmlfd,int
buffer_length)
+{      
+    apr_status_t rv;
+    char *buffer;
+    apr_size_t length;
+
+    *parser = apr_xml_parser_create(p);
+    if (*parser == NULL ) {
+        /* FIXME: returnng  a error code would be nice, but we dont get
one ;( */
+        return APR_EGENERAL;
+    }
+    buffer = apr_palloc(p,buffer_length);
+    length=buffer_length;
+
+    rv = apr_file_read( xmlfd, buffer, &length);
+
+    while (rv == APR_SUCCESS ) {
+        rv = apr_xml_parser_feed(  *parser, buffer, length);
+        if (rv != APR_SUCCESS ) {
+            return rv;
+        }
 
+        length=buffer_length;
+        rv = apr_file_read( xmlfd, buffer, &length);
+    }
+    if ( rv != APR_EOF ) {
+        return rv;
+    }
+    rv = apr_xml_parser_done( *parser, ppdoc );
+    *parser=NULL;
+    return rv;
+}
 APU_DECLARE(void) apr_text_append(apr_pool_t * p, apr_text_header *hdr,
                                   const char *text)
 {


Index: apr_xml.h
===================================================================
RCS file: /home/cvspublic/apr-util/include/apr_xml.h,v
retrieving revision 1.13
diff -u -r1.13 apr_xml.h
--- apr_xml.h   2001/05/16 17:22:34     1.13
+++ apr_xml.h   2001/08/07 19:55:43
@@ -57,6 +57,7 @@
 
 #include "apr_pools.h"
 #include "apr_tables.h"
+#include "apr_file_io.h"
 
 #include "apu.h"
 
@@ -243,6 +244,17 @@
  * @return The new parser.
  */
 APU_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool);
+/**
+ * Parse a File, producing a xml_doc
+ * @param pool The pool for allocating the parse results.
+ * @param parser A pointer to *parser (needed so calling function can
get errors), will be set to NULL on successfull completion.
+ * @param pdoc A pointer to *apr_xml_doc (which has the parsed results
in it)
+ * @param xmlfd A file to read from.
+ * @param int Buffer length which would be suitable 
+ * @return Any errors found during parsing.
+ */
+APU_DECLARE(apr_status_t) apr_xml_parse_file(apr_pool_t *p,
apr_xml_parser**parser,apr_xml_doc **ppdoc, apr_file_t *xmlfd,int
buffer_length);
+
 
 /**
  * Feed input into the parser


Index: Makefile.in
===================================================================
RCS file: /home/cvspublic/apr-util/test/Makefile.in,v
retrieving revision 1.12
diff -u -r1.12 Makefile.in
--- Makefile.in 2001/08/01 20:32:59     1.12
+++ Makefile.in 2001/08/07 19:54:29
@@ -1,7 +1,7 @@
 [EMAIL PROTECTED]@
 INCLUDES=-I$(top_builddir)/include -I$(top_builddir)/include/private
[EMAIL PROTECTED]@/include
 TARGETS =
-PROGRAMS = testdbm testdate testmd4
+PROGRAMS = testdbm testdate testmd4 testxml
 
 # bring in rules.mk for standard functionality
 @INCLUDE_RULES@
@@ -17,6 +17,11 @@
 testdate_LDADD =  ../libaprutil.la @APR_SOURCE_DIR@/libapr.la
 testdate: $(testdate_OBJECTS) $(testdate_LDADD)
        $(LINK) $(testdate_OBJECTS) $(testdate_LDADD) $(LIBS)
+
+testxml_OBJECTS = testxml.lo
+testxml_LDADD =  ../libaprutil.la @APR_SOURCE_DIR@/libapr.la
../xml/expat/lib/libexpat.la
+testxml: $(testxml_OBJECTS) $(testxml_LDADD)
+       $(LINK) $(testxml_OBJECTS) $(testxml_LDADD) $(LIBS)
 
 testmd4_OBJECTS = testmd4.lo
 testmd4_LDADD =  ../libaprutil.la @APR_SOURCE_DIR@/libapr.la

-- 
Ian Holsman          [EMAIL PROTECTED]
Performance Measurement & Analysis
CNET Networks   -   (415) 364-8608
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

#include "apr.h"
#include "apr_general.h"
#include "apr_xml.h"

static const char *progname;
static const char *usage = "%s [xmlfile]\nIt will create a dummy XML file if none is supplied";
/*
 * If our platform knows about the tmpnam() external buffer size, create
 * a buffer to pass in.  This is needed in a threaded environment, or
 * one that thinks it is (like HP-UX).
 */

#ifdef L_tmpnam
static char tname_buf[L_tmpnam];
#else
static char *tname_buf = NULL;
#endif

static apr_status_t create_dummy_file_error( apr_pool_t *p, apr_file_t**fd)
{
    apr_status_t rv;
    char*tmpfile;
    int i;
    apr_off_t off=0L;
    tmpfile= tmpnam(tname_buf);

    if ((tmpfile== NULL) || (*tmpfile== '\0')) {
        fprintf(stderr, "unable to generate temporary filename\n");
        if (errno == 0) {
            errno = ENOENT;
        }
        perror("tmpnam");
        return APR_EGENERAL;
    }
    rv = apr_file_open( fd, tmpfile, 
        APR_CREATE|APR_TRUNCATE|APR_DELONCLOSE|APR_READ|APR_WRITE|APR_EXCL,
        APR_OS_DEFAULT,p);

    if (rv != APR_SUCCESS)
        return rv;
    rv = apr_file_puts( "<?xml version=\"1.0\" ?>\n<maryx><had a=\"little\"/><lamb its='fleece was white as snow' />\n" , *fd );
    if (rv != APR_SUCCESS)
        return rv;

    for (i=0;i<5000;i++) {
        rv = apr_file_puts( "<hmm roast=\"lamb\" for=\"dinner\">yummy</hmm>\n" , *fd );
        if (rv != APR_SUCCESS)
            return rv;
    }
    rv = apr_file_puts( "</mary>\n" , *fd );
    if (rv != APR_SUCCESS)
        return rv;

    rv = apr_file_seek( *fd,APR_SET,&off );
    return rv;
}

static apr_status_t create_dummy_file( apr_pool_t *p, apr_file_t**fd)
{
    apr_status_t rv;
    char*tmpfile;
    int i;
    apr_off_t off=0L;
    tmpfile= tmpnam(tname_buf);

    if ((tmpfile== NULL) || (*tmpfile== '\0')) {
        fprintf(stderr, "unable to generate temporary filename\n");
        if (errno == 0) {
            errno = ENOENT;
        }
        perror("tmpnam");
        return APR_EGENERAL;
    }
    rv = apr_file_open( fd, tmpfile, 
        APR_CREATE|APR_TRUNCATE|APR_DELONCLOSE|APR_READ|APR_WRITE|APR_EXCL,
        APR_OS_DEFAULT,p);

    if (rv != APR_SUCCESS)
        return rv;
    rv = apr_file_puts( "<?xml version=\"1.0\" ?>\n<mary><had a=\"little\"/><lamb its='fleece was white as snow' />\n" , *fd );
    if (rv != APR_SUCCESS)
        return rv;

    for (i=0;i<5000;i++) {
        rv = apr_file_puts( "<hmm roast=\"lamb\" for=\"dinner\">yummy</hmm>\n" , *fd );
        if (rv != APR_SUCCESS)
            return rv;
    }
    rv = apr_file_puts( "</mary>\n" , *fd );
    if (rv != APR_SUCCESS)
        return rv;

    rv = apr_file_seek( *fd,APR_SET,&off );
    return rv;
}
static void dump_xml( apr_xml_elem *e, int level ) 
{
    apr_xml_attr*a;
    apr_xml_elem*ec;

    printf("%d: element %s\n",level, e->name);
    if (e->attr) {
        a=e->attr;
        printf("%d:\tattrs\t",level);
        while(a) {
            printf("%s=%s\t",a->name,a->value);
            a=a->next;
        }
        printf("\n");
    }
    if (e->first_child) {
        ec = e->first_child;
        while (ec) {
            dump_xml( ec,level+1);
            ec = ec->next;
        }
    }
}
static void oops(const char *s1, const char *s2)
{
    if (progname)
        fprintf(stderr, "%s: ", progname);
    fprintf(stderr, s1, s2);
    if (errno > 0 && errno < sys_nerr)
        fprintf(stderr, " (%s)", sys_errlist[errno]);
    fprintf(stderr, "\n");
    exit(1);
}
int main(int argc, const char * const * argv)
{
    apr_pool_t *pool;
    apr_file_t *fd;
    apr_xml_parser*parser;
    apr_xml_doc*doc;
    apr_status_t rv;
    char errbuf[2000];
    char errbufXML[2000];

    (void) apr_initialize();
    apr_pool_create(&pool, NULL);
    progname =argv[0];
    if (argc == 1 ) {
        rv = create_dummy_file(pool, &fd);
        if (rv != APR_SUCCESS) {
            oops("cannot create dummy file","oops");
        }
    }
    else {
        if (argc == 2 ) {
            rv = apr_file_open(&fd,argv[1], APR_READ, APR_OS_DEFAULT, pool);
            if (rv != APR_SUCCESS) {
                oops("cannot open: %s", argv[1]);
            }
        }
        else {
            oops("usage: %s", usage);
        }
    }
   rv = apr_xml_parse_file(pool,&parser,&doc,fd,2000);
   if (rv != APR_SUCCESS) {
        fprintf(stderr, "APR Error %s\nXML Error: %s\n",
            apr_strerror( rv ,errbuf,sizeof(errbuf)),
            apr_xml_parser_geterror( parser,errbufXML,sizeof(errbufXML)) );
        return rv;
   }
   dump_xml( doc->root,0);
   apr_file_close(fd);
   if (argc==1) {
       rv = create_dummy_file_error(pool, &fd);
       if (rv != APR_SUCCESS) {
            oops("cannot create error dummy file","oops");
       }
       rv = apr_xml_parse_file(pool,&parser,&doc,fd,2000);
       if (rv != APR_SUCCESS) {
            fprintf(stdout, "APR Error %s\nXML Error: %s (EXPECTED ERROR CONDITION) This is good\n",
                apr_strerror( rv ,errbuf,sizeof(errbuf)),
                apr_xml_parser_geterror( parser,errbufXML,sizeof(errbufXML)) );
       }
       else  {
            fprintf(stderr, "Expected an error, but didn't get one ;( ");
            return APR_EGENERAL;
       }
   }
   apr_pool_destroy(pool);
   apr_terminate();
   return rv;
}

 

Reply via email to