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

📄 db_dict.c

📁 数据库C语言开发工具包,可以方便地移植到嵌入式系统中
💻 C
字号:
/****************************************************************************/
/*                                                                          */
/*                                                                          */
/*	db_dict.c - dictionary (symtable manager) routines                  */
/*                  v1.3  (c) 1990  Ken Harris                              */
/*                                                                          */
/*                                                                          */
/****************************************************************************/
/*                                                                          */
/*      This software is made available on an AS-IS basis. Unrestricted     */
/*      use is granted provided that the copyright notice remains intact.   */
/*      The author makes no warranties expressed or implied.                */
/*                                                                          */
/****************************************************************************/

#include "dblib.h"

#ifdef ANSI
static void strupr(char *);
#else
static void strupr();
#endif
char *calloc();

/*
 *	db_dict_hash - Computer hash value for a name
 */

static db_dict_hash(name)
 char *name;
{
	long x=0;

	while (*name) x += *name++;
	
	return(x % DICT_HASH_SIZE);
}




/*
 *	db_dict_init - Initialize a Dictionary
 */

DICT db_dict_init()
{	DICT  dict;
	int   i;


	db_error = 0;

	dict = (DICT) calloc(sizeof(struct db_dict_hdr), 1);
	if (!dict)
	{	db_error = DB_ALLOC_ERROR;
		return(NULL);
	}

	dict->magic = DICT_MAGIC;

	for (i=0; i<DICT_HASH_SIZE; i++)
		dict->htbl[i] = NULL;

	return(dict);
}

/*
 *	db_dict_add - add a new object to the dictionary
 */

void *db_dict_add(dict, name, o_type, d_size, data)
 DICT  dict; 
 char *name; 
 int   o_type; 
 int   d_size; 
 void *data;
{
	short hval, o_size;
	DOBJ  dobj;
	char *o_name, *o_data;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return(NULL);
	}

	if (!name || !*name) 
	{	db_error = DB_INVALID_NAME;
		return(NULL);
	}

	strupr(name);
	hval = db_dict_hash(name);

	if (db_dict_find(dict, name, o_type))
	{	db_dict_delete(dict, name, o_type);
		if (db_error) return(NULL);
	}
	else
		db_error = 0;

	o_size = sizeof(struct db_dict_obj) + strlen(name) + d_size;
	dobj   = (DOBJ) calloc(o_size, 1);
	if (!dobj)
	{	db_error = DB_ALLOC_ERROR;
		return(NULL);
	}

	dobj->o_type     = o_type;
	dobj->next       = dict->htbl[hval];
	dict->htbl[hval] = dobj;
	dobj->n_size     = strlen(name);
	dobj->d_size     = d_size;

	o_data           = &dobj->data;
	o_name           = o_data + dobj->d_size;

	strcpy(o_name, name);
	if (data) memcpy(o_data, data, d_size);

	return(o_data);
}

/*
 *	db_dict_delete - delete an object by name
 */

void db_dict_delete(dict, name, o_type)
 DICT  dict; 
 char *name; 
 int   o_type;
{
	DOBJ  prev, cur, next;
	short hval;
	char *cur_name;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return;
	}

	if (!name || !*name)
	{	db_error = DB_INVALID_NAME;
		return;
	}

	strupr(name);

	hval = db_dict_hash(name);
	prev = NULL;
	cur  = dict->htbl[hval];

	while (cur)
	{	cur_name = &cur->data + cur->d_size;	
		if (strcmp(cur_name, name)==0 &&
		    (cur->o_type==o_type || o_type==0))
		{	if (prev)
				prev->next       = cur->next;
			else
				dict->htbl[hval] = cur->next;

			next = cur->next;
			free(cur);
			cur = next;
		}
		else
		{	prev = cur;
			cur  = cur->next;
		}
	}
}

/*
 *	db_dict_delete_all - delete all objects of a type
 */

void db_dict_delete_all(dict, o_type)
 DICT  dict; 
 int   o_type;
{
	DOBJ  prev, cur, next;
	short hval, i;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return;
	}

	for (i=0; i<DICT_HASH_SIZE; i++)
	{	prev = NULL;
		cur  = dict->htbl[i];

		while (cur)
		{	if (cur->o_type==o_type || o_type==0)
			{	if (prev)
					prev->next    = cur->next;
				else
					dict->htbl[i] = cur->next;

				next = cur->next;
				free(cur);
				cur = next;
			}
			else
			{	prev = cur;
				cur  = cur->next;
			}
		}
	}
}

/*
 *	db_dict_find - Find a object by name
 */

void *db_dict_find(dict, name, o_type)
 DICT  dict; 
 char *name; 
 int   o_type;
{
	DOBJ  dobj;
	short hval;
	char *o_name;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return(NULL);
	}

	if (!name || !*name)
	{	db_error = DB_INVALID_NAME;
		return(NULL);
	}

	strupr(name);

	hval = db_dict_hash(name);
	dobj = dict->htbl[hval];

	while (dobj)
	{	o_name = &dobj->data + dobj->d_size;
		if (strcmp(o_name,name)==0 &&
		    (dobj->o_type==o_type || o_type==0))
			return(&dobj->data);
		
		dobj = dobj->next;
	}

	db_error = DB_REC_NOT_FOUND;
	return(NULL);
}

/*
 *	db_dict_find_all - Find all objects by type
 */

