blob: ad72441f9a8923110a6cd4777c8554bb0e231e04 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr.h"
#if APU_USE_LIBXML2
#include "apr_xml.h"
#include <libxml/parser.h>
#include <libxml/xmlerror.h>
typedef xmlParserCtxtPtr XML_Parser;
typedef xmlParserErrors XML_Error;
#include "apr_xml_internal.h"
static apr_status_t cleanup_parser(void *ctx)
{
apr_xml_parser *parser = ctx;
xmlFreeParserCtxt(parser->xp);
parser->xp = NULL;
return APR_SUCCESS;
}
static int libxml2_parse(apr_xml_parser* parser, const char* data,
apr_size_t sz, int final)
{
parser->xp_err = xmlParseChunk(parser->xp, data, sz, final);
if (parser->xp_err != 0) {
xmlErrorPtr errptr = xmlCtxtGetLastError(parser->xp);
parser->xp_msg = errptr->message;
/* this misnomer is used as a test for (any) parser error. */
parser->error = APR_XML_ERROR_EXPAT;
}
return parser->xp_err;
}
static XMLParserImpl xml_parser_libxml2 = {
libxml2_parse,
cleanup_parser
};
static const char APR_KW_DAV[] = { 0x44, 0x41, 0x56, 0x3A, '\0' };
XMLParserImpl* apr_xml_get_parser_impl(void)
{
return &xml_parser_libxml2;
}
apr_xml_parser* apr_xml_parser_create_internal(apr_pool_t *pool,
void *start_func, void *end_func, void *cdata_func)
{
apr_xml_parser *parser = apr_pcalloc(pool, sizeof(*parser));
/* FIXME: This is a mismatch. We should create a single global
* sax instance and re-use it for every parser. That means we
* need an up-front initialisation function.
*/
xmlSAXHandlerPtr sax = apr_pcalloc(pool, sizeof(xmlSAXHandler));
sax->startElement = start_func;
sax->endElement = end_func;
sax->characters = cdata_func;
sax->initialized = 1;
parser->impl = apr_xml_get_parser_impl();
parser->p = pool;
parser->doc = apr_pcalloc(pool, sizeof(*parser->doc));
parser->doc->namespaces = apr_array_make(pool, 5, sizeof(const char *));
/* ### is there a way to avoid hard-coding this? */
apr_xml_insert_uri(parser->doc->namespaces, APR_KW_DAV);
parser->xp = xmlCreatePushParserCtxt(sax, parser, NULL, 0, NULL);
if (parser->xp == NULL) {
(*apr_pool_abort_get(pool))(APR_ENOMEM);
return NULL;
}
apr_pool_cleanup_register(pool, parser, cleanup_parser,
apr_pool_cleanup_null);
return parser;
}
#endif