X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=cdb%2Freadonly.c;h=7a3ba446439b825fa8b51c05ba62b48d486b69ff;hp=b644a1d9c72908a133841d516e71fdc8a9234d17;hb=5dca360f2da544c9b6baf9d18ad8cd0b0e073e60;hpb=7795b9e72903475e48adbc986a945ef3a7fb0309 diff --git a/cdb/readonly.c b/cdb/readonly.c index b644a1d..7a3ba44 100644 --- a/cdb/readonly.c +++ b/cdb/readonly.c @@ -1,9 +1,103 @@ -/**/ +/* + * cdb, cdb-wr - Tcl bindings for tinycdb and a journalling write extension + * Copyright 2006 Ian Jackson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ #include "chiark_tcl_cdb.h" -static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *val) { abort(); } +typedef struct Ro { + int ix, fd; + struct cdb cdb; +} Ro; + +static void ro_close(Ro *ro) { + cdb_free(&ro->cdb); + close(ro->fd); +} + +static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *ro_v) { + ro_close(ro_v); + TFREE(ro_v); +} const IdDataSpec cdbtcl_databases= { "cdb-db", "cdb-opendatabases-table", destroy_cdb_idtabcb }; + +int cht_do_cdb_open(ClientData cd, Tcl_Interp *ip, + const char *path, void **result) { + Ro *ro; + int rc, r; + + ro= TALLOC(sizeof(*ro)); + ro->ix= -1; + ro->fd= open(path, O_RDONLY); + if (ro->fd<0) PE("open database file"); + r= cdb_init(&ro->cdb, ro->fd); + if (r) PE("initialise cdb"); + *result= ro; + return TCL_OK; + + x_rc: + if (ro->fd >= 0) close(ro->fd); + return rc; +} + +int cht_do_cdb_close(ClientData cd, Tcl_Interp *ip, void *ro_v) { + ro_close(ro_v); + cht_tabledataid_disposing(ip, ro_v, &cdbtcl_databases); + TFREE(ro_v); + return TCL_OK; +} + +int cht_do_cdb_lookup(ClientData cd, Tcl_Interp *ip, void *ro_v, + Tcl_Obj *keyo, Tcl_Obj *def, Tcl_Obj **result) { + Ro *ro= ro_v; + const Byte *key; + const Byte *data; + int r, dlen, klen; + + key= Tcl_GetStringFromObj(keyo, &klen); assert(key); + + r= cht_cdb_lookup_cdb(ip, &ro->cdb, key, klen, &data, &dlen); + if (r) return r; + + return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen, + cht_cdb_storeanswer_string); +} + +int cht_do_cdb_lookup_hb(ClientData cd, Tcl_Interp *ip, void *ro_v, + HBytes_Value key, Tcl_Obj *def, Tcl_Obj **result) { + Ro *ro= ro_v; + const Byte *data; + int r, dlen; + + r= cht_cdb_lookup_cdb(ip, &ro->cdb, + cht_hb_data(&key), cht_hb_len(&key), + &data, &dlen); + if (r) return r; + + return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen, + cht_cdb_storeanswer_hb); +} + +int cht_do_cdbtoplevel_cdb(ClientData cd, Tcl_Interp *ip, + const Cdb_SubCommand* subcmd, + int objc, Tcl_Obj *const *objv) { + return subcmd->func((void*)subcmd,ip,objc,objv); +}