]> mj.ucw.cz Git - libucw.git/blob - lib/db-emul.c
bugfix in image scaling (select the correct strategy)
[libucw.git] / lib / db-emul.c
1 /*
2  *      UCW Library -- SDBM emulator at top of GDBM
3  *
4  *      (c) 1999 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/db.h"
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include <gdbm.h>
18
19 struct sdbm {
20   GDBM_FILE db;
21   datum prevkey;
22 };
23
24 struct sdbm *
25 sdbm_open(struct sdbm_options *o)
26 {
27   struct sdbm *d = xmalloc(sizeof(struct sdbm));
28   d->db = gdbm_open(o->name,
29                     (o->page_order ? (1 << o->page_order) : 0),
30                     ((o->flags & SDBM_WRITE) ? ((o->flags & SDBM_CREAT) ? GDBM_WRCREAT : GDBM_WRITER) : GDBM_READER)
31                       | ((o->flags & SDBM_SYNC) ? GDBM_SYNC : 0),
32                     0666,
33                     NULL);
34   if (o->cache_size)
35     gdbm_setopt(d->db, GDBM_CACHESIZE, &o->cache_size, sizeof(o->cache_size));
36   d->prevkey.dptr = NULL;
37   return d;
38 }
39
40 void
41 sdbm_close(struct sdbm *d)
42 {
43   sdbm_rewind(d);
44   gdbm_close(d->db);
45   xfree(d);
46 }
47
48 static int
49 sdbm_put_user(byte *D, uns Dl, byte *val, uns *vallen)
50 {
51   if (vallen)
52     {
53       if (*vallen < Dl)
54         return 1;
55       *vallen = Dl;
56     }
57   if (val)
58     memcpy(val, D, Dl);
59   return 0;
60 }
61
62 int
63 sdbm_store(struct sdbm *d, byte *key, uns keylen, byte *val, uns vallen)
64 {
65   datum K, V;
66   int rc;
67
68   K.dptr = key;
69   K.dsize = keylen;
70   V.dptr = val;
71   V.dsize = vallen;
72   rc = gdbm_store(d->db, K, V, GDBM_INSERT);
73   return (rc < 0) ? rc : !rc;
74 }
75
76 int
77 sdbm_replace(struct sdbm *d, byte *key, uns keylen, byte *val, uns vallen)
78 {
79   datum K, V;
80   int rc;
81
82   if (!val)
83     return sdbm_delete(d, key, keylen);
84   K.dptr = key;
85   K.dsize = keylen;
86   V.dptr = val;
87   V.dsize = vallen;
88   rc = gdbm_store(d->db, K, V, GDBM_REPLACE);
89   return (rc < 0) ? rc : !rc;
90 }
91
92 int
93 sdbm_delete(struct sdbm *d, byte *key, uns keylen)
94 {
95   datum K;
96
97   K.dptr = key;
98   K.dsize = keylen;
99   return !gdbm_delete(d->db, K);
100 }
101
102 int
103 sdbm_fetch(struct sdbm *d, byte *key, uns keylen, byte *val, uns *vallen)
104 {
105   datum K, V;
106   int rc;
107
108   K.dptr = key;
109   K.dsize = keylen;
110   if (!val && !vallen)
111     return gdbm_exists(d->db, K);
112   V = gdbm_fetch(d->db, K);
113   if (!V.dptr)
114     return 0;
115   rc = sdbm_put_user(V.dptr, V.dsize, val, vallen);
116   xfree(V.dptr);
117   return rc ? SDBM_ERROR_TOO_LARGE : 1;
118 }
119
120 void
121 sdbm_rewind(struct sdbm *d)
122 {
123   if (d->prevkey.dptr)
124     {
125       xfree(d->prevkey.dptr);
126       d->prevkey.dptr = NULL;
127     }
128 }
129
130 int
131 sdbm_get_next(struct sdbm *d, byte *key, uns *keylen, byte *val, uns *vallen)
132 {
133   datum K;
134
135   if (d->prevkey.dptr)
136     {
137       K = gdbm_nextkey(d->db, d->prevkey);
138       xfree(d->prevkey.dptr);
139     }
140   else
141     K = gdbm_firstkey(d->db);
142   d->prevkey = K;
143   if (!K.dptr)
144     return 0;
145   if (sdbm_put_user(K.dptr, K.dsize, key, keylen))
146     return SDBM_ERROR_TOO_LARGE;
147   if (val || vallen)
148     return sdbm_fetch(d, key, *keylen, val, vallen);
149   return 1;
150 }
151
152 void
153 sdbm_sync(struct sdbm *d)
154 {
155 }