db_dict_find_all(dict, o_type, nlist, dlist)
 DICT   dict; 
 int    o_type; 
 char **nlist[]; 
 void **dlist[];
{
	DOBJ  dobj;
	short i, j, cnt;
	char  *tmp, *o_name, *o_data;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return(0);
	}

	for (i=0, cnt=0; i<DICT_HASH_SIZE; i++)
	{	dobj = dict->htbl[i];
		while (dobj)
		{	if (dobj->o_type==o_type || o_type==0) cnt++;
			dobj = dobj->next;
		}
	}

	if (!cnt)
	{	db_error = DB_REC_NOT_FOUND;
		*nlist = NULL;
		*dlist = NULL;
		return(0);
	}

	*nlist = (char **) calloc(sizeof(char *), cnt);
	if (!*nlist)
	{	db_error = DB_ALLOC_ERROR;
		return(0);
	}

	*dlist = (void **) calloc(sizeof(char *), cnt);
	if (!*dlist) 
	{	db_error = DB_ALLOC_ERROR;
		free(*nlist);
		return(0);
	}
	for (i=0, cnt=0; i<DICT_HASH_SIZE; i++)
	{	dobj = dict->htbl[i];
		while (dobj)
		{	if (dobj->o_type==o_type || o_type==0)
			{	o_data = &dobj->data;
				o_name = o_data + dobj->d_size;
 				(*nlist)[cnt] = o_name;
				(*dlist)[cnt] = o_data;
				cnt++;

				for (j=cnt-1; j>0; j--)
				{	if (strcmp((*nlist)[j],(*nlist)[j-1])<0)
					{	tmp           = (*nlist)[j];
						(*nlist)[j]   = (*nlist)[j-1];
						(*nlist)[j-1] = tmp;
						tmp           = (*dlist)[j];
						(*dlist)[j]   = (*dlist)[j-1];
						(*dlist)[j-1] = tmp;
					}
					else
						break;
				}
			}
			dobj = dobj->next;
		}
	}
	return(cnt);
}

/*
 *	db_dict_load - Load dictionary entries from a file
 */

void db_dict_load(dict, path, fname)
 DICT  dict; 
 char *path, *fname;
{
	DATA_FILE df;
	FILE_HDR  fh;
	DOBJ      dobj;
	char     *o_name, *buf;
	unsigned  o_size, hval;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return;
	}

	if (!fname || !*fname)
	{	db_error = DB_INVALID_NAME;
		return;
	}

	df = db_open(path, fname);
	if (db_error) return;

	fh  = (FILE_HDR)df->df_fhdr;
	buf = (char *)calloc(fh->fh_rec_size, 1);
	if (!buf)
	{	db_error = DB_ALLOC_ERROR;
		return;
	}

	db_read_first(df, buf, &o_size);
	while (!db_error)
	{	dobj = (DOBJ) calloc(o_size, 1);
		if (!dobj) 
		{	db_error = DB_ALLOC_ERROR;
			free(buf);
			return;
		}

		memcpy(dobj, buf, o_size);

		o_name           = &dobj->data + dobj->d_size;
		hval             = db_dict_hash(o_name);
		dobj->next       = dict->htbl[hval];
		dict->htbl[hval] = dobj;

		db_read_next(df, buf, &o_size);
	}
	if (db_error = DB_END_OF_FILE) db_error = 0;
	free(buf);
	db_close(df);
}

/*
 *	db_dict_dump - Dump dictionary objects to a file
 */

void db_dict_dump(dict, path, fname)
 DICT  dict; 
 char *path, *fname;
{
	DATA_FILE df;
	DOBJ      dobj;
	unsigned  o_size, i, cnt, max_size;
	char      options[50];

	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return;
	}

	if (!fname || !*fname)
	{	db_error = DB_INVALID_NAME;
		return;
	}

	for (i=0, cnt=0, max_size=0; i<DICT_HASH_SIZE; i++)
	{	dobj = dict->htbl[i];
		while (dobj)
		{	o_size = sizeof(struct db_dict_obj) + dobj->d_size
			       + dobj->n_size;
			if (o_size > max_size) max_size = o_size;	
			cnt++;
			dobj = dobj->next;
		}
	}

	if (!cnt)
	{	db_error = DB_REC_NOT_FOUND;
		return;
	}

	sprintf(options,"VAR, REC=%d", max_size);
	df = db_create(path, fname, options);
	if (db_error) return;

	for (i=0; i<DICT_HASH_SIZE; i++)
	{	dobj = dict->htbl[i];
		while (dobj)
		{	o_size = sizeof(struct db_dict_obj) + dobj->d_size
			       + dobj->n_size;
			db_add(df, dobj, o_size);
			if (db_error) return;
			dobj = dobj->next;
		}
	}
	db_close(df);
}

/*
 *	db_dict_close - Close a dictionary and dispose of its contents
 */

void db_dict_close(dict)
 DICT dict;
{
	DOBJ  dobj, next;
	short i;


	db_error = 0;

	if (!dict || dict->magic != DICT_MAGIC) 
	{	db_error = DB_INVALID_DICT;
		return;
	}

	for (i=0; i<DICT_HASH_SIZE; i++)
	{	dobj = dict->htbl[i];
		while (dobj)
		{	next = dobj->next;
			free(dobj);
			dobj = next;
		}
	}
	dict->magic = 0;
	free(dict);
}

/*
 *	strupr - convert string to upper case
 */

static void strupr(str)
 char *str;
{
	while (*str)
	{	if (islower(*str)) *str = toupper(*str);
		str++;
	}
}

⌨️ 快捷键说明

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