Statistics
| Branch: | Tag: | Revision:

root / lib / filter-kvs-gdbm.c @ 351eb643

History | View | Annotate | Download (3.82 KB)

1
/* SylFilter - a message filter
2
 *
3
 * Copyright (C) 2011 Hiroyuki Yamamoto
4
 * Copyright (C) 2011 Sylpheed Development Team
5
 */
6

    
7
#include "config.h"
8

    
9
#ifdef USE_GDBM
10

    
11
#include <stdio.h>
12
#include <string.h>
13
#include <stdlib.h>
14
#include <glib.h>
15
#include <gdbm.h>
16

    
17
#include "filter-kvs.h"
18
#include "filter-kvs-gdbm.h"
19

    
20
static XFilterKVS *xf_gdbm_open(const char *dbfile);
21
static int xf_gdbm_close(XFilterKVS *kvs);
22
static int xf_gdbm_insert(XFilterKVS *kvs, const char *key, void *value, int size);
23
static int xf_gdbm_delete(XFilterKVS *kvs, const char *key);
24
static int xf_gdbm_update(XFilterKVS *kvs, const char *key, void *value, int size);
25
static int xf_gdbm_fetch(XFilterKVS *kvs, const char *key, void *vbuf, int vsize);
26
static int xf_gdbm_size(XFilterKVS *kvs);
27
static int xf_gdbm_foreach(XFilterKVS *kvs, XFilterKVSForeachFunc func, void *data);
28

    
29

    
30
int xfilter_kvs_gdbm_set_engine(void)
31
{
32
        XFilterKVSEngine engine = {
33
                xf_gdbm_open,
34
                xf_gdbm_close,
35
                xf_gdbm_insert,
36
                xf_gdbm_delete,
37
                xf_gdbm_update,
38
                xf_gdbm_fetch,
39
                NULL,
40
                NULL,
41
                xf_gdbm_size,
42
                xf_gdbm_foreach
43
        };
44

    
45
        return xfilter_kvs_set_engine(&engine);
46
}
47

    
48
static XFilterKVS *xf_gdbm_open(const char *dbfile)
49
{
50
        GDBM_FILE dbf;
51

    
52
        dbf = gdbm_open((char *)dbfile, 0, GDBM_WRCREAT, 0600, 0);
53
        if (!dbf) {
54
                fprintf(stderr, "xf_gdbm_open: %s: %s\n",
55
                        dbfile, gdbm_strerror(gdbm_errno));
56
                return NULL;
57
        }
58
        return xfilter_kvs_new(dbfile, (void *)dbf);
59
}
60

    
61
static int xf_gdbm_close(XFilterKVS *kvs)
62
{
63
        gdbm_close((GDBM_FILE)xfilter_kvs_get_handle(kvs));
64
        return 0;
65
}
66

    
67
static int xf_gdbm_insert(XFilterKVS *kvs, const char *key, void *value, int size)
68
{
69
        GDBM_FILE dbf;
70
        datum dkey, dvalue;
71

    
72
        dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
73

    
74
        dkey.dptr = (char *)key;
75
        dkey.dsize = strlen(key);
76
        dvalue.dptr = (char *)value;
77
        dvalue.dsize = size;
78
        if (gdbm_store(dbf, dkey, dvalue, GDBM_INSERT) != 0)
79
                return -1;
80

    
81
        return 0;
82
}
83

    
84
static int xf_gdbm_delete(XFilterKVS *kvs, const char *key)
85
{
86
        GDBM_FILE dbf;
87
        datum dkey;
88

    
89
        dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
90

    
91
        dkey.dptr = (char *)key;
92
        dkey.dsize = strlen(key);
93
        if (gdbm_delete(dbf, dkey) != 0)
94
                return -1;
95

    
96
        return 0;
97
}
98

    
99
static int xf_gdbm_update(XFilterKVS *kvs, const char *key, void *value, int size)
100
{
101
        GDBM_FILE dbf;
102
        datum dkey, dvalue;
103

    
104
        dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
105

    
106
        dkey.dptr = (char *)key;
107
        dkey.dsize = strlen(key);
108
        dvalue.dptr = (char *)value;
109
        dvalue.dsize = size;
110
        if (gdbm_store(dbf, dkey, dvalue, GDBM_REPLACE) != 0)
111
                return -1;
112

    
113
        return 0;
114
}
115

    
116
static int xf_gdbm_fetch(XFilterKVS *kvs, const char *key, void *vbuf, int vsize)
117
{
118
        GDBM_FILE dbf;
119
        datum dkey, dvalue;
120

    
121
        dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
122

    
123
        dkey.dptr = (char *)key;
124
        dkey.dsize = strlen(key);
125
        dvalue = gdbm_fetch(dbf, dkey);
126
        if (!dvalue.dptr)
127
                return -1;
128

    
129
        memcpy(vbuf, dvalue.dptr, MIN(vsize, dvalue.dsize));
130
        free(dvalue.dptr);
131

    
132
        return dvalue.dsize;
133
}
134

    
135
static int xf_gdbm_size(XFilterKVS *kvs)
136
{
137
        GDBM_FILE dbf;
138
        datum dkey, nkey;
139
        int size = 0;
140

    
141
        dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
142

    
143
        for (dkey = gdbm_firstkey(dbf); dkey.dptr; size++) {
144
                nkey = gdbm_nextkey(dbf, dkey);
145
                free(dkey.dptr);
146
                dkey = nkey;
147
        }
148

    
149
        return size;
150
}
151

    
152
static int xf_gdbm_foreach(XFilterKVS *kvs, XFilterKVSForeachFunc func, void *data)
153
{
154
        GDBM_FILE dbf;
155
        datum dkey, dvalue, nkey;
156
        char key[1024];
157
        int ksize;
158

    
159
        dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
160

    
161
        dkey = gdbm_firstkey(dbf);
162
        for (dkey = gdbm_firstkey(dbf); dkey.dptr; ) {
163
                int r;
164

    
165
                dvalue = gdbm_fetch(dbf, dkey);
166
                if (!dvalue.dptr) {
167
                        free(dkey.dptr);
168
                        break;
169
                }
170
                ksize = MIN(sizeof(key) - 1, dkey.dsize);
171
                memcpy(key, dkey.dptr, ksize);
172
                key[ksize] = '\0';
173
                r = func(kvs, key, dvalue.dptr, dvalue.dsize, data);
174
                if (r < 0) {
175
                        free(dvalue.dptr);
176
                        free(dkey.dptr);
177
                        break;
178
                }
179
                nkey = gdbm_nextkey(dbf, dkey);
180
                free(dvalue.dptr);
181
                free(dkey.dptr);
182

    
183
                dkey = nkey;
184
        }
185

    
186
        return 0;
187
}
188

    
189
#endif /* USE_GDBM */