mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-11 15:04:23 +00:00
223 lines
4.4 KiB
C
223 lines
4.4 KiB
C
/* radare - LGPL - Copyright 2011-2012 pancake<nopcode.org> */
|
|
|
|
#include <r_db.h>
|
|
#include <r_util.h>
|
|
#include "sdb/src/sdb.h"
|
|
|
|
R_API void r_pair_set_file (RPair*p, const char *file) {
|
|
if (!file || !*file) return;
|
|
if (p->file) free (p->file);
|
|
p->file = strdup (file);
|
|
if (p->sdb) {
|
|
Sdb *sdb = p->sdb;
|
|
sdb->dir = p->file;
|
|
} else eprintf ("no sdb set\n");
|
|
}
|
|
|
|
R_API void r_pair_fini(RPair *p) {
|
|
r_hashtable_free (p->ht);
|
|
r_list_free (p->dbs);
|
|
if (p->file) {
|
|
free (p->file);
|
|
// memleak
|
|
//sdb_free (p->sdb);
|
|
p->sdb = NULL;
|
|
}
|
|
free (p->dir);
|
|
}
|
|
|
|
R_API int r_pair_save(RPair *p, const char *f) {
|
|
r_pair_set_file (p, f);
|
|
return r_pair_sync (p);
|
|
}
|
|
|
|
R_API int r_pair_load(RPair *p, const char *f) {
|
|
RPair *p2;
|
|
char *file = (f&&*f)? strdup (f): p->file? strdup (p->file): NULL;
|
|
r_pair_set_file (p, f);
|
|
r_pair_fini (p);
|
|
if (!file) return R_FALSE;
|
|
p2 = r_pair_new_from_file (file);
|
|
memcpy (p, p2, sizeof (RPair));
|
|
free (p2);
|
|
free (file);
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API RPair *r_pair_new () {
|
|
RPair *p = R_NEW0 (RPair);
|
|
p->file = NULL;
|
|
p->sdb = sdb_new (NULL, 0);
|
|
p->ht = r_hashtable_new ();
|
|
p->dbs = r_list_new ();
|
|
p->dbs->free = (RListFree)sdb_free;
|
|
return p;
|
|
}
|
|
|
|
R_API RPair *r_pair_new_from_file (const char *file) {
|
|
RPair *p = r_pair_new ();
|
|
p->file = strdup (file);
|
|
p->sdb = sdb_new (file, 0);
|
|
return p;
|
|
}
|
|
|
|
R_API void r_pair_free (RPair *p) {
|
|
if (p==NULL) return;
|
|
r_pair_fini (p);
|
|
free (p);
|
|
}
|
|
|
|
R_API void r_pair_delete (RPair *p, const char *name) {
|
|
Sdb *sdb;
|
|
ut32 hdom;
|
|
char *dom, *key = strdup (name);
|
|
|
|
dom = r_str_lchr (key, '.');
|
|
if (dom) {
|
|
key = dom+1;
|
|
*dom = 0;
|
|
dom = 0;
|
|
} else dom = "";
|
|
hdom = r_str_hash (dom);
|
|
sdb = r_hashtable_lookup (p->ht, hdom);
|
|
if (sdb)
|
|
sdb_remove (sdb, key, 0);
|
|
}
|
|
|
|
static Sdb *pair_sdb_new(RPair *p, const char *dom, ut32 hdom) {
|
|
Sdb *sdb;
|
|
char *old = NULL;
|
|
if (p->dir) {
|
|
old = r_sys_getdir ();
|
|
r_sys_rmkdir (p->dir);
|
|
r_sys_chdir (p->dir);
|
|
}
|
|
sdb = sdb_new (dom, 0);
|
|
if (old) {
|
|
r_sys_chdir (old);
|
|
free (old);
|
|
}
|
|
r_list_append (p->dbs, sdb);
|
|
r_hashtable_insert (p->ht, hdom, sdb);
|
|
return sdb;
|
|
}
|
|
|
|
R_API char *r_pair_get (RPair *p, const char *name) {
|
|
Sdb *sdb;
|
|
ut32 hdom;
|
|
char *dom, *key, *okey;
|
|
|
|
if (p->file)
|
|
return sdb_get (p->sdb, name, NULL);
|
|
|
|
key = okey = strdup (name);
|
|
dom = r_str_lchr (okey, '.');
|
|
if (dom) {
|
|
char *tmp = okey;
|
|
*dom = 0;
|
|
key = dom+1;
|
|
dom = tmp;
|
|
} else dom = "";
|
|
hdom = r_str_hash (dom);
|
|
sdb = r_hashtable_lookup (p->ht, hdom);
|
|
if (!sdb)
|
|
sdb = pair_sdb_new (p, dom, hdom);
|
|
dom = sdb_get (sdb, key, NULL);
|
|
free (okey);
|
|
return dom;
|
|
}
|
|
|
|
R_API void r_pair_set (RPair *p, const char *name, const char *value) {
|
|
char *dom, *key, *okey;
|
|
ut32 hdom;
|
|
Sdb *sdb;
|
|
|
|
if (p->file) {
|
|
sdb_set (p->sdb, name, value, 0);
|
|
return;
|
|
}
|
|
key = strdup (name);
|
|
dom = r_str_lchr (key, '.');
|
|
if (dom) {
|
|
okey = key;
|
|
*dom = 0;
|
|
key = dom+1;
|
|
dom = okey;
|
|
} else dom = "";
|
|
hdom = r_str_hash (dom);
|
|
sdb = r_hashtable_lookup (p->ht, hdom);
|
|
if (!sdb) sdb = pair_sdb_new (p, dom, hdom);
|
|
sdb_set (sdb, key, value, 0);
|
|
}
|
|
|
|
R_API RList *r_pair_list (RPair *p, const char *domain) {
|
|
Sdb *s;
|
|
if (p->file) s = p->sdb;
|
|
else s = r_hashtable_lookup (p->ht, r_str_hash (domain));
|
|
if (s) {
|
|
RList *list = r_list_new ();
|
|
char key[SDB_KSZ];
|
|
char val[SDB_VSZ];
|
|
list->free = (RListFree)r_pair_item_free;
|
|
sdb_dump_begin (s);
|
|
while (sdb_dump_next (s, key, val))
|
|
r_list_append (list, r_pair_item_new (key, val));
|
|
return list;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
RPairItem *r_pair_item_new (const char *k, const char *v) {
|
|
RPairItem *i = R_NEW (RPairItem);
|
|
i->k = strdup (k);
|
|
i->v = strdup (v);
|
|
return i;
|
|
}
|
|
|
|
R_API void r_pair_item_free (RPairItem *i) {
|
|
free (i->k);
|
|
free (i->v);
|
|
free (i);
|
|
}
|
|
|
|
R_API void r_pair_set_sync_dir (RPair *p, const char *dir) {
|
|
free (p->dir);
|
|
p->dir = strdup (dir);
|
|
}
|
|
|
|
R_API void r_pair_reset (RPair *p) {
|
|
Sdb *s;
|
|
RListIter *iter;
|
|
r_list_foreach (p->dbs, iter, s)
|
|
sdb_reset (s);
|
|
}
|
|
|
|
R_API int r_pair_sync (RPair *p) {
|
|
Sdb *s;
|
|
char *old = NULL;
|
|
RListIter *iter;
|
|
if (p->file)
|
|
return sdb_sync (p->sdb);
|
|
if (p->dir) {
|
|
old = r_sys_getdir ();
|
|
r_sys_rmkdir (p->dir);
|
|
r_sys_chdir (p->dir);
|
|
}
|
|
r_list_foreach (p->dbs, iter, s) {
|
|
sdb_sync (s);
|
|
}
|
|
if (old) {
|
|
r_sys_chdir (old);
|
|
free (old);
|
|
}
|
|
return R_TRUE;
|
|
}
|
|
|
|
R_API char* r_pair_serialize(RPair *p, const char *fmt, void *ptr) {
|
|
return NULL;
|
|
}
|
|
|
|
R_API int r_pair_deserialize(RPair *p, ut8 *out, const char *fmt, const char *ptr) {
|
|
return 0;
|
|
}
|