/* Copyright 2006 Joachim Zobel . * * Licensed 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. */ /* * The advantage of SAX buckets is that you are not trapped in a callback * anymore. Event handling can be done from the filters brigade loop. * The functions below are intended to help with this. */ /* XXX * Taking Advantage of SAX buckets * Loop processing replaces callback processing * Needed: * inspect-Functions to check for tags and namespaces * A way to bridge the brigade gap * A stack of buckets kept for processing * A function to read tag content? * * Keep stops brigade passing * So we can go back in the bucket chain */ #include "apr.h" #include "apr_general.h" //#include "apr_tables.h" #ifndef XML_CHAR_T #define XML_CHAR_T typedef char xml_char_t ; #endif /***************************************************************************** * Functions and Macros *****************************************************************************/ #define BUCKET_IS_SAX(b) (strcmp(b->type->name, "SAX") == 0) /** * Returns the buckets type assuming it is a SAX bucket * @param b - The SAX bucket that will be checked * @return The buckets type */ #define sax_inspect_which(b) (((bucket_sax *)(b)->data)->which) /** * Returns the buckets event assuming it is a SAX bucket * @param b - The SAX bucket that will be checked * @return The buckets event */ #define sax_inspect_event(b) (((bucket_sax *)(b)->data)->event) /** * Checks if a bucket belongs to the namespace identified by uri and prefix. If both * are given both must match. Note that an end ns bucket only has a prefix. * @param b - The SAX bucket that will be checked * @param uri - The namespace (must be a unified name), NULL means wildcard * @param prefix - The namespace by prefix (must be a unified name), NULL means wildcard * @param check_attr - if this is set, the attribute namespaces will be checked. * @return The buckets start/end id */ se_id_t sax_inspect_ns(apr_bucket *b, const xml_char_t *uri, const xml_char_t *prefix, int check_attr) ; /** * Checks if a bucket is a matching end. * @param b - The bucket that will be checked * @param start - The start buckets se_id * @return !=0, if the bucket matches */ int sax_inspect_end(apr_bucket *b, se_id_t start) ; /***************************************************************************** * The start bucket stack. *****************************************************************************/ /** * We can not search forward in the bucket stream * since we may reach the end of the current brigade. * We can however turn passing brigades off and do * the processing when the end tag is reached. The * start stack exists to keep track of the start * buckets of the tags we are processing this way. */ typedef apr_array_header_t start_stack_t ; /** * Init the start_stack_t * @param ss - The start bucket stack * @return true/false */ #define sax_start_stack_init(pool) apr_array_make(pool, 6, sizeof(apr_bucket_t *)) /** * Do we need to skip ap_pass_brigade? * @param ss - The start bucket stack * @return true/false */ #define sax_start_stack_keep(ss) (fss->nelts) /** * Get the top element from the process stack without popping it * @param p - The process stack * @return A pointer to the top element */ #define sax_start_stack_top(ss) ((ss->nelts>0)?((apr_bucket_t *)ss->elts+ss->nelts-1):NULL) /** * Get the content of a tag. * @param fbuf - The content is written to this * @param s - The start bucket * @param e - The end bucket * @param encoded - Shall the return be XML encoded * @return The number of character written to fbuf */ apr_off_t sax_extract_tag_content(frag_buffer_t *fbuf, apr_bucket *s, apr_bucket *e, int encoded) ;