⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlnode.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -------------------------------------------------------------------------- * * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL").  You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/.   * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL * for the specific language governing rights and limitations under the * JOSL. * * Copyrights *  * Portions created by or assigned to Jabber.com, Inc. are  * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact * information for Jabber.com, Inc. is available at http://www.jabber.com/. * * Portions Copyright (c) 1998-1999 Jeremie Miller. *  * Acknowledgements *  * Special thanks to the Jabber Open Source Contributors for their * suggestions and support of Jabber. *  * Alternatively, the contents of this file may be used under the terms of the * GNU General Public License Version 2 or later (the "GPL"), in which case * the provisions of the GPL are applicable instead of those above.  If you * wish to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the JOSL, * indicate your decision by deleting the provisions above and replace them * with the notice and other provisions required by the GPL.  If you do not * delete the provisions above, a recipient may use your version of this file * under either the JOSL or the GPL.  *  *  * --------------------------------------------------------------------------*/#include "lib.h"/* Internal routines */xmlnode _xmlnode_new(pool p, const char* name, unsigned int type){    xmlnode result = NULL;    if (type > NTYPE_LAST)        return NULL;    if (type != NTYPE_CDATA && name == NULL)        return NULL;    if (p == NULL)    {        p = pool_heap(1*1024);    }    /* Allocate & zero memory */    result = (xmlnode)pmalloco(p, sizeof(_xmlnode));    /* Initialize fields */    if (type != NTYPE_CDATA)        result->name = pstrdup(p,name);    result->type = type;    result->p = p;    return result;}static xmlnode _xmlnode_append_sibling(xmlnode lastsibling, const char* name, unsigned int type){    xmlnode result;    result = _xmlnode_new(xmlnode_pool(lastsibling), name, type);    if (result != NULL)    {        /* Setup sibling pointers */        result->prev = lastsibling;        lastsibling->next = result;    }    return result;}static xmlnode _xmlnode_insert(xmlnode parent, const char* name, unsigned int type){    xmlnode result;    if(parent == NULL || (type != NTYPE_CDATA && name == NULL)) return NULL;    /* If parent->firstchild is NULL, simply create a new node for the first child */    if (parent->firstchild == NULL)    {        result = _xmlnode_new(parent->p, name, type);        parent->firstchild = result;    }    /* Otherwise, append this to the lastchild */    else    {        result= _xmlnode_append_sibling(parent->lastchild, name, type);    }    result->parent = parent;    parent->lastchild = result;    return result;}static xmlnode _xmlnode_search(xmlnode firstsibling, const char* name, unsigned int type){    xmlnode current;    /* Walk the sibling list, looking for a NTYPE_TAG xmlnode with    the specified name */    current = firstsibling;    while (current != NULL)    {        if ((current->type == type) && (j_strcmp(current->name, name) == 0))            return current;        else            current = current->next;    }    return NULL;}void _xmlnode_merge(xmlnode data){    xmlnode cur;    char *merge, *scur;    int imerge;    /* get total size of all merged cdata */    imerge = 0;    for(cur = data; cur != NULL && cur->type == NTYPE_CDATA; cur = cur->next)        imerge += cur->data_sz;    /* copy in current data and then spin through all of them and merge */    scur = merge = pmalloc(data->p,imerge + 1);    for(cur = data; cur != NULL && cur->type == NTYPE_CDATA; cur = cur->next)    {        memcpy(scur,cur->data,cur->data_sz);        scur += cur->data_sz;    }    *scur = '\0';    /* this effectively hides all of the merged-in chunks */    data->next = cur;    if(cur == NULL)        data->parent->lastchild = data;    else        cur->prev = data;    /* reset data */    data->data = merge;    data->data_sz = imerge;    }static void _xmlnode_hide_sibling(xmlnode child){    if(child == NULL)        return;    if(child->prev != NULL)        child->prev->next = child->next;    if(child->next != NULL)        child->next->prev = child->prev;}void _xmlnode_tag2str(spool s, xmlnode node, int flag){    xmlnode tmp;    if(flag==0 || flag==1)    {	    spooler(s,"<",xmlnode_get_name(node),s);	    tmp = xmlnode_get_firstattrib(node);	    while(tmp) {	        spooler(s," ",xmlnode_get_name(tmp),"='",strescape(xmlnode_pool(node),xmlnode_get_data(tmp)),"'",s);	        tmp = xmlnode_get_nextsibling(tmp);	    }	    if(flag==0)	        spool_add(s,"/>");	    else	        spool_add(s,">");    }    else    {	    spooler(s,"</",xmlnode_get_name(node),">",s);    }}spool _xmlnode2spool(xmlnode node){    spool s;    int level=0,dir=0;    xmlnode tmp;    if(!node || xmlnode_get_type(node)!=NTYPE_TAG)        return NULL;    s = spool_new(xmlnode_pool(node));    if(!s) return(NULL);    while(1)    {        if(dir==0)        {    	    if(xmlnode_get_type(node) == NTYPE_TAG)            {                if(xmlnode_has_children(node))                {                    _xmlnode_tag2str(s,node,1);                    node = xmlnode_get_firstchild(node);                    level++;                    continue;                }else{                    _xmlnode_tag2str(s,node,0);                }            }else{                spool_add(s,strescape(xmlnode_pool(node),xmlnode_get_data(node)));            }        }    	tmp = xmlnode_get_nextsibling(node);        if(!tmp)        {            node = xmlnode_get_parent(node);            level--;            if(level>=0) _xmlnode_tag2str(s,node,2);            if(level<1) break;            dir = 1;        }else{            node = tmp;            dir = 0;        }    }    return s;}/* External routines *//* *  xmlnode_new_tag -- create a tag node *  Automatically creates a memory pool for the node. * *  parameters *      name -- name of the tag * *  returns *      a pointer to the tag node *      or NULL if it was unsuccessfull */xmlnode xmlnode_new_tag(const char* name){    return _xmlnode_new(NULL, name, NTYPE_TAG);}/* *  xmlnode_new_tag_pool -- create a tag node within given pool * *  parameters *      p -- previously created memory pool *      name -- name of the tag * *  returns *      a pointer to the tag node *      or NULL if it was unsuccessfull */xmlnode xmlnode_new_tag_pool(pool p, const char* name){    return _xmlnode_new(p, name, NTYPE_TAG);}/* *  xmlnode_insert_tag -- append a child tag to a tag * *  parameters *      parent -- pointer to the parent tag *      name -- name of the child tag * *  returns *      a pointer to the child tag node *      or NULL if it was unsuccessfull */xmlnode xmlnode_insert_tag(xmlnode parent, const char* name){    return _xmlnode_insert(parent, name, NTYPE_TAG);}/* *  xmlnode_insert_cdata -- append character data to a tag * *  parameters *      parent -- parent tag *      CDATA -- character data *      size -- size of CDATA *              or -1 for null-terminated CDATA strings * *  returns *      a pointer to the child CDATA node *      or NULL if it was unsuccessfull */xmlnode xmlnode_insert_cdata(xmlnode parent, const char* CDATA, unsigned int size){    xmlnode result;    if(CDATA == NULL || parent == NULL)        return NULL;    if(size == -1)        size = strlen(CDATA);    result = _xmlnode_insert(parent, NULL, NTYPE_CDATA);    if (result != NULL)    {        result->data = (char*)pmalloc(result->p, size + 1);        memcpy(result->data, CDATA, size);        result->data[size] = '\0';        result->data_sz = size;    }    return result;}/* *  xmlnode_get_tag -- find given tag in an xmlnode tree * *  parameters *      parent -- pointer to the parent tag *      name -- "name" for the child tag of that name *              "name/name" for a sub child (recurses) *              "?attrib" to match the first tag with that attrib defined *              "?attrib=value" to match the first tag with that attrib and value *              "=cdata" to match the cdata contents of the child *              or any combination: "name/name/?attrib", "name=cdata", etc * *  results *      a pointer to the tag matching search criteria *      or NULL if search was unsuccessfull */xmlnode xmlnode_get_tag(xmlnode parent, const char* name){    char *str, *slash, *qmark, *equals;    xmlnode step, ret;    if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL;    if(strstr(name, "/") == NULL && strstr(name,"?") == NULL && strstr(name, "=") == NULL)        return _xmlnode_search(parent->firstchild, name, NTYPE_TAG);    str = strdup(name);    slash = strstr(str, "/");    qmark = strstr(str, "?");    equals = strstr(str, "=");    if(equals != NULL && (slash == NULL || equals < slash) && (qmark == NULL || equals < qmark))    { /* of type =cdata */        *equals = '\0';        equals++;        for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))        {            if(xmlnode_get_type(step) != NTYPE_TAG)                continue;            if(*str != '\0')                if(j_strcmp(xmlnode_get_name(step),str) != 0)                    continue;            if(j_strcmp(xmlnode_get_data(step),equals) != 0)                continue;            break;        }        free(str);        return step;    }    if(qmark != NULL && (slash == NULL || qmark < slash))    { /* of type ?attrib */        *qmark = '\0';        qmark++;        if(equals != NULL)        {            *equals = '\0';            equals++;        }        for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))        {            if(xmlnode_get_type(step) != NTYPE_TAG)                continue;            if(*str != '\0')                if(j_strcmp(xmlnode_get_name(step),str) != 0)                    continue;            if(xmlnode_get_attrib(step,qmark) == NULL)                continue;            if(equals != NULL && j_strcmp(xmlnode_get_attrib(step,qmark),equals) != 0)                continue;            break;        }        free(str);        return step;    }    *slash = '\0';    ++slash;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -