Sat, 12 Jan 2013 14:00:47 +0100
cleaning up resources after requests
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2013 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "../ucx/string.h" #include "../ucx/dlist.h" #include "../util/pool.h" #include "saxhandler.h" using namespace std; void xstack_push(UcxDlist **stack, XmlElement *elm) { *stack = ucx_dlist_prepend(*stack, elm); } XmlElement* xstack_pop(UcxDlist **stack) { if(*stack == NULL) { return NULL; } XmlElement* ret = (XmlElement*)(*stack)->data; UcxDlist *newstack = ucx_dlist_remove(*stack, *stack); *stack = newstack; return ret; } PropfindHandler::PropfindHandler(PropfindRequest *rq, pool_handle_t *p) { davrq = rq; pool = p; davPropTag = false; property = NULL; } PropfindHandler::~PropfindHandler() { } void PropfindHandler::startElement( const XMLCh *const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) { davPropTag = true; } else if(davPropTag && property == NULL) { //property = (DavProperty*)pool_malloc(pool, sizeof(DavProperty)); property = (DavProperty*)malloc(sizeof(DavProperty)); /* Ultra TODO: pool_malloc makes big mistakes!! */ size_t nslen = strlen(ns); size_t namelen = strlen(name); if(nslen > 0) { property->xmlns = (char*)pool_malloc(pool, nslen + 1); property->xmlns[nslen] = 0; memcpy(property->xmlns, ns, nslen); } else { property->xmlns = NULL; } if(namelen > 0) { property->name = (char*)pool_malloc(pool, namelen + 1); property->name[namelen] = 0; memcpy(property->name, name, namelen); } else { property->name = NULL; } } XMLString::release(&ns); XMLString::release(&name); } void PropfindHandler::endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(property != NULL) { const char *xmlns = (property->xmlns) ? property->xmlns : ""; if(!strcmp(ns, xmlns) && !strcmp(name, property->name)) { // add property to DavRequest UcxDlist *elm = (UcxDlist*)pool_malloc(pool, sizeof(UcxDlist)); elm->prev = NULL; elm->next = NULL; elm->data = property; //printf("saxhandler: add property: {%s}\n", property->name); davrq->properties = ucx_dlist_concat(davrq->properties, elm); property = NULL; } } XMLString::release(&ns); XMLString::release(&name); } void PropfindHandler::startDocument() { } void PropfindHandler::endDocument() { } /************* PropPatch Handler **************/ ProppatchHandler::ProppatchHandler(ProppatchRequest *rq, pool_handle_t *p) { davrq = rq; pool = p; davPropTag = false; rootElement = NULL; xmlStack = NULL; newElement = NULL; updateMode = -1; } ProppatchHandler::~ProppatchHandler() { } void ProppatchHandler::startElement( const XMLCh *const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) { updateMode = 0; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) { updateMode = 1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) { davPropTag = true; } else if(davPropTag) { newElement = (XmlElement*)pool_calloc(pool, 1, sizeof(XmlElement)); newElement->name = sstr(pool_strdup(pool, name)); newElement->xmlns = xmlnsmap_put(davrq->nsmap, ns); /* * the xml stack manages the xml hierarchy * new elements will be added to the top element on the stack */ XmlElement *currentElm = XSTACK_CUR(); if(currentElm) { xmlelm_add_child(currentElm, newElement); } /* newElement is now the parent for future elements */ XSTACK_PUSH(newElement); /* if the root element isn't set, the first new element is the root */ if(!rootElement) { rootElement = newElement; } } XMLString::release(&ns); XMLString::release(&name); } void ProppatchHandler::endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) { updateMode = -1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) { updateMode = -1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) { davPropTag = false; } else if(davPropTag) { XmlElement *elm = XSTACK_POP(); if(xmlStack == NULL) { /* property complete */ /* XmlElement *r = rootElement; printf("<%s>\n", sstrdup(r->name).ptr); printf("%s\n", r->content); printf("</%s>\n", sstrdup(r->name).ptr); */ /* add the property to the proppatch request */ switch(updateMode) { case 0: { davrq->setProps = ucx_dlist_append( davrq->setProps, rootElement); break; } case 1: { davrq->removeProps = ucx_dlist_append( davrq->removeProps, rootElement); break; } } rootElement = NULL; } } XMLString::release(&ns); XMLString::release(&name); } void ProppatchHandler::characters( const XMLCh *const chars, const XMLSize_t length) { XMLString::trim((XMLCh *const)chars); if(chars[0] == 0) { return; } XmlElement *currentElm = XSTACK_CUR(); if(currentElm) { xmlch_t *str = (xmlch_t*)pool_calloc(pool, sizeof(xmlch_t), length + 1); for(int i=0;i<length;i++) { str[i] = chars[i]; } currentElm->content = str; currentElm->ctlen = length; } } void ProppatchHandler::startDocument() { } void ProppatchHandler::endDocument() { }