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

📄 xode.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: xode.c,v 1.3 2004/08/24 08:58:30 janakj Exp $ * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *  Jabber *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ */#include "xode.h"static int _xode_strcmp(const char *a, const char *b){    if(a == NULL || b == NULL) return -1;    return strcmp(a,b);}/* Internal routines */static xode _xode_new(xode_pool p, const char* name, unsigned int type){    xode result = NULL;    if (type > XODE_TYPE_LAST)        return NULL;    if (type != XODE_TYPE_CDATA && name == NULL)        return NULL;    if (p == NULL)    {        p = xode_pool_heap(1*1024);    }    /* Allocate & zero memory */    result = (xode)xode_pool_malloc(p, sizeof(_xode));    memset(result, '\0', sizeof(_xode));    /* Initialize fields */    if (type != XODE_TYPE_CDATA)        result->name = xode_pool_strdup(p,name);    result->type = type;    result->p = p;    return result;}static xode _xode_appendsibling(xode lastsibling, const char* name, unsigned int type){    xode result;    result = _xode_new(xode_get_pool(lastsibling), name, type);    if (result != NULL)    {        /* Setup sibling pointers */        result->prev = lastsibling;        lastsibling->next = result;    }    return result;}static xode _xode_insert(xode parent, const char* name, unsigned int type){    xode result;    if(parent == NULL || name == NULL) return NULL;    /* If parent->firstchild is NULL, simply create a new node for the first child */    if (parent->firstchild == NULL)    {        result = _xode_new(parent->p, name, type);        parent->firstchild = result;    }    /* Otherwise, append this to the lastchild */    else    {        result= _xode_appendsibling(parent->lastchild, name, type);    }    result->parent = parent;    parent->lastchild = result;    return result;}static xode _xode_search(xode firstsibling, const char* name, unsigned int type){    xode current;    /* Walk the sibling list, looking for a XODE_TYPE_TAG xode with    the specified name */    current = firstsibling;    while (current != NULL)    {        if (name != NULL && (current->type == type) && (_xode_strcmp(current->name, name) == 0))            return current;        else            current = current->next;    }    return NULL;}static char* _xode_merge(xode_pool p, char* dest, unsigned int destsize, const char* src, unsigned int srcsize){    char* result;    result = (char*)xode_pool_malloc(p, destsize + srcsize + 1);    memcpy(result, dest, destsize);    memcpy(result+destsize, src, srcsize);    result[destsize + srcsize] = '\0';    /* WARNING: major ugly hack: since we're throwing the old data away, let's jump in the xode_pool and subtract it from the size, this is for xmlstream's big-node checking */    p->size -= destsize;    return result;}static void _xode_hidesibling(xode child){    if(child == NULL)        return;    if(child->prev != NULL)        child->prev->next = child->next;    if(child->next != NULL)        child->next->prev = child->prev;}static void _xode_tag2str(xode_spool s, xode node, int flag){    xode tmp;    if(flag==0 || flag==1)    {	    xode_spooler(s,"<",xode_get_name(node),s);	    tmp = xode_get_firstattrib(node);	    while(tmp) {	        xode_spooler(s," ",xode_get_name(tmp),"='",xode_strescape(xode_get_pool(node),xode_get_data(tmp)),"'",s);	        tmp = xode_get_nextsibling(tmp);	    }	    if(flag==0)	        xode_spool_add(s,"/>");	    else	        xode_spool_add(s,">");    }    else    {	    xode_spooler(s,"</",xode_get_name(node),">",s);    }}static xode_spool _xode_tospool(xode node){    xode_spool s;    int level=0,dir=0;    xode tmp;    if(!node || xode_get_type(node) != XODE_TYPE_TAG)	return NULL;    s = xode_spool_newfrompool(xode_get_pool(node));    if(!s) return(NULL);    while(1)    {        if(dir==0)        {    	    if(xode_get_type(node) == XODE_TYPE_TAG)            {		        if(xode_has_children(node))                {		            _xode_tag2str(s,node,1);        		    node = xode_get_firstchild(node);		            level++;		            continue;        		}                else                {		            _xode_tag2str(s,node,0);		        }	        }            else            {		        xode_spool_add(s,xode_strescape(xode_get_pool(node),xode_get_data(node)));	        }	    }    	tmp = xode_get_nextsibling(node);	    if(!tmp)        {	        node = xode_get_parent(node);	        level--;	        if(level>=0) _xode_tag2str(s,node,2);	        if(level<1) break;	        dir = 1;	    }        else        {	        node = tmp;	        dir = 0;	    }    }    return s;}/* External routines *//* *  xode_new_tag -- create a tag node *  Automatically creates a memory xode_pool for the node. * *  parameters *      name -- name of the tag * *  returns *      a pointer to the tag node *      or NULL if it was unsuccessful */xode xode_new(const char* name){    return _xode_new(NULL, name, XODE_TYPE_TAG);}/* * alias for 'xode_new' */xode xode_new_tag(const char* name){    return _xode_new(NULL, name, XODE_TYPE_TAG);}/* *  xode_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 unsuccessful */xode xode_new_frompool(xode_pool p, const char* name){    return _xode_new(p, name, XODE_TYPE_TAG);}/* *  xode_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 unsuccessful */xode xode_insert_tag(xode parent, const char* name){    return _xode_insert(parent, name, XODE_TYPE_TAG);}/* *  xode_insert_cdata -- append character data to a tag *  If last child of the parent is CDATA, merges CDATA nodes. Otherwise *  creates a CDATA node, and appends it to the parent's child list. * *  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 unsuccessful */xode xode_insert_cdata(xode parent, const char* CDATA, unsigned int size){    xode result;    if(CDATA == NULL || parent == NULL)        return NULL;    if(size == -1)        size = strlen(CDATA);    if ((parent->lastchild != NULL) && (parent->lastchild->type == XODE_TYPE_CDATA))    {        result = parent->lastchild;        result->data = _xode_merge(result->p, result->data, result->data_sz, CDATA, size);        result->data_sz = result->data_sz + size;    }    else    {        result = _xode_insert(parent, "", XODE_TYPE_CDATA);        if (result != NULL)        {            result->data = (char*)xode_pool_malloc(result->p, size + 1);            memcpy(result->data, CDATA, size);            result->data[size] = '\0';            result->data_sz = size;        }    }    return result;}/* *  xode_gettag -- find given tag in an xode 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 *              or any combination: "name/name/?attrib", etc * *  results *      a pointer to the tag matching search criteria *      or NULL if search was unsuccessful */xode xode_get_tag(xode parent, const char* name){    char *str, *slash, *qmark, *equals;    xode step, ret;    if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL;    if(strstr(name, "/") == NULL && strstr(name,"?") == NULL)        return _xode_search(parent->firstchild, name, XODE_TYPE_TAG);    /* jer's note: why can't I modify the name directly, why do I have to strdup it?  damn c grrr! */    str = strdup(name);    slash = strstr(str, "/");    qmark = strstr(str, "?");    equals = strstr(str, "=");    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 = xode_get_nextsibling(step))        {            if(xode_get_type(step) != XODE_TYPE_TAG)                continue;            if(*str != '\0')                if(_xode_strcmp(xode_get_name(step),str) != 0)                    continue;            if(xode_get_attrib(step,qmark) == NULL)                continue;            if(equals != NULL && _xode_strcmp(xode_get_attrib(step,qmark),equals) != 0)                continue;            break;        }        free(str);        return step;    }    *slash = '\0';    ++slash;    for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step))    {        if(xode_get_type(step) != XODE_TYPE_TAG) continue;        if(_xode_strcmp(xode_get_name(step),str) != 0)            continue;        ret = xode_get_tag(step, slash);        if(ret != NULL)        {            free(str);            return ret;        }    }    free(str);    return NULL;}/* return the cdata from any tag */char *xode_get_tagdata(xode parent, const char *name){    xode tag;    tag = xode_get_tag(parent, name);    if(tag == NULL) return NULL;    return xode_get_data(tag);}void xode_put_attrib(xode owner, const char* name, const char* value){    xode attrib;    if(owner == NULL || name == NULL || value == NULL) return;    /* If there are no existing attributes, allocate a new one to start    the list */    if (owner->firstattrib == NULL)    {

⌨️ 快捷键说明

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