/* 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 #include 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