lookup
db iddata(&cdbtcl_databases)
key obj
+ ?def obj
=> obj
lookup-hb
db iddata(&cdbtcl_databases)
key hb
- => hb
+ ?def obj
+ => obj
close
db iddata(&cdbtcl_databases)
/*---------- from lookup.c ----------*/
-int cht_cdb_dosomelookup(Tcl_Interp *ip, void *db_v,
- const char *key, Tcl_Obj *def,
- Tcl_Obj **result,
- int (*somelookup)(Tcl_Interp *ip, void *db_v,
- const char *key,
- const Byte **data_r, int *len_r),
- int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result,
- const Byte *data, int len));
+int cht_cdb_donesomelookup(Tcl_Interp *ip, void *db_v,
+ Tcl_Obj *def, Tcl_Obj **result,
+ const Byte *data, int dlen,
+ int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result,
+ const Byte *data, int len));
int cht_cdb_storeanswer_string(Tcl_Interp *ip, Tcl_Obj **result,
const Byte *data, int len);
int cht_cdb_storeanswer_hb(Tcl_Interp *ip, Tcl_Obj **result,
const Byte *data, int len);
+int cht_cdb_lookup_cdb(Tcl_Interp *ip, struct cdb *cdb,
+ const Byte *key, int klen,
+ const Byte **data_r, int *dlen_r);
+
+/*---------- macros ----------*/
+
+#define PE(m) do{ \
+ rc= cht_posixerr(ip, errno, "failed to " m); goto x_rc; \
+ }while(0)
#endif /*CHIARK_TCL_CDB_H*/
#include "chiark_tcl_cdb.h"
-int cht_cdb_dosomelookup(Tcl_Interp *ip, void *db_v,
- const char *key, Tcl_Obj *def,
- Tcl_Obj **result,
- int (*somelookup)(Tcl_Interp *ip, void *db_v,
- const char *key,
- const Byte **data_r, int *len_r),
- int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result,
- const Byte *data, int len)) {
- int r, len;
- const Byte *data;
-
- r= somelookup(ip, db_v, key, &data, &len);
- if (r) return r;
- if (len>0) return storeanswer(ip, result, data, len);
+int cht_cdb_donesomelookup(Tcl_Interp *ip, void *db_v,
+ Tcl_Obj *def, Tcl_Obj **result,
+ const Byte *data, int dlen,
+ int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result,
+ const Byte *data, int len)) {
+ if (dlen>0) return storeanswer(ip, result, data, dlen);
if (def) { *result= def; return TCL_OK; }
return cht_staticerr(ip, "cdbwr lookup key not found", "CDB NOTFOUND");
}
*result= cht_ret_hb(ip, val);
return TCL_OK;
}
+
+int cht_cdb_lookup_cdb(Tcl_Interp *ip, struct cdb *cdb,
+ const Byte *key, int klen,
+ const Byte **data_r, int *len_r) {
+ int r;
+
+ r= cdb_find(cdb, key, klen);
+ if (!r) { *data_r= 0; *len_r= -1; return TCL_OK; }
+ if (r<0) return cht_posixerr(ip, errno, "cdb_find failed");
+ assert(r==1);
+ *len_r= cdb_datalen(cdb);
+ assert(*len_r > 0);
+ *data_r= cdb_getdata(cdb);
+ if (!*data_r) return cht_posixerr(ip, errno, "cdb_getdata failed");
+ return TCL_OK;
+}
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);
+}
if (fd>=0) close(fd);
}
-#define PE(m) do{ \
- rc= cht_posixerr(ip, errno, "failed to " m); goto x_rc; \
- }while(0)
-
/*==================== Subsystems and subtypes ====================*/
/*---------- Pathbuf ----------*/
}
mainfd= open(pathbuf_sfx(&rw->pbsome,".main"), O_RDONLY);
- if (mainfd<0) PE("open exist3ing database file .main");
+ if (mainfd<0) PE("open existing database file .main");
rc= acquire_lock(ip, &rw->pbsome, &rw->lock_fd); if (rc) goto x_rc;
r= fstat(mainfd, &stab); if (r) PE("fstat .main");
const Byte **data_r, int *len_r /* -1 => notfound */) {
Rw *rw= rw_v;
const HashValue *val;
- int r;
val= ht_lookup(&rw->logincore, key);
if (val) {
else { *data_r= 0; *len_r= -1; return TCL_OK; }
}
- r= cdb_find(&rw->cdb, key, strlen(key));
- if (!r) { *data_r= 0; *len_r= -1; return TCL_OK; }
- if (r<0) return cht_posixerr(ip, errno, "cdb_find failed");
- assert(r==1);
- *len_r= cdb_datalen(&rw->cdb);
- assert(*len_r > 0);
- *data_r= cdb_getdata(&rw->cdb);
- if (!*data_r) return cht_posixerr(ip, errno, "cdb_getdata failed");
- return TCL_OK;
+ return cht_cdb_lookup_cdb(ip, &rw->cdb, key, strlen(key), data_r, len_r);
}
int cht_do_cdbwr_lookup(ClientData cd, Tcl_Interp *ip, void *rw_v,
const char *key, Tcl_Obj *def,
Tcl_Obj **result) {
- return cht_cdb_dosomelookup(ip, rw_v, key, def, result,
- lookup_rw, cht_cdb_storeanswer_string);
+ const Byte *data;
+ int dlen, r;
+
+ r= lookup_rw(ip, rw_v, key, &data, &dlen); if (r) return r;
+ return cht_cdb_donesomelookup(ip, rw_v, def, result, data, dlen,
+ cht_cdb_storeanswer_string);
}
int cht_do_cdbwr_lookup_hb(ClientData cd, Tcl_Interp *ip, void *rw_v,
const char *key, Tcl_Obj *def,
Tcl_Obj **result) {
- return cht_cdb_dosomelookup(ip, rw_v, key, def, result,
- lookup_rw, cht_cdb_storeanswer_hb);
+ const Byte *data;
+ int dlen, r;
+
+ r= lookup_rw(ip, rw_v, key, &data, &dlen); if (r) return r;
+ return cht_cdb_donesomelookup(ip, rw_v, def, result, data, dlen,
+ cht_cdb_storeanswer_hb);
}