1 /* GDBM module, hacked from the still-breathing corpse of the
2 DBM module by anthony.baxter@aaii.oz.au. Original copyright
5 /***********************************************************
6 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
11 Permission to use, copy, modify, and distribute this software and its
12 documentation for any purpose and without fee is hereby granted,
13 provided that the above copyright notice appear in all copies and that
14 both that copyright notice and this permission notice appear in
15 supporting documentation, and that the names of Stichting Mathematisch
16 Centrum or CWI not be used in advertising or publicity pertaining to
17 distribution of the software without specific, written prior permission.
19 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
20 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
22 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
25 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 ******************************************************************/
29 /* DBM module using dictionary interface */
32 #include "allobjects.h"
33 #include "modsupport.h"
35 #include <sys/types.h>
42 int di_size
; /* -1 means recompute */
46 staticforward typeobject Dbmtype
;
48 #define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
50 static object
*DbmError
;
53 newdbmobject(file
, flags
, mode
)
60 dp
= NEWOBJ(dbmobject
, &Dbmtype
);
65 if ( (dp
->di_dbm
= gdbm_open(file
, 0, flags
, mode
, NULL
)) == 0 ) {
69 err_setstr(DbmError
, (char *) gdbm_strerror(gdbm_errno
));
80 register dbmobject
*dp
;
83 gdbm_close(dp
->di_dbm
);
91 if ( dp
->di_size
< 0 ) {
97 for ( key
=gdbm_firstkey(dp
->di_dbm
); key
.dptr
;
98 key
= gdbm_nextkey(dp
->di_dbm
,okey
)) {
100 if(okey
.dsize
) free(okey
.dptr
);
109 dbm_subscript(dp
, key
)
111 register object
*key
;
116 if (!getargs(key
, "s#", &krec
.dptr
, &krec
.dsize
) )
119 drec
= gdbm_fetch(dp
->di_dbm
, krec
);
120 if ( drec
.dptr
== 0 ) {
121 err_setstr(KeyError
, GETSTRINGVALUE((stringobject
*)key
));
124 v
= newsizedstringobject(drec
.dptr
, drec
.dsize
);
130 dbm_ass_sub(dp
, v
, w
)
136 if ( !getargs(v
, "s#", &krec
.dptr
, &krec
.dsize
) ) {
137 err_setstr(TypeError
, "gdbm mappings have string indices only");
142 if ( gdbm_delete(dp
->di_dbm
, krec
) < 0 ) {
143 err_setstr(KeyError
, GETSTRINGVALUE((stringobject
*)v
));
147 if ( !getargs(w
, "s#", &drec
.dptr
, &drec
.dsize
) ) {
148 err_setstr(TypeError
,
149 "gdbm mappings have string elements only");
153 if ( gdbm_store(dp
->di_dbm
, krec
, drec
, GDBM_REPLACE
) < 0 ) {
157 err_setstr(DbmError
, (char *) gdbm_strerror(gdbm_errno
));
164 static mapping_methods dbm_as_mapping
= {
165 (inquiry
)dbm_length
, /*mp_length*/
166 (binaryfunc
)dbm_subscript
, /*mp_subscript*/
167 (objobjargproc
)dbm_ass_sub
, /*mp_ass_subscript*/
172 register dbmobject
*dp
;
175 register object
*v
, *item
;
176 datum key
, okey
={ (char *)NULL
, 0};
178 if (dp
== NULL
|| !is_dbmobject(dp
)) {
184 v
= newlistobject(0);
187 for (key
= gdbm_firstkey(dp
->di_dbm
); key
.dptr
;
188 key
= gdbm_nextkey(dp
->di_dbm
,okey
) ) {
189 item
= newsizedstringobject(key
.dptr
, key
.dsize
);
192 addlistitem(v
, item
);
193 if(okey
.dsize
) free(okey
.dptr
);
201 dbm_has_key(dp
, args
)
202 register dbmobject
*dp
;
207 if (!getargs(args
, "s#", &key
.dptr
, &key
.dsize
))
209 return newintobject((long) gdbm_exists(dp
->di_dbm
, key
));
212 static struct methodlist dbm_methods
[] = {
213 {"keys", (method
)dbm_keys
},
214 {"has_key", (method
)dbm_has_key
},
215 {NULL
, NULL
} /* sentinel */
219 dbm_getattr(dp
, name
)
223 return findmethod(dbm_methods
, (object
*)dp
, name
);
226 static typeobject Dbmtype
= {
227 OB_HEAD_INIT(&Typetype
)
232 (destructor
)dbm_dealloc
, /*tp_dealloc*/
234 (getattrfunc
)dbm_getattr
, /*tp_getattr*/
239 0, /*tp_as_sequence*/
240 &dbm_as_mapping
, /*tp_as_mapping*/
243 /* ----------------------------------------------------------------- */
253 /* XXXX add other flags */
254 if ( !getargs(args
, "(ssi)", &name
, &flags
, &mode
) )
256 if ( strcmp(flags
, "r") == 0 )
257 iflags
= GDBM_READER
;
258 else if ( strcmp(flags
, "w") == 0 )
259 iflags
= GDBM_WRITER
;
260 else if ( strcmp(flags
, "c") == 0 )
261 iflags
= GDBM_WRCREAT
;
262 else if ( strcmp(flags
, "n") == 0 )
266 "Flags should be one of 'r', 'w', 'c' or 'n'");
269 return newdbmobject(name
, iflags
, mode
);
272 static struct methodlist dbmmodule_methods
[] = {
273 { "open", (method
)dbmopen
},
281 m
= initmodule("gdbm", dbmmodule_methods
);
282 d
= getmoduledict(m
);
283 DbmError
= newstringobject("gdbm.error");
284 if ( DbmError
== NULL
|| dictinsert(d
, "error", DbmError
) )
285 fatal("can't define gdbm.error");