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

📄 htutree.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
字号:
/***	URL DATA TREE STRUCTURE****	(c) COPYRIGHT MIT 1995.**	Please first read the full copyright statement in the file COPYRIGH.**	@(#) $Id: HTUTree.c,v 2.6 1999/02/22 22:10:12 frystyk Exp $**** AUTHORS:**	HFN	Henrik Frystyk Nielsen <frystyk@w3.org>****	An infobase is a tree structure where we can store all the information**	we know about a remote server. Typically, each remote server will**	have its own infobase which gets richer as we get to know more about**	the remote web site.****	This module maintains an URL information database**	which can contain information stored by filters. This can for**	example be used to store challenges received from remote server.**	A infobase has the advantage that it can be searched using URLs _or_**	using realms. The letter is most useful to "guess" information**	about a remote URL that we haven't seen before*//* Library include files */#include "wwwsys.h"#include "WWWUtil.h"#include "HTUTree.h"					 /* Implemented here */#define TREE_TIMEOUT		43200L	     /* Default tree timeout is 12 h */struct _HTUTree {			  /* Server URL info base */    char *		name;    char *		host;    int			port;    HTList *		templates;	  /* List of templates for this tres */    HTList * 		realms;		     /* List of realms for this tree */    time_t		created;	     /* Creation time of this object */    HTUTree_gc * 	gc;			/* Contect garbage collector */};struct _HTURealm {			  		  /* Realm specifics */    char *		realm;    void *		context;    HTUTemplate *	tm_ptr;};struct _HTUTemplate {				 /* Hierarchical information */    char *		tmplate;    HTURealm *	       	rm_ptr;};PRIVATE HTList ** InfoTable = NULL;    		/* List of information bases */PRIVATE time_t UTreeTimeout = TREE_TIMEOUT;/* ------------------------------------------------------------------------- *//***	Create a new realm**	Returns new object or NULL if error*/PRIVATE HTURealm * HTUTree_newRealm (HTUTree * tree, const char * realm,				     void * context){    if (tree) {	HTURealm * me;	if ((me = (HTURealm *) HT_CALLOC(1, sizeof(HTURealm))) == NULL)	    HT_OUTOFMEM("HTURealm_new");	if (realm) StrAllocCopy(me->realm, realm);	me->context = context;	HTList_addObject(tree->realms, (void *) me);	return me;    }    return NULL;}/***	Delete a realm. We call the scheme gc callback to free the opaque**	context object.*/PRIVATE BOOL HTUTree_deleteRealm (HTUTree * tree, HTURealm * me){    if (tree && me) {	if (tree->gc && me->context) (*tree->gc)(me->context);	HTList_removeObject(tree->realms, (void *) me);	HT_FREE(me->realm);	HT_FREE(me);	return YES;    }    return NO;}/***	Find a realm*/PRIVATE HTURealm * HTUTree_findRealm (HTUTree * tree, const char * realm){    if (tree && tree->realms && realm) {	HTList * cur = tree->realms;	HTURealm * pres;	while ((pres = (HTURealm *) HTList_nextObject(cur))) {	    if (!strcmp(pres->realm, realm)) {		HTTRACE(CORE_TRACE, "URL Node.... Realm `%s\' found\n" _ realm);		return pres;	    }	}    }    return NULL;}/***	Create a new template and add to URL tree**	Returns new object or NULL if error*/PRIVATE HTUTemplate * HTUTree_newTemplate (HTUTree * tree,const char * tmplate){    if (tree && tmplate) {	HTUTemplate * me;	if ((me = (HTUTemplate *) HT_CALLOC(1, sizeof(HTUTemplate))) == NULL)	    HT_OUTOFMEM("HTUTemplate_new");	StrAllocCopy(me->tmplate, tmplate);	HTList_addObject(tree->templates, (void *) me);	return me;    }    return NULL;}/***	Delete a template*/PRIVATE BOOL HTUTree_deleteTemplate (HTUTree * tree, HTUTemplate * me){    if (tree && me) {	HTList_removeObject(tree->templates, (void *) me);	HT_FREE(me->tmplate);	HT_FREE(me);	return YES;    }    return NO;}/***	Find a template*/PRIVATE HTUTemplate * HTUTree_findTemplate (HTUTree * tree, const char * path){    if (tree && tree->templates && path) {	HTUTemplate * pres;	HTList * cur = tree->templates;	while ((pres = (HTUTemplate *) HTList_nextObject(cur))) {	    if (HTStrMatch(pres->tmplate, path)) {		HTTRACE(CORE_TRACE, "URL Node.... Found template `%s\' for for `%s\'\n" _ 			    pres->tmplate _ path);		return pres;	    }	}    }    return NULL;}/***	Search a URL Tree for a matching template or realm**	Return the opaque context object found or NULL if none**	Please regard this as a first simple attempt - it can be done**	much more efficient!*/PUBLIC void * HTUTree_findNode (HTUTree * tree,				const char * realm, const char * path){    HTURealm * rm = HTUTree_findRealm(tree, realm);    if (rm)	return rm->context;    else {	HTUTemplate * tm = HTUTree_findTemplate(tree, path);	if (tm) return tm->rm_ptr ? tm->rm_ptr->context : NULL;    }    HTTRACE(CORE_TRACE, "URL Node.... Not found\n");    return NULL;}/***	Add a new node (a template and a realm) to the tree*/PUBLIC BOOL HTUTree_addNode (HTUTree * tree,			     const char * realm, const char * path,			     void * context){    if (tree) {	if (realm && path) { 		       /* If both a path and a realm */	    HTUTemplate * new_template = HTUTree_newTemplate(tree, path);	    HTURealm * new_realm = HTUTree_newRealm(tree, realm, context);	    new_realm->tm_ptr = new_template;	    new_template->rm_ptr = new_realm;	    return YES;	} else if (realm) {				  /* If only a realm */	    HTUTree_newRealm(tree, realm, context);	    return YES;	}	HTTRACE(CORE_TRACE, "URL Node.... At least realm must be present\n");    }    return NO;}/***	Replace node (insert a new context at the same node)*/PUBLIC BOOL HTUTree_replaceNode (HTUTree * tree,				 const char * realm, const char * path,				 void * context){    HTURealm * rm = HTUTree_findRealm(tree, realm);    if (!rm) {	HTUTemplate * tm = HTUTree_findTemplate(tree, path);	if (tm) rm = tm->rm_ptr;    }    if (rm) {	if (tree->gc && rm->context) (*tree->gc)(rm->context);	rm->context = context;	return YES;    }    HTTRACE(CORE_TRACE, "URL Node.... Not found\n");    return NO;}/***	Remove a node (a template and a realm) from the tree*/PUBLIC BOOL HTUTree_deleteNode (HTUTree * tree,				const char * realm, const char * path){    if (tree) {	HTURealm * rm = HTUTree_findRealm(tree, realm);	HTUTemplate * tm = rm ? rm->tm_ptr : HTUTree_findTemplate(tree, path);	if (!rm) rm = tm ? tm->rm_ptr : NULL;	HTUTree_deleteRealm(tree, rm);	HTUTree_deleteTemplate(tree, tm);	return YES;    }    return NO; }PRIVATE BOOL delete_tree (HTUTree * tree){    if (tree) {	HTList * cur;	/* Free all templates */	if ((cur = tree->templates)) {	    HTUTemplate * pres;	    while ((pres = (HTUTemplate *) HTList_lastObject(cur)))		HTUTree_deleteTemplate(tree, pres);	    HTList_delete(tree->templates);	}	/* Free all nodes */	if ((cur = tree->realms)) {	    HTURealm * pres;	    while ((pres = (HTURealm *) HTList_lastObject(cur)))		HTUTree_deleteRealm(tree, pres);	    HTList_delete(tree->realms);	    	}	HT_FREE(tree->name);	HT_FREE(tree->host);	HT_FREE(tree);	return YES;    }    return NO;}/***	Find an existing URL Tree**	Returns tree or NULL if error*/PRIVATE HTUTree * find_tree (const char * 	name,			     const char *	host,			     int		port,			     HTList **		hashlist){    HTUTree * pres = NULL;    *hashlist = NULL;    if (!name || !host) {	HTTRACE(CORE_TRACE, "URL Tree.... Bad argument\n");	return NULL;    }    /* Find a hash for this host */    {	int hash;	const unsigned char * p;	for (p=host, hash=0; *p; p++) {	    hash = (hash * 3 + *p) % HT_L_HASH_SIZE;	}	if (!InfoTable) {	    if ((InfoTable = (HTList **) HT_CALLOC(HT_L_HASH_SIZE,						   sizeof(HTList *))) == NULL)	        HT_OUTOFMEM("HTUTree_find");	}	if (!InfoTable[hash])	    InfoTable[hash] = *hashlist = HTList_new();	else	    *hashlist = InfoTable[hash];    }    /* Search the existing list to see if we already have this entry */    {	HTList * cur = *hashlist;	while ((pres = (HTUTree *) HTList_nextObject(cur))) {	    if (!strcmp(pres->name, name) && !strcmp(pres->host, host) &&		pres->port==port) {		if (time(NULL) > pres->created + UTreeTimeout) {		    HTTRACE(CORE_TRACE, "URL Tree.... Collecting URL Tree %p\n" _ pres);		    HTList_removeObject(*hashlist, pres);		    delete_tree(pres);		    pres = NULL;		}		return pres;	    }	}    }    return NULL;}/***	Create a new URL Tree (or return an aready existing one)**	Returns new object (or the one found) or NULL if error*/PUBLIC HTUTree * HTUTree_new (const char * 		name,			      const char * 		host,			      int 			port,			      HTUTree_gc *	 	gc){    if (name && host) {	HTList * hashlist = NULL;	HTUTree * pres = find_tree(name, host, port, &hashlist);	/* If not found (or gc'ed) then create a new URL tree */	if (!pres) {	    if ((pres = (HTUTree *) HT_CALLOC(1, sizeof(HTUTree))) == NULL)		HT_OUTOFMEM("HTUTree_new");	    StrAllocCopy(pres->name, name);	    StrAllocCopy(pres->host, host);	    pres->port = (port > 0 ? port : 80);	    pres->templates = HTList_new();	    pres->realms = HTList_new();	    pres->created = time(NULL);	    pres->gc = gc;	    /* Add the new URL tree to the hash table */	    HTList_addObject(hashlist, (void *) pres);	    HTTRACE(CORE_TRACE, "URL Tree.... Created %p with name `%s\'\n" _ 				   pres _ pres->name);	} else {	    HTTRACE(CORE_TRACE, "URL Tree.... Found %p with name `%s\'\n" _ 				    pres _ pres->name);	}	return pres;    } else {	HTTRACE(CORE_TRACE, "URL Tree.... Bad argument\n");	return NULL;    }}/***	Find a URL tree*/PUBLIC HTUTree * HTUTree_find (const char *	name,			       const char * 	host,			       int		port){    if (name && host) {	HTList * hashlist = NULL;	HTUTree * pres = find_tree(name, host, port, &hashlist);	HTTRACE(CORE_TRACE, "URL Tree.... did %sfind `%s\'\n" _ 				pres ? "" : "NOT " _ name);	return pres;    } else {	HTTRACE(CORE_TRACE, "URL Tree.... Bad augument\n");    }    return NULL;}/***	Delete a complete server tree and everything within it.*/PUBLIC BOOL HTUTree_delete (const char * 	name,			    const char * 	host,			    int			port){    if (name && host) {	HTList * hashlist = NULL;	HTUTree * pres = find_tree(name, host, port, &hashlist);	if (pres) {	    HTList_removeObject(hashlist, pres);	    delete_tree(pres);	    HTTRACE(CORE_TRACE, "URL Tree.... deleted %p\n" _ pres);	    return YES;	}    }    return NO;}/***	Delete all URL Trees*/PUBLIC BOOL HTUTree_deleteAll (void){    if (InfoTable) {	int cnt;	HTList * cur;	for (cnt=0; cnt<HT_L_HASH_SIZE; cnt++) {	    if ((cur = InfoTable[cnt])) { 		HTUTree * pres;		while ((pres = (HTUTree *) HTList_nextObject(cur)))		    delete_tree(pres);	    }	    HTList_delete(InfoTable[cnt]);	}	HT_FREE(InfoTable);	return YES;    }    return NO;}

⌨️ 快捷键说明

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