Initial SDBization of RAnalMeta...

This commit is contained in:
pancake 2014-03-04 12:23:52 +01:00
parent 94fc93890a
commit d664e7b7de
10 changed files with 426 additions and 70 deletions

View File

@ -55,7 +55,7 @@ R_API RAnal *r_anal_new() {
anal->sdb_locals = sdb_new (NULL, NULL, 0);
anal->sdb_xrefs = NULL;
anal->sdb_types = sdb_new (NULL, NULL, 0);
anal->sdb_meta = NULL; // TODO : implement sdb_meta
anal->sdb_meta = sdb_new (NULL, NULL, 0);
r_meta_init (anal);
anal->printf = (PrintfCallback) printf;
r_anal_type_init (anal);

View File

@ -1,33 +1,99 @@
/* radare - LGPL - Copyright 2008-2014 - nibble, pancake */
// TODO: Use SDB
// TODO: rename to r_anal_meta_get() ??
#define USE_ANAL_SDB 1
#include <r_anal.h>
#include <r_print.h>
#if USE_ANAL_SDB
#define META_RANGE_BASE(x) ((x)>>12)
#define META_RANGE_SIZE 0xfff
static char *meta_inrange_get (RAnal *a, ut64 addr, int size) {
#undef DB
#define DB a->sdb_meta
char key[64];
ut64 base, base2;
base = META_RANGE_BASE (addr);
base2 = META_RANGE_BASE (addr+size);
// return string array of all the offsets where there are stuff
for (; base<base2; base += META_RANGE_SIZE) {
snprintf (key, sizeof (key)-1, "range.0x%"PFMT64x, base);
sdb_array_get (DB, key, 0, 0);
}
return NULL;
}
static int meta_inrange_add (RAnal *a, ut64 addr, int size) {
int set = 0;
char key[64];
ut64 base, base2;
base = META_RANGE_BASE (addr);
base2 = META_RANGE_BASE (addr+size);
for (; base<base2; base += META_RANGE_SIZE) {
snprintf (key, sizeof (key)-1, "range.0x%"PFMT64x, base);
if (sdb_array_add_num (DB, key, -1, addr, 0))
set = 1;
}
return set;
}
static int meta_inrange_del (RAnal *a, ut64 addr, int size) {
int set = 0;
char key[64];
ut64 base, base2;
base = META_RANGE_BASE (addr);
base2 = META_RANGE_BASE (addr+size);
// TODO: optimize this thing?
for (; base<base2; base += META_RANGE_SIZE) {
snprintf (key, sizeof (key)-1, "range.0x%"PFMT64x, base);
if (sdb_array_del_num (DB, key, addr, 0))
set = 1;
}
//sdb_array_del (DB);
return set;
}
#endif
R_API void r_meta_init(RAnal *a) {
#if USE_ANAL_SDB
a->meta = NULL;
#else
a->meta = r_list_new ();
a->meta->free = r_meta_item_free;
#endif
}
R_API void r_meta_fini(RAnal *a) {
#if !USE_ANAL_SDB
r_list_free (a->meta);
#endif
}
R_API int r_meta_count(RAnal *m, int type, ut64 from, ut64 to) {
RAnalMetaItem *d;
RListIter *iter;
int count = 0;
r_list_foreach (m->meta, iter, d) {
if (d->type == type || type == R_META_TYPE_ANY)
if (from >= d->from && d->to < to)
count++;
}
return count;
}
// TODO: Add APIs to resize meta? nope, just del and add
R_API int r_meta_set_string(RAnal *m, int type, ut64 addr, const char *s) {
#if USE_ANAL_SDB
#undef DB
#define DB m->sdb_meta
char key[100], val[2048], *e_str;
int ret;
ut64 size;
snprintf (key, sizeof (key)-1, "meta.%c", type);
sdb_array_add_num (DB, key, -1, addr, 0);
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr);
size = sdb_array_get_num (DB, key, 0, 0);
if (!size) {
size = strlen (s);
meta_inrange_add (m, addr, size);
ret = R_TRUE;
} else ret = R_FALSE;
e_str = sdb_encode ((const void*)s, 0);
snprintf (val, sizeof (val)-1, "%d,%s", (int)size, e_str);
sdb_set (DB, key, val, 0);
free ((void*)e_str);
return ret;
#else
RAnalMetaItem *mi = r_meta_find (m, addr, type, R_META_WHERE_HERE);
if (mi) {
free (mi->str);
@ -36,9 +102,24 @@ R_API int r_meta_set_string(RAnal *m, int type, ut64 addr, const char *s) {
}
r_meta_add (m, type, addr, addr+1, s);
return R_FALSE;
#endif
}
R_API char *r_meta_get_string(RAnal *m, int type, ut64 addr) {
#if USE_ANAL_SDB
#undef DB
#define DB m->sdb_meta
char key[100];
const char *k, *p;
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, 'C', addr);
k = sdb_const_get (DB, key, NULL);
if (!k) return NULL;
p = strchr (k, SDB_RS);
if (!p) return NULL;
k = p+1;
// TODO : comment append has been deprecated
return (char *)sdb_decode (k, NULL);
#else
char *str = NULL;
RListIter *iter;
RAnalMetaItem *d;
@ -70,9 +151,48 @@ R_API char *r_meta_get_string(RAnal *m, int type, ut64 addr) {
}
}
return str;
#endif
}
R_API int r_meta_del(RAnal *a, int type, ut64 from, ut64 size, const char *str) {
R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size, const char *str) {
#if USE_ANAL_SDB
#undef DB
#define DB a->sdb_meta
int i, nxt;
char key[100], key2[100], *dtr, *s, *p;
const char *ptr;
if (size == UT64_MAX) {
// FULL CLEANUP
// XXX: this thing ignores the type
if (type == R_META_TYPE_ANY) {
sdb_reset (DB);
} else {
snprintf (key, sizeof (key)-1, "meta.%c", type);
dtr = sdb_get (DB, key, 0);
for (p = dtr; p; p = s) {
s = sdb_array_string (p, &nxt);
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x,
type, sdb_atoi (s));
eprintf ("--> %s\n", key);
sdb_unset (DB, key, 0);
if (!nxt) break;
}
free (dtr);
}
return R_FALSE;
}
meta_inrange_del (a, addr, size);
snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, addr);
ptr = sdb_const_get (DB, key, 0);
for (i=0; ptr[i]; i++) {
if (ptr[i] != SDB_RS) {
snprintf (key2, sizeof (key2)-1, "meta.%c.0x%"PFMT64x, ptr[i], addr);
sdb_unset (DB, key2, 0);
}
}
sdb_unset (DB, key, 0);
return R_FALSE;
#else
int ret = 0;
RListIter *iter, *iter_tmp;
RAnalMetaItem *d;
@ -81,7 +201,7 @@ R_API int r_meta_del(RAnal *a, int type, ut64 from, ut64 size, const char *str)
if (d->type == type || type == R_META_TYPE_ANY) {
if (str && d->str && !strstr (d->str, str))
continue;
if (size==UT64_MAX || (from+size >= d->from && from <= d->to-size)) {
if (size==UT64_MAX || (addr+size >= d->from && addr <= d->to-size)) {
free (d->str);
r_list_delete (a->meta, iter);
ret++;
@ -89,13 +209,16 @@ R_API int r_meta_del(RAnal *a, int type, ut64 from, ut64 size, const char *str)
}
}
return ret;
#endif
}
R_API int r_meta_cleanup(RAnal *a, ut64 from, ut64 to) {
#if USE_ANAL_SDB
eprintf ("TODO: Implement r_meta_cleanup for SDB\n");
#else
RAnalMetaItem *d;
RListIter *iter, next;
int ret = R_FALSE;
if (from == 0LL && to == UT64_MAX) {
RList *m2 = a->meta;
r_meta_init (a);
@ -143,6 +266,7 @@ R_API int r_meta_cleanup(RAnal *a, ut64 from, ut64 to) {
iter = &next;
}
return ret;
#endif
}
R_API void r_meta_item_free(void *_item) {
@ -157,6 +281,22 @@ R_API RAnalMetaItem *r_meta_item_new(int type) {
return mi;
}
#if USE_ANAL_SDB
// DEPRECATED FUNCTIONS FTW
#else
R_API int r_meta_count(RAnal *m, int type, ut64 from, ut64 to) {
RAnalMetaItem *d;
RListIter *iter;
int count = 0;
r_list_foreach (m->meta, iter, d) {
if (d->type == type || type == R_META_TYPE_ANY)
if (from >= d->from && d->to < to)
count++;
}
return count;
}
// TODO: This is ultraslow. must accelerate with hashtables
R_API int r_meta_comment_check (RAnal *m, const char *s, ut64 addr) {
RAnalMetaItem *d;
@ -168,11 +308,34 @@ R_API int r_meta_comment_check (RAnal *m, const char *s, ut64 addr) {
if (!strcmp (s, d->str))
return R_TRUE;
}
return R_FALSE;
}
#endif
R_API int r_meta_add(RAnal *m, int type, ut64 from, ut64 to, const char *str) {
#if USE_ANAL_SDB
#define DB m->sdb_meta
char *e_str, key[100], val[2048];
if (from>=to)
return R_FALSE;
/* set entry */
e_str = sdb_encode ((const void*)str, 0);
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, from);
snprintf (val, sizeof (val)-1, "%d,%s", (int)(to-from), e_str);
sdb_set (DB, key, val, 0);
free (e_str);
/* set type index */
snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, from);
snprintf (val, sizeof (val)-1, "%c", type);
sdb_array_add (DB, key, -1, val, 0);
/* set type index */
snprintf (key, sizeof (key)-1, "meta.%c", type);
sdb_array_add_num (DB, key, -1, from, 0);
return R_TRUE;
#else
RAnalMetaItem *mi;
if (to<from)
to = from+to;
@ -211,10 +374,27 @@ R_API int r_meta_add(RAnal *m, int type, ut64 from, ut64 to, const char *str) {
if (mi && mi->type == R_META_TYPE_FORMAT)
mi->size = r_print_format_length (mi->str);
return R_TRUE;
#endif
}
/* snippet from data.c */
R_API RAnalMetaItem *r_meta_find(RAnal *m, ut64 off, int type, int where) {
#if USE_ANAL_SDB
static RAnalMetaItem it = {0};
// XXX: return allocated item? wtf
if (where != R_META_WHERE_HERE) {
eprintf ("THIS WAS NOT SUPOSED TO HAPPEN\n");
return NULL;
}
//char *range = get_in_range (off);
if (type == R_META_TYPE_ANY) {
char key [100];
snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, off);
} else {
// snprintf (key, sizeof (key)-1, "meta.
}
return &it;
#else
RAnalMetaItem *d, *it = NULL;
RListIter *iter;
r_list_foreach (m->meta, iter, d) {
@ -236,6 +416,7 @@ R_API RAnalMetaItem *r_meta_find(RAnal *m, ut64 off, int type, int where) {
}
}
return it;
#endif
}
#if 0
@ -281,23 +462,6 @@ R_API const char *r_meta_type_to_string(int type) {
return "(...)";
}
#if 0
#include <r_util.h>
struct r_range_t *r_meta_ranges(RAnal *m)
{
struct r_range_t *r;
struct list_head *pos;
r = r_range_new();
list_for_each(pos, &m->meta) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
r_range_add(r, d->from, d->to, 1); //d->type);
}
return r;
}
#endif
static void printmetaitem(RAnal *m, RAnalMetaItem *d, int rad) {
char *pstr, *str = r_str_escape (d->str);
if (str) {
@ -332,8 +496,42 @@ static void printmetaitem(RAnal *m, RAnalMetaItem *d, int rad) {
}
}
#if USE_ANAL_SDB
typedef struct {
RAnal *anal;
int type;
int rad;
} RAnalMetaUserItem;
static int meta_print_item(void *user, const char *k, const char *v) {
RAnalMetaUserItem *ui = user;
RAnalMetaItem it;
if (strlen (k)<8)
return R_FALSE;
if (k[6]!='.')
return R_FALSE;
it.type = k[5];
it.size = sdb_atoi (v);
it.from = sdb_atoi (k+7);
it.to = it.from + it.size;
it.str = strchr (v, ',');
if (it.str)
it.str = (char *)sdb_decode ((const char*)it.str+1, 0);
printmetaitem (ui->anal, &it, ui->rad);
free (it.str);
return R_TRUE;
}
#endif
// TODO: Deprecate
R_API int r_meta_list(RAnal *m, int type, int rad) {
#if USE_ANAL_SDB
#define DB m->sdb_meta
RAnalMetaUserItem ui = { m, type, rad };
// XXX: doesnt works well on sync
sdb_foreach (DB, meta_print_item, &ui);
return 0;
#else
int count = 0;
RListIter *iter;
RAnalMetaItem *d;
@ -347,23 +545,17 @@ R_API int r_meta_list(RAnal *m, int type, int rad) {
}
if (rad=='j') m->printf ("]\n");
return count;
#endif
}
R_API char *r_anal_meta_bar (RAnal *anal, ut64 from, ut64 to, int blocks) {
int i, n, blocksize;
char *res;
ut64 f, t;
if (blocks<1 || from > to)
return NULL;
#if 0
if (from == to && from == 0) {
// autodetect min and max here
// from =
}
#endif
blocksize = (to-from)/blocks;
res = malloc (blocks*4); //blocksize*5);// use realloc here
res = malloc (blocks*4);
for (i=0; i< blocks; i++) {
f = from + (blocksize*i);
t = f+blocksize;

View File

@ -20,6 +20,7 @@ extern "C" {
#define SDB_RS ','
#define SDB_SS ","
#define SDB_MAX_PATH 256
#define SDB_NUM_BASE 10
#define SDB_OPTION_NONE 0
#define SDB_OPTION_ALL 0xff
@ -151,6 +152,7 @@ void sdb_ns_sync (Sdb* s);
// array
int sdb_array_exists (Sdb* s, const char *key, const char *val);
SDB_API int sdb_array_exists_num(Sdb *s, const char *key, ut64 val);
int sdb_array_add (Sdb* s, const char *key, int idx, const char *val, ut32 cas);
int sdb_array_add_num (Sdb* s, const char *key, int idx, ut64 val, ut32 cas);
int sdb_array_set (Sdb* s, const char *key, int idx, const char *val, ut32 cas);
@ -188,6 +190,12 @@ int sdb_num_base (const char *s);
int sdb_bool_set(Sdb *db, const char *str, int v, ut32 cas);
int sdb_bool_get(Sdb *db, const char *str, ut32 *cas);
// base64
ut8 *sdb_decode (const char *in, int *len);
SDB_API char *sdb_encode(const ut8 *bin, int len);
SDB_API void sdb_encode_raw(char *bout, const ut8 *bin, int len);
SDB_API int sdb_decode_raw(ut8 *bout, const char *bin, int len);
#ifdef __cplusplus
}
#endif

View File

@ -206,7 +206,6 @@ static RIODesc *rap__open(struct r_io_t *io, const char *pathname, int rw, int m
}
r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, ENDIAN);
if (i>0) eprintf ("ok\n");
#if 0
/* Read meta info */
r_socket_read (rap_fd, (ut8 *)&buf, 4);
@ -272,7 +271,7 @@ static int rap__system(RIO *io, RIODesc *fd, const char *command) {
if (i == -1)
return -1;
ret = 0;
ptr = (char *)malloc (i);
ptr = (char *)malloc (i+1);
if (ptr) {
int ir, tr = 0;
do {

View File

@ -1,7 +1,7 @@
include ../config.mk
CFLAGS+= -g -ggdb
OBJ=cdb.o buffer.o cdb_make.o ls.o ht.o sdb.o num.o
OBJ=cdb.o buffer.o cdb_make.o ls.o ht.o sdb.o num.o base64.o
OBJ+=json.o ns.o lock.o util.o disk.o query.o array.o
SOBJ=$(subst .o,._o,${OBJ})

View File

@ -81,7 +81,8 @@ SDB_API char *sdb_array_get(Sdb *s, const char *key, int idx, ut32 *cas) {
SDB_API int sdb_array_ins_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) {
char valstr[64];
return sdb_array_ins (s, key, idx, sdb_itoa (val, valstr, 10), cas);
return sdb_array_ins (s, key, idx,
sdb_itoa (val, valstr, SDB_NUM_BASE), cas);
}
// TODO: done, but there's room for improvement
@ -128,11 +129,12 @@ SDB_API int sdb_array_ins(Sdb *s, const char *key, int idx, const char *val, ut3
SDB_API int sdb_array_set_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) {
char valstr[64];
return sdb_array_set (s, key, idx, sdb_itoa (val, valstr, 10), cas);
return sdb_array_set (s, key, idx,
sdb_itoa (val, valstr, SDB_NUM_BASE), cas);
}
SDB_API int sdb_array_add_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) {
char valstr[64], *vs = sdb_itoa (val, valstr, 10);
char valstr[64], *vs = sdb_itoa (val, valstr, SDB_NUM_BASE);
if (sdb_array_exists (s, key, vs))
return 0;
return sdb_array_add (s, key, idx, vs, cas);
@ -280,6 +282,12 @@ SDB_API const char *sdb_array_index(const char *str, int idx) {
return NULL;
}
SDB_API int sdb_array_exists_num(Sdb *s, const char *key, ut64 num) {
char val[64];
char *nval = sdb_itoa (num, val, SDB_NUM_BASE);
return sdb_array_exists (s, key, nval);
}
SDB_API int sdb_array_exists(Sdb *s, const char *key, const char *val) {
int found = 0, hasnext = 1;
char *list = sdb_get (s, key, 0);

85
shlr/sdb/src/base64.c Normal file
View File

@ -0,0 +1,85 @@
/* base64 enc/dec - LGPLv3 - Copyright 2011-2014 - pancake */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "sdb.h"
#define SZ 1024
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
static void b64_encode(const ut8 in[3], char out[4], int len) {
out[0] = cb64[ in[0] >> 2 ];
out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
}
static int b64_decode(const char in[4], ut8 out[3]) {
ut8 len = 3, i, v[4] = {0};
for (i=0; i<4; i++) {
if (in[i]<43 || in[i]>122)
return -1;
v[i] = cd64[in[i]-43];
if (v[i]=='$') {
len = i-1;
break;
}
v[i]-=62;
}
out[0] = v[0] << 2 | v[1] >> 4;
out[1] = v[1] << 4 | v[2] >> 2;
out[2] = ((v[2] << 6) & 0xc0) | v[3];
return len;
}
SDB_API void sdb_encode_raw(char *bout, const ut8 *bin, int len) {
int in, out;
for (in=out=0; in<len; in+=3,out+=4)
b64_encode (bin+in, bout+out, len-in>3?3:len-in);
bout[out] = 0;
}
SDB_API int sdb_decode_raw(ut8 *bout, const char *bin, int len) {
int in, out, ret;
for (in=out=0; in<len-1;in+=4) {
if ((ret = b64_decode (bin+in, bout+out))<1)
break;
out += 3;
}
bout[out-1] = 0;
return (in != out);
}
SDB_API char *sdb_encode(const ut8 *bin, int len) {
char *out;
if (len<1)
len = strlen ((const char *)bin)+1;
if (len==0)
return strdup ("");
out = malloc (len+8);
if (!out)
return NULL;
memset (out, 0, len+8);
sdb_encode_raw (out, bin, len);
return out;
}
SDB_API ut8 *sdb_decode (const char *in, int *len) {
ut8 *out;
int olen, ilen = strlen (in);
out = malloc (ilen+8);
if (!out)
return NULL;
memset (out, 0, ilen+8);
olen = sdb_decode_raw (out, in, ilen);
if (!olen) {
free (out);
return NULL;
}
if (len)
*len = olen;
return out;
}

View File

@ -31,10 +31,13 @@ SDB_API char *sdb_querysf (Sdb *s, char *buf, size_t buflen, const char *fmt, ..
}
// XXX: cmd is reused
#define out_concat(x) if (x) { char *o =(void*)realloc((void*)out, 2+strlen(x)+(out?strlen(out):0)); if (o) { if (out) strcat (out, "\n"); else *o=0; out=o; strcat (out, x); } }
#define out_concat(x) if (x) { \
char *o =(void*)realloc((void*)out, 2+strlen(x)+(out?strlen(out):0)); \
if (o) { if (out) strcat (out, "\n"); else *o=0; out=o; strcat (out, x); } \
}
SDB_API char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd) {
int i, d, ok, w, alength, bufset = 0, is_ref = 0;
int i, d, ok, w, alength, bufset = 0, is_ref = 0, encode = 0;
char *eq, *tmp, *json, *next, *quot, *out = NULL;
const char *p, *q, *val = NULL;
ut64 n;
@ -49,6 +52,11 @@ SDB_API char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd) {
}
repeat:
p = cmd;
if (*p=='%') {
encode = 1;
cmd++;
p++;
}
eq = strchr (p, '=');
is_ref = 0;
if (eq) {
@ -92,7 +100,7 @@ next_quote:
char *tp = strchr (cmd, ']');
if (!tp) {
fprintf (stderr, "Missing ']'.\n");
goto failure;
goto fail;
}
*tp++ = 0;
p = (const char *)tp;
@ -105,7 +113,7 @@ next_quote:
if (s->options & SDB_OPTION_FS) {
if (!sdb_query_file (s, cmd+1)) {
fprintf (stderr, "sdb: cannot open '%s'\n", cmd+1);
goto failure;
goto fail;
}
} else {
fprintf (stderr, "sdb: filesystem access disabled in config\n");
@ -205,15 +213,30 @@ next_quote:
/* [+3]foo=bla */
if (i<0) {
char *tmp = sdb_array_get (s, p, -i, NULL);
ok = 0;
out_concat (tmp);
sdb_array_del (s, p, -i, 0);
free (tmp);
if (tmp) {
if (encode) {
char *newtmp = (void*)sdb_decode (tmp, NULL);
if (!newtmp)
goto fail;
free (tmp);
tmp = newtmp;
}
ok = 0;
out_concat (tmp);
sdb_array_del (s, p, -i, 0);
free (tmp);
} else goto fail;
} else {
if (encode)
val = sdb_encode ((const ut8*)val, 0);
ok = cmd[1]? ((cmd[1]=='+')?
sdb_array_ins (s, p, i, val, 0):
sdb_array_set (s, p, i, val, 0)
): sdb_array_del (s, p, i, 0);
if (encode) {
free ((void*)val);
val = NULL;
}
}
if (ok) *buf = 0;
else buf = NULL;
@ -244,17 +267,19 @@ next_quote:
} else {
if (eq) {
/* [3]foo=bla */
char *q, *sval = strdup (val);
// TODO: define new printable separator character
for (q=sval; *q; q++) if (*q==',') *q = SDB_RS;
char *sval = (char*)val;
if (encode) {
sval = sdb_encode ((const ut8*)val, 0);
}
if (cmd[1]) {
int idx = atoi (cmd+1);
ok = sdb_array_set (s, p, idx, val, 0);
ok = sdb_array_set (s, p, idx, sval, 0);
// TODO: handle when idx > sdb_alen
} else {
ok = sdb_set (s, p, sval, 0);
}
free (sval);
if (encode)
free (sval);
if (ok) {
*buf = 0;
return buf;
@ -265,9 +290,16 @@ next_quote:
size_t wl;
if (cmd[1]) {
i = atoi (cmd+1);
tmp = sdb_array_get (s, p, i, NULL);
out_concat (tmp);
free (tmp);
buf = sdb_array_get (s, p, i, NULL);
bufset = 1;
if (encode) {
char *newbuf = (void*)sdb_decode (buf, NULL);
if (newbuf) {
free (buf);
buf = newbuf;
}
}
out_concat (buf);
} else {
if (!sval) return NULL;
wl = strlen (sval);
@ -281,6 +313,13 @@ next_quote:
else buf[i] = sval[i];
}
buf[i] = 0;
if (encode) {
char *newbuf = (void*)sdb_decode (buf, NULL);
if (newbuf) {
free (buf);
buf = newbuf;
}
}
out_concat (buf);
}
}
@ -289,13 +328,19 @@ next_quote:
if (eq) {
// 1 0 kvpath=value
// 1 1 kvpath:jspath=value
if (encode)
val = sdb_encode ((const ut8*)val, 0);
if (json>eq) json = NULL;
if (json) {
*json++ = 0;
ok = sdb_json_set (s, cmd, json, val, 0);
} else ok = sdb_set (s, cmd, val, 0);
if (encode) {
free ((void*)val);
val = NULL;
}
if (!ok)
goto failure;
goto fail;
} else {
// 0 1 kvpath?jspath
// 0 0 kvpath
@ -303,13 +348,24 @@ next_quote:
*json++ = 0;
// TODO: not optimized to reuse 'buf'
if ((tmp = sdb_json_get (s, cmd, json, 0))) {
if (encode) {
char *newtmp = (void*)sdb_decode (tmp, NULL);
if (!newtmp)
goto fail;
free (tmp);
tmp = newtmp;
}
out_concat (tmp);
free (tmp);
}
} else {
// sdbget
if ((q = sdb_const_get (s, cmd, 0))) {
if (encode)
q = (void*)sdb_decode (q, NULL);
out_concat (q);
if (encode)
free ((void*)q);
}
}
}
@ -324,7 +380,7 @@ next_quote:
goto repeat;
}
if (eq) *--eq = '=';
failure:
fail:
if (bufset)
free (buf);
return out;

View File

@ -20,6 +20,7 @@ extern "C" {
#define SDB_RS ','
#define SDB_SS ","
#define SDB_MAX_PATH 256
#define SDB_NUM_BASE 10
#define SDB_OPTION_NONE 0
#define SDB_OPTION_ALL 0xff
@ -151,6 +152,7 @@ void sdb_ns_sync (Sdb* s);
// array
int sdb_array_exists (Sdb* s, const char *key, const char *val);
SDB_API int sdb_array_exists_num(Sdb *s, const char *key, ut64 val);
int sdb_array_add (Sdb* s, const char *key, int idx, const char *val, ut32 cas);
int sdb_array_add_num (Sdb* s, const char *key, int idx, ut64 val, ut32 cas);
int sdb_array_set (Sdb* s, const char *key, int idx, const char *val, ut32 cas);
@ -188,6 +190,12 @@ int sdb_num_base (const char *s);
int sdb_bool_set(Sdb *db, const char *str, int v, ut32 cas);
int sdb_bool_get(Sdb *db, const char *str, ut32 *cas);
// base64
ut8 *sdb_decode (const char *in, int *len);
SDB_API char *sdb_encode(const ut8 *bin, int len);
SDB_API void sdb_encode_raw(char *bout, const ut8 *bin, int len);
SDB_API int sdb_decode_raw(ut8 *bout, const char *bin, int len);
#ifdef __cplusplus
}
#endif

View File

@ -126,7 +126,7 @@ SDB_API int sdb_isnum (const char *s) {
}
SDB_API int sdb_num_base (const char *s) {
if (!s) return 10;
if (!s) return SDB_NUM_BASE;
if (!strncmp (s, "0x", 2))
return 16;
if (*s=='0' && s[1]) return 8;