00001
00002
00003
00004
00005
00006
00007
#ifndef __WVGDBMHASH_H
00008
#define __WVGDBMHASH_H
00009
00010
#include "wvautoconf.h"
00011
00012
#ifndef HAVE_GDBM_H
00013
# error "Sorry, no gdbm support in wvstreams!"
00014
#endif
00015
00016
#include "wvhashtable.h"
00017
#include "wvserialize.h"
00018
00019
#include <gdbm.h>
00020
00021
00022
00023 class WvGdbmHashBase
00024 {
00025
public:
00026
WvGdbmHashBase(
WvStringParm dbfile);
00027
~WvGdbmHashBase();
00028
00029
int add(
const datum &key,
const datum &data,
bool replace);
00030
int remove(
const datum &key);
00031 datum
find(
const datum &key);
00032
bool exists(
const datum &key);
00033
void zap();
00034
00035 class IterBase
00036 {
00037
public:
00038
IterBase(
WvGdbmHashBase &_gdbmhash);
00039
~IterBase();
00040
void rewind();
00041
void next();
00042
00043
protected:
00044 WvGdbmHashBase &
gdbmhash;
00045 datum
curkey,
nextkey;
00046 datum
curdata;
00047 };
00048
private:
00049
friend class IterBase;
00050 GDBM_FILE dbf;
00051 };
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
template <
class K,
class D>
00064 class WvGdbmHash :
public WvGdbmHashBase
00065 {
00066
public:
00067
00068
00069
00070
template <
typename T>
00071 class datumize :
public datum
00072 {
00073
datumize(
datumize &);
00074
public:
00075 WvDynBuf buf;
00076
00077 datumize(
const T &t)
00078 {
00079
wv_serialize(
buf, t);
00080 dsize =
buf.
used();
00081 dptr = (
char *)
buf.
peek(0,
buf.
used());
00082 }
00083 };
00084
00085
template <
typename T>
00086 static T undatumize(datum &data)
00087 {
00088
WvConstInPlaceBuf buf(data.dptr, data.dsize);
00089
return wv_deserialize<T>(buf);
00090 }
00091
00092
protected:
00093 D *saveddata;
00094
00095
public:
00096 WvGdbmHash(
WvStringParm dbfile) :
WvGdbmHashBase(dbfile)
00097 { saveddata = NULL; }
00098
00099 void add(
const K &key,
const D &data,
bool replace =
false)
00100 {
00101
int r = WvGdbmHashBase::add(datumize<K>(key),
00102 datumize<D>(data), replace);
00103 assert(!r &&
"Set the replace flag to replace existing elements.");
00104 }
00105
00106 void remove(
const K &key)
00107 { WvGdbmHashBase::remove(datumize<K>(key)); }
00108
00109 D &find(
const K &key)
00110 {
00111
if (saveddata)
00112
delete saveddata;
00113 datum s = WvGdbmHashBase::find(datumize<K>(key));
00114 saveddata = undatumize<D *>(s);
00115 free(s.dptr);
00116
return *saveddata;
00117 }
00118
00119 D &operator[] (
const K &key)
00120 {
return find(key); }
00121
00122 bool exists(
const K &key)
00123 {
return WvGdbmHashBase::exists(datumize<K>(key)); }
00124
00125 class Iter :
public WvGdbmHashBase::IterBase
00126 {
00127 K *k;
00128 D *d;
00129
public:
00130 Iter(
WvGdbmHash &_gdbmhash) : IterBase(_gdbmhash)
00131 { k = NULL; d = NULL; }
00132 ~Iter()
00133 {
00134
if (k)
delete k;
00135
if (d)
delete d;
00136 }
00137
00138 bool next()
00139 {
00140
if (!nextkey.dptr)
00141
return false;
00142
if (k)
delete k;
00143
if (d)
delete d;
00144 IterBase::next();
00145
if (curdata.dptr)
00146 {
00147 k = undatumize<K *>(curkey);
00148 d = undatumize<D *>(curdata);
00149
return true;
00150 }
00151
else
00152 {
00153 k = NULL;
00154 d = NULL;
00155
return false;
00156 }
00157 }
00158
00159 bool cur()
00160 {
return curdata.dptr; }
00161
00162 K &
key()
const
00163
{
return *k; }
00164
00165 D *
ptr()
const
00166
{
return d; }
00167
WvIterStuff(D);
00168 };
00169 };
00170
00171
#endif // __WVGDBMHASH_H