/* 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. */ #include #include #include #include #include "frag_buffer.h" #include "buckets_sax.h" #include "sax_util.h" // Equal with NULL as wildcard // #define EQUAL_WC(x, y) (!(x) || !(y) || ((x) == (y))) // Equal with a left NULL as wildcard #define EQUAL_WC_L(x, y) (!(x) || ((x) == (y))) /** * Extract the next attribute for the given ns * @param attr - a (start elements) array off attributes * @param uri - the unified ns uri. NULL is wildcard * @param prefix - the unified ns prefix. NULL is wildcard * @return the pointer to the next attribute, NULL if none was found. */ static attr_t *sax_extract_next_attr(attr_t *attr, const xml_char_t *uri, const xml_char_t *prefix) { while (attr->name.name && !EQUAL_WC_L(uri, attr->name.uri) && !EQUAL_WC_L(prefix, attr->name.prefix) ) { attr++ ; } // No name means we reached the terminator return attr->name.name?attr:NULL; } /* * sax_inspect_ns */ se_id_t sax_inspect_ns(apr_bucket *b, const xml_char_t *uri, const xml_char_t *prefix, int check_attr) { bucket_sax *bs = b->data ; se_id_t rv = 0 ; const xml_char_t *b_uri = NULL ; const xml_char_t *b_prefix = NULL ; attr_t *attr = NULL ; switch (bs->which) { case START_ELT: { start_elt_t *se = bs->event ; b_uri = se->name.uri ; b_prefix= se->name.prefix ; attr = se->atts ; rv = se->se_id ; } break ; case END_ELT: { end_elt_t *ee = bs->event ; b_uri = ee->name.uri ; b_prefix= ee->name.prefix ; rv = ee->se_id ; } break ; case START_NS: { start_ns_t *sn = bs->event ; b_uri = sn->uri ; b_prefix= sn->prefix ; rv = sn->se_id ; } break ; case END_NS: { end_ns_t *en = bs->event ; b_prefix= en->prefix ; rv = en->se_id ; } break ; default: break ; } // Check the namespace if ( EQUAL_WC_L(uri, b_uri) && EQUAL_WC_L(prefix, b_prefix) ) { return rv ; } else if (check_attr && attr && sax_extract_next_attr(attr, uri, prefix)) { return rv ; } else { return 0 ; } } /* * sax_inspect_end */ int sax_inspect_end(apr_bucket *b, se_id_t start) { bucket_sax *bs = b->data ; int rv = 0 ; switch (bs->which) { case END_ELT: { end_elt_t *ee = bs->event ; rv = (-start == ee->se_id) ; } break ; case END_NS: { end_ns_t *en = bs->event ; rv = (-start == en->se_id) ; } break ; default: break ; } return rv ; } /* * sax_extract_tag_content */ apr_off_t sax_extract_tag_content(frag_buffer_t *fbuf, apr_bucket *s, apr_bucket *e, int encoded) { apr_bucket *cur = NULL ; apr_off_t rv = 0 ; // We walk the content between the tags for ( cur=APR_BUCKET_NEXT(s) ; cur=APR_BUCKET_NEXT(cur) ; APR_BUCKET_NEXT(cur)!=e // handle empty buckets && cur != e) { if (sax_inspect_which(cur) == CHARACTER) { character_t *c = sax_inspect_event(cur) ; frag_write(fbuf, c->text, c->len) ; rv += c->len ; } } return rv ; }