/*
 * db.c - a simple database
 * Copyright (C) 1996 by candy
 */
char rcsid_db[] = "$Id: db.c,v 3.6 1996/11/28 09:01:20 candy Exp $";
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "db.h"

#ifdef NO_MEMMOVE
#define memmove(d,s,l) bcopy(s,d,l)
#endif

struct db_t *
db_new(size_t max, int (*comp)(const void *, const void *))
{
	struct db_t *db = malloc(sizeof(*db));
	if (db != NULL) {
		db->db_max = max;
		db->db_used = 0;
		db->db_comp = comp;
		db->db_table = malloc(sizeof(*db->db_table) * max);
		if (db->db_table == NULL) {
			free(db);
			db = NULL;
		}
	}
	return db;
}/* db_new */

void
db_free(struct db_t *db)
{
	free(db->db_table);
	free(db);
}/* db_free */

void *
db_install(struct db_t *db, const void *data)
{
	void *ret = NULL;
	if (db->db_used < db->db_max) {
		void **tab = db->db_table;
		int i = 0;
		while (i < db->db_used && db->db_comp(tab[i], data) < 0)
			i++;
		if (i < db->db_used)
			memmove(&tab[i + 1], &tab[i], sizeof(*tab) * (db->db_used - i));
		tab[i] = (void *)data;
		db->db_used++;
		ret = (void *)data;
	}
	return ret;
}/* db_install */

static int (*cur_comp)(const void *, const void *);

static int
std_comp(const void *d_, const void *s_)
{
	void * const *d = d_, * const *s = s_;
	return cur_comp(*d, *s);
}/* std_comp */

void *
db_lookup(struct db_t *db, const void *data)
{
	void *ret;
	cur_comp = db->db_comp;
	ret = bsearch(&data, db->db_table, db->db_used, sizeof(*db->db_table), std_comp);
	if (ret != NULL)
		ret = *(void **)ret;
	return ret;
}/* db_lookup */
