X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=cdb%2Freadonly.c;h=d9f3eefcf2a3b65ee6e738f9d8586b8ea9b9080d;hp=b644a1d9c72908a133841d516e71fdc8a9234d17;hb=602f89cabd45c343f6adb4b788d26d316f5be47b;hpb=9eb8c5c8a5caa7264d7d3464cf650baffb42a05c diff --git a/cdb/readonly.c b/cdb/readonly.c index b644a1d..d9f3eef 100644 --- a/cdb/readonly.c +++ b/cdb/readonly.c @@ -7,3 +7,65 @@ static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *val) { abort(); } const IdDataSpec cdbtcl_databases= { "cdb-db", "cdb-opendatabases-table", destroy_cdb_idtabcb }; + +typedef struct Ro { + int ix, fd; + struct cdb cdb; +} Ro; + +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->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 *ro= ro_v; + cdb_free(&ro->cdb); + close(ro->fd); + TFREE(ro); + 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); +}