/* 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))) /* * sax_extract_next_attr */ 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_inspect_se_id */ se_id_t sax_inspect_se_id(apr_bucket *b) { bucket_sax *bs = b->data ; #define SE_ID_BY_TYPE(type) {type *e = bs->event; return e->se_id;} switch (bs->which) { case START_ELT: SE_ID_BY_TYPE(start_elt_t) case END_ELT: SE_ID_BY_TYPE(end_elt_t) case START_NS: SE_ID_BY_TYPE(start_ns_t) case END_NS: SE_ID_BY_TYPE(end_ns_t) default: return 0; } } /* * sax_extract_tag_content */ apr_off_t sax_extract_tag_content(frag_buffer_t *fbuf, apr_bucket *s, apr_bucket *e, int encoded, int delete) { 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 ; if (delete) { apr_bucket_delete(cur) ; } } } return rv ; } /* * sax_pop_attr */ const xml_char_t *sax_pop_attr(apr_bucket *b, const xml_char_t *name, const xml_char_t *uri, const xml_char_t *prefix) { ap_assert(sax_inspect_which(b) == START_ELT); start_elt_t *se = sax_inspect_event(b); attr_t *attr = se->atts; while (attr = sax_extract_next_attr(attr, uri, prefix), attr) { if (strcmp(attr->name.name,name) == 0) { const xml_char_t *value = attr->value; int cnt; for (cnt=1; attr[cnt].name.name; cnt++) {}; // The trailing NULL attr is also moved memmove(attr, (attr+1), sizeof(*attr)*cnt); return value; } attr++; } return NULL; }