From 9b3b0ecccff2620fc82bf77d872ba0c9f841201f Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Mon, 15 Nov 1999 22:46:56 +0000 Subject: [PATCH] Added emulator of SDBM on top of GDBM. --- lib/db-emul.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 lib/db-emul.c diff --git a/lib/db-emul.c b/lib/db-emul.c new file mode 100644 index 00000000..533c996f --- /dev/null +++ b/lib/db-emul.c @@ -0,0 +1,152 @@ +/* + * Sherlock Library -- SDBM emulator at top of GDBM + * + * (c) 1999 Martin Mares + */ + +#include +#include +#include + +#include "lib.h" +#include "db.h" + +#include + +struct sdbm { + GDBM_FILE db; + datum prevkey; +}; + +struct sdbm * +sdbm_open(struct sdbm_options *o) +{ + struct sdbm *d = xmalloc(sizeof(struct sdbm)); + d->db = gdbm_open(o->name, + (o->page_order ? (1 << o->page_order) : 0), + ((o->flags & SDBM_WRITE) ? ((o->flags & SDBM_CREAT) ? GDBM_WRCREAT : GDBM_WRITER) : GDBM_READER) + | ((o->flags & SDBM_SYNC) ? GDBM_SYNC : 0), + 0666, + NULL); + if (o->cache_size) + gdbm_setopt(d->db, GDBM_CACHESIZE, &o->cache_size, sizeof(o->cache_size)); + d->prevkey.dptr = NULL; + return d; +} + +void +sdbm_close(struct sdbm *d) +{ + sdbm_rewind(d); + gdbm_close(d->db); + free(d); +} + +static int +sdbm_put_user(byte *D, uns Dl, byte *val, uns *vallen) +{ + if (vallen) + { + if (*vallen < Dl) + return 1; + *vallen = Dl; + } + if (val) + memcpy(val, D, Dl); + return 0; +} + +int +sdbm_store(struct sdbm *d, byte *key, uns keylen, byte *val, uns vallen) +{ + datum K, V; + int rc; + + K.dptr = key; + K.dsize = keylen; + V.dptr = val; + V.dsize = vallen; + rc = gdbm_store(d->db, K, V, GDBM_INSERT); + return (rc < 0) ? rc : !rc; +} + +int +sdbm_replace(struct sdbm *d, byte *key, uns keylen, byte *val, uns vallen) +{ + datum K, V; + int rc; + + if (!val) + return sdbm_delete(d, key, keylen); + K.dptr = key; + K.dsize = keylen; + V.dptr = val; + V.dsize = vallen; + rc = gdbm_store(d->db, K, V, GDBM_REPLACE); + return (rc < 0) ? rc : !rc; +} + +int +sdbm_delete(struct sdbm *d, byte *key, uns keylen) +{ + datum K; + + K.dptr = key; + K.dsize = keylen; + return !gdbm_delete(d->db, K); +} + +int +sdbm_fetch(struct sdbm *d, byte *key, uns keylen, byte *val, uns *vallen) +{ + datum K, V; + int rc; + + K.dptr = key; + K.dsize = keylen; + if (!val && !vallen) + return gdbm_exists(d->db, K); + V = gdbm_fetch(d->db, K); + if (!V.dptr) + return 0; + rc = sdbm_put_user(V.dptr, V.dsize, val, vallen); + free(V.dptr); + return rc ? SDBM_ERROR_TOO_LARGE : 1; +} + +void +sdbm_rewind(struct sdbm *d) +{ + if (d->prevkey.dptr) + { + free(d->prevkey.dptr); + d->prevkey.dptr = NULL; + } +} + +int +sdbm_get_next(struct sdbm *d, byte *key, uns *keylen, byte *val, uns *vallen) +{ + datum K; + + if (d->prevkey.dptr) + { + K = gdbm_nextkey(d->db, d->prevkey); + free(d->prevkey.dptr); + } + else + K = gdbm_firstkey(d->db); + d->prevkey = K; + if (!K.dptr) + return 0; + if (sdbm_put_user(K.dptr, K.dsize, key, keylen)) + return SDBM_ERROR_TOO_LARGE; + if (val || vallen) + return sdbm_fetch(d, key, *keylen, val, vallen); + return 1; +} + +void +sdbm_sync(struct sdbm *d) +{ +} -- 2.39.2