chiark / gitweb /
3bfa98bbb68bd3a691894e7b4772973938815a96
[chiark-tcl.git] / cdb / readonly.c
1 /**/
2
3 #include "chiark_tcl_cdb.h"
4
5 typedef struct Ro {
6   int ix, fd;
7   struct cdb cdb;
8 } Ro;
9
10 static void ro_close(Ro *ro) {
11   cdb_free(&ro->cdb);
12   close(ro->fd);
13 }
14
15 static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *ro_v) {
16   ro_close(ro_v);
17   TFREE(ro_v);
18 }
19
20 const IdDataSpec cdbtcl_databases= {
21   "cdb-db", "cdb-opendatabases-table", destroy_cdb_idtabcb
22 };
23
24 int cht_do_cdb_open(ClientData cd, Tcl_Interp *ip,
25                     const char *path, void **result) {
26   Ro *ro;
27   int rc, r;
28
29   ro= TALLOC(sizeof(*ro));
30   ro->ix= -1;
31   ro->fd= open(path, O_RDONLY);
32   if (ro->fd<0) PE("open database file");
33   r= cdb_init(&ro->cdb, ro->fd);
34   if (r) PE("initialise cdb");
35   *result= ro;
36   return TCL_OK;
37
38  x_rc:
39   if (ro->fd >= 0) close(ro->fd);
40   return rc;
41 }
42
43 int cht_do_cdb_close(ClientData cd, Tcl_Interp *ip, void *ro_v) {
44   ro_close(ro_v);
45   cht_tabledataid_disposing(ip, ro_v, &cdbtcl_databases);
46   TFREE(ro_v);
47   return TCL_OK;
48 }
49
50 int cht_do_cdb_lookup(ClientData cd, Tcl_Interp *ip, void *ro_v,
51                       Tcl_Obj *keyo, Tcl_Obj *def, Tcl_Obj **result) {
52   Ro *ro= ro_v;
53   const Byte *key;
54   const Byte *data;
55   int r, dlen, klen;
56
57   key= Tcl_GetStringFromObj(keyo, &klen);  assert(key);
58   
59   r= cht_cdb_lookup_cdb(ip, &ro->cdb, key, klen, &data, &dlen);
60   if (r) return r;
61   
62   return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen,
63                                 cht_cdb_storeanswer_string);
64 }
65
66 int cht_do_cdb_lookup_hb(ClientData cd, Tcl_Interp *ip, void *ro_v,
67                          HBytes_Value key, Tcl_Obj *def, Tcl_Obj **result) {
68   Ro *ro= ro_v;
69   const Byte *data;
70   int r, dlen;
71   
72   r= cht_cdb_lookup_cdb(ip, &ro->cdb,
73                         cht_hb_data(&key), cht_hb_len(&key),
74                         &data, &dlen);
75   if (r) return r;
76   
77   return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen,
78                                 cht_cdb_storeanswer_hb);
79 }
80
81 int cht_do_cdbtoplevel_cdb(ClientData cd, Tcl_Interp *ip,
82                            const Cdb_SubCommand* subcmd,
83                            int objc, Tcl_Obj *const *objv) {
84   return subcmd->func((void*)subcmd,ip,objc,objv);
85 }