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

📄 pdtree.c

📁 性能优秀的SIP Proxy
💻 C
字号:
/** * $Id: pdtree.c,v 1.2 2006/01/30 15:56:04 anomarme Exp $ * * Copyright (C) 2005 Voice Sistem SRL (Voice-System.RO) * * This file is part of openser, a free SIP server. * * This file 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 file 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 * * History: * ------- * 2005-01-25  first tree version (ramona) * 2006-01-30 multi domain support added (ramona) */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include "../../dprint.h"#include "../../mem/mem.h"#include "pdtree.h"#include "utils.h"pdt_tree_t* pdt_init_tree(str* sdomain){	pdt_tree_t *pt = NULL;	pt = (pdt_tree_t*)pkg_malloc(sizeof(pdt_tree_t));	if(pt==NULL)	{		LOG(L_ERR, "pdt_init_tree:ERROR: no more pkg memory\n");		return NULL;	}	memset(pt, 0, sizeof(pdt_tree_t));	pt->sdomain.s = (char*)pkg_malloc((1+sdomain->len)*sizeof(char));	if(pt->sdomain.s==NULL)	{		pkg_free(pt);		LOG(L_ERR, "pdt_init_tree:ERROR: no more pkg mem\n");		return NULL;	}	memset(pt->sdomain.s, 0,1+sdomain->len );	memcpy(pt->sdomain.s, sdomain->s, sdomain->len);	pt->sdomain.len = sdomain->len;//	printf("sdomain:%.*s\n", pt->sdomain.len, pt->sdomain.s);		pt->head = (pdt_node_t*)pkg_malloc(PDT_NODE_SIZE*sizeof(pdt_node_t));	if(pt->head == NULL)	{		pkg_free(pt->sdomain.s);		pkg_free(pt);		LOG(L_ERR, "pdt_init_tree:ERROR: no more pkg mem\n");		return NULL;	}	memset(pt->head, 0, PDT_NODE_SIZE*sizeof(pdt_node_t));		return pt;}int add_to_tree(pdt_tree_t *pt, str *sp, str *sd){	int l;	pdt_node_t *itn, *itn0;		if(pt==NULL || sp==NULL || sp->s==NULL			|| sd==NULL || sd->s==NULL)	{		LOG(L_ERR, "pdt_add_to_tree:ERROR: bad parameters\n");		return -1;	}	if(sp->len>=PDT_MAX_DEPTH)	{		LOG(L_ERR, "pdt_add_to_tree:ERROR: max prefix len exceeded\n");		return -1;	}		l = 0;	itn0 = pt->head;	itn = itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].child;	while(l < sp->len-1)	{		if(sp->s[l] < '0' || sp->s[l] > '9')		{			LOG(L_ERR,			"pdt_add_to_tree:ERROR: invalid char %d in prefix [%c (0x%x)]\n",				l, sp->s[l], sp->s[l]);			return -1;					}				if(itn == NULL)		{			itn = (pdt_node_t*)pkg_malloc(PDT_NODE_SIZE*sizeof(pdt_node_t));			if(itn == NULL)			{				LOG(L_ERR, "pdt_add_to_tree: no more pkg mem\n");				return -1;			}			memset(itn, 0, PDT_NODE_SIZE*sizeof(pdt_node_t));			itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].child = itn;		}		l++;			itn0 = itn;		itn = itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].child;	}	if(itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.s!=NULL)	{		LOG(L_ERR, "pdt_add_to_tree:ERROR: prefix alredy allocated\n");		return -1;	}	itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.s			= (char*)pkg_malloc((sd->len+1)*sizeof(char));	if(itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.s==NULL)	{		LOG(L_ERR, "pdt_add_to_tree:ERROR: no more pkg mem!\n");		return -1;	}	strncpy(itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.s,			sd->s, sd->len);	itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.len = sd->len;	itn0[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.s[sd->len] = '\0';		return 0;}pdt_tree_t* pdt_get_tree(pdt_tree_t *pl, str *sdomain){	pdt_tree_t *it;			   	if(pl==NULL)		return NULL;	if( sdomain==NULL || sdomain->s==NULL)	{		LOG(L_ERR, "pdt_get_tree:ERROR: bad parameters\n");		return NULL;	}	it = pl;	/* search the tree for the asked sdomain */	while(it!=NULL && scmp(&it->sdomain, sdomain)<0)		it = it->next;	if(it==NULL || scmp(&it->sdomain, sdomain)>0)		return NULL;		return it;}int pdt_add_to_tree(pdt_tree_t **dpt, str *sdomain, str *code, str *domain){	pdt_tree_t *ndl, *it, *prev;	if( sdomain==NULL || sdomain->s==NULL			|| code==NULL || code->s==NULL			|| domain==NULL || domain->s==NULL)	{		LOG(L_ERR, "pdt_add_to_dlist:ERROR: bad parameters\n");		return -1;	}		ndl = NULL;		it = *dpt;	prev = NULL;	/* search the it position before which to insert new domain */	while(it!=NULL && scmp(&it->sdomain, sdomain)<0)	{			prev = it;		it = it->next;	}//	printf("sdomain:%.*s\n", sdomain->len, sdomain->s);	/* add new sdomain*/	if(it==NULL || scmp(&it->sdomain, sdomain)>0)	{		ndl = pdt_init_tree(sdomain);		if(ndl==NULL)		{			LOG(L_ERR, "pdt_add_to_tree:ERROR: no more pkg memory\n");			return -1; 		}		if(add_to_tree(ndl, code, domain)<0)		{			LOG(L_ERR, "pdt_add_to_dlist:ERROR: pdt_add_to_tree internal error!\n");			return -1;		}		ndl->next = it;				/* new domain must be added as first element */		if(prev==NULL)			*dpt = ndl;		else			prev->next=ndl;	}	else 		/* add (prefix, code) to already present sdomain */		if(add_to_tree(it, code, domain)<0)		{			LOG(L_ERR, "pdt_add_to_dlist:ERROR: pdt_add_to_tree internal error!\n");			return -1;		}	return 0;}int remove_from_tree(pdt_tree_t *pt, str *sp){	int l;	pdt_node_t *itn;	if(pt==NULL || sp==NULL || sp->s==NULL || sp->len<=0)	{		LOG(L_ERR, "remove_from_tree:ERROR: bad parameters\n");		return -1;	}		l = 1;	itn = pt->head;		while(itn!=NULL && l < sp->len && l < PDT_MAX_DEPTH)	{		itn = itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].child;		l++;		}	if(itn!=NULL && l==sp->len			&& itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].domain.s!=NULL)	{		DBG("remove_from_tree: deleting <%.*s>\n",				itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].domain.len,				itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].domain.s);		pkg_free(itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].domain.s);		itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].domain.s   = NULL;		itn[(sp->s[l-1]-'0')%PDT_NODE_SIZE].domain.len = 0;	}	/* todo: should free the node if no child and prefix inside */		return 0;}int pdt_remove_prefix_from_tree(pdt_tree_t *pl, str *sdomain, str* code){	pdt_tree_t *it;		if(pl==NULL || sdomain==NULL || sdomain->s==NULL || code==NULL || code->s==NULL)	{		LOG(L_ERR, "pdt_remove_prefix_from_tree:ERROR: bad parameters\n");		return -1;	}	it = pl;	while(it!=NULL && scmp(&it->sdomain, sdomain)<0)		it = it->next;		/* find the sdomain where to delete the (prefix, domain) */	if(it!=NULL && scmp(&it->sdomain, sdomain)==0)	{		if(remove_from_tree(it, code)<0)		{			LOG(L_ERR, "pdt_remove_prefix_from_tree:ERROR: remove_from_tree internal error\n");			return -1;		}	}			return 0;}str* get_domain(pdt_tree_t *pt, str *sp, int *plen){	int l, len;	pdt_node_t *itn;	str *domain;	if(pt==NULL || sp==NULL || sp->s==NULL)	{		LOG(L_ERR, "pdt_get_domain:ERROR: bad parameters\n");		return NULL;	}		l = len = 0;	itn = pt->head;	domain = NULL;	while(itn!=NULL && l < sp->len && l < PDT_MAX_DEPTH)	{		if(itn[(sp->s[l]-'0')%PDT_NODE_SIZE].domain.s!=NULL)		{			domain = &itn[(sp->s[l]-'0')%PDT_NODE_SIZE].domain;			len = l+1;		}				itn = itn[(sp->s[l]-'0')%PDT_NODE_SIZE].child;		l++;		}		if(plen!=NULL)		*plen = len;		return domain;	}str* pdt_get_domain(pdt_tree_t *pl, str* sdomain, str *code, int *plen){	pdt_tree_t *it;	int len;	str *domain=NULL;	if(pl==NULL || sdomain==NULL || sdomain->s==NULL || code == NULL || code->s == NULL)	{		LOG(L_ERR, "pdt_get_domain:ERROR: bad parameters\n");		return NULL;	}	it = pl;	while(it!=NULL && scmp(&it->sdomain, sdomain)<0)		it = it->next;		if(it==NULL || scmp(&it->sdomain, sdomain)>0)		return NULL;		domain = get_domain(it, code, &len);	if(plen!=NULL)			*plen = len;	return domain;}void pdt_free_node(pdt_node_t *pn){	int i;	if(pn==NULL)		return;	for(i=0; i<PDT_NODE_SIZE; i++)	{		if(pn[i].domain.s!=NULL)		{			pkg_free(pn[i].domain.s);			pn[i].domain.s   = NULL;			pn[i].domain.len = 0;		}		if(pn[i].child!=NULL)		{			pdt_free_node(pn[i].child);			pn[i].child = NULL;		}	}	pkg_free(pn);	pn = NULL;		return;}void pdt_free_tree(pdt_tree_t *pt){	if(pt == NULL)		return;	if(pt->head!=NULL) 		pdt_free_node(pt->head);	if(pt->next!=NULL)		pdt_free_tree(pt->next);	if(pt->sdomain.s!=NULL)		pkg_free(pt->sdomain.s);		pkg_free(pt);	pt = NULL;	return;}int pdt_print_node(pdt_node_t *pn, char *code, int len){	int i;	if(pn==NULL || code==NULL || len>=PDT_MAX_DEPTH)		return 0;		for(i=0; i<PDT_NODE_SIZE; i++)	{		code[len] = '0' + (char)i;		if(pn[i].domain.s!=NULL)			DBG("pdt_print_node: [%.*s] [%.*s]\n",				len+1, code, pn[i].domain.len, pn[i].domain.s);		pdt_print_node(pn[i].child, code, len+1);	}	return 0;}int pdt_print_tree(pdt_tree_t *pt){	static char code_buf[PDT_MAX_DEPTH+1];	int len;	if(pt == NULL)		return 0;	DBG("pdt_print_tree: [%.*s]\n", pt->sdomain.len, pt->sdomain.s);	len = 0;	pdt_print_node(pt->head, code_buf, len);	return pdt_print_tree(pt->next);}

⌨️ 快捷键说明

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