mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-02 03:32:04 +00:00
Bump for SDB (0.9.6-git)
This commit is contained in:
parent
2afcbbaee0
commit
195df37634
@ -8,10 +8,6 @@
|
||||
|
||||
#define KVLSZ 4
|
||||
|
||||
extern char *cdb_alloc(unsigned int n);
|
||||
extern void cdb_alloc_free(void*);
|
||||
extern int cdb_alloc_re(void);
|
||||
|
||||
/* TODO THIS MUST GTFO! */
|
||||
int cdb_getkvlen(int fd, ut32 *klen, ut32 *vlen);
|
||||
#define CDB_HASHSTART 5381
|
||||
@ -29,12 +25,11 @@ struct cdb {
|
||||
ut32 dlen; /* initialized if cdb_findnext() returns 1 */
|
||||
};
|
||||
|
||||
extern void cdb_free(struct cdb *);
|
||||
extern void cdb_init(struct cdb *,int fd);
|
||||
extern void cdb_findstart(struct cdb *);
|
||||
extern int cdb_read(struct cdb *,char *,unsigned int,ut32);
|
||||
extern int cdb_findnext(struct cdb *,ut32 u, const char *,unsigned int);
|
||||
extern int cdb_find(struct cdb *,const char *,unsigned int);
|
||||
void cdb_free(struct cdb *);
|
||||
void cdb_init(struct cdb *, int fd);
|
||||
void cdb_findstart(struct cdb *);
|
||||
int cdb_read(struct cdb *, char *, unsigned int, ut32);
|
||||
int cdb_findnext(struct cdb *, ut32 u, const char *, ut32);
|
||||
|
||||
#define cdb_datapos(c) ((c)->dpos)
|
||||
#define cdb_datalen(c) ((c)->dlen)
|
||||
|
@ -11,24 +11,25 @@
|
||||
struct cdb_hp { ut32 h; ut32 p; } ;
|
||||
|
||||
struct cdb_hplist {
|
||||
struct cdb_hp hp[CDB_HPLIST];
|
||||
struct cdb_hplist *next;
|
||||
int num;
|
||||
} ;
|
||||
struct cdb_hp hp[CDB_HPLIST];
|
||||
struct cdb_hplist *next;
|
||||
int num;
|
||||
};
|
||||
|
||||
struct cdb_make {
|
||||
char bspace[8192];
|
||||
char final[2048];
|
||||
ut32 count[256];
|
||||
ut32 start[256];
|
||||
struct cdb_hplist *head;
|
||||
struct cdb_hp *split; /* includes space for hash */
|
||||
struct cdb_hp *hash;
|
||||
ut32 numentries;
|
||||
buffer b;
|
||||
ut32 pos;
|
||||
int fd;
|
||||
} ;
|
||||
char bspace[8192];
|
||||
char final[2048];
|
||||
ut32 count[256];
|
||||
ut32 start[256];
|
||||
struct cdb_hplist *head;
|
||||
struct cdb_hp *split; /* includes space for hash */
|
||||
struct cdb_hp *hash;
|
||||
ut32 numentries;
|
||||
ut32 memsize;
|
||||
buffer b;
|
||||
ut32 pos;
|
||||
int fd;
|
||||
};
|
||||
|
||||
extern int cdb_make_start(struct cdb_make *,int);
|
||||
extern int cdb_make_addbegin(struct cdb_make *,unsigned int,unsigned int);
|
||||
|
@ -1 +1 @@
|
||||
#define SDB_VERSION "0.9.2"
|
||||
#define SDB_VERSION "0.9.6"
|
||||
|
@ -21,6 +21,12 @@ extern "C" {
|
||||
#undef r_offsetof
|
||||
#define r_offsetof(type, member) ((unsigned long) &((type*)0)->member)
|
||||
|
||||
/* Key value sizes */
|
||||
#define SDB_MIN_VALUE 1
|
||||
#define SDB_MAX_VALUE 0xffffff
|
||||
#define SDB_MIN_KEY 1
|
||||
#define SDB_MAX_KEY 0xff
|
||||
|
||||
#define SDB_MODE 0644
|
||||
//#define SDB_MODE 0600
|
||||
|
||||
@ -99,6 +105,7 @@ int sdb_exists (Sdb*, const char *key);
|
||||
int sdb_unset (Sdb*, const char *key, ut32 cas);
|
||||
int sdb_unset_matching(Sdb *s, const char *k);
|
||||
char *sdb_get (Sdb*, const char *key, ut32 *cas);
|
||||
char *sdb_get_len (Sdb*, const char *key, int *vlen, ut32 *cas);
|
||||
const char *sdb_const_get (Sdb*, const char *key, ut32 *cas);
|
||||
const char *sdb_const_get_len (Sdb* s, const char *key, int *vlen, ut32 *cas);
|
||||
int sdb_set (Sdb*, const char *key, const char *data, ut32 cas);
|
||||
@ -206,6 +213,7 @@ int sdb_array_remove_num (Sdb* s, const char *key, ut64 val, ut32 cas);
|
||||
char *sdb_anext(char *str, char **next);
|
||||
const char *sdb_const_anext(const char *str, const char **next);
|
||||
int sdb_alen(const char *str);
|
||||
int sdb_alen_ignore_empty(const char *str);
|
||||
int sdb_array_size(Sdb* s, const char *key);
|
||||
int sdb_array_length(Sdb* s, const char *key);
|
||||
|
||||
|
@ -65,7 +65,6 @@
|
||||
// TODO: deprecate R_NEW
|
||||
#define R_NEW(x) (x*)malloc(sizeof(x))
|
||||
#define R_NEW0(x) (x*)calloc(1,sizeof(x))
|
||||
#define R_ANEW(x) (x*)cdb_alloc(sizeof(x))
|
||||
#define UT32_MAX ((ut32)0xffffffff)
|
||||
#define UT64_MAX ((ut64)(0xffffffffffffffffLL))
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
DESTDIR?=
|
||||
PREFIX?=/usr
|
||||
|
||||
SDBVER=0.9.2
|
||||
SDBVER=0.9.6
|
||||
|
||||
INSTALL?=install
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* sdb - LGPLv3 - Copyright 2011-2014 - pancake */
|
||||
/* sdb - LGPLv3 - Copyright 2011-2015 - pancake */
|
||||
|
||||
#include "sdb.h"
|
||||
|
||||
@ -334,15 +334,7 @@ SDB_API int sdb_array_size(Sdb *s, const char *key) {
|
||||
|
||||
// NOTE: ignore empty buckets
|
||||
SDB_API int sdb_array_length(Sdb *s, const char *key) {
|
||||
int ret = 0;
|
||||
char *val = sdb_get (s, key, 0);
|
||||
if (val && *val) {
|
||||
// TOO SLOW
|
||||
sdb_array_compact (val);
|
||||
ret = sdb_alen (val);
|
||||
}
|
||||
free (val);
|
||||
return ret;
|
||||
return sdb_alen_ignore_empty (sdb_const_get (s, key, 0));
|
||||
}
|
||||
|
||||
SDB_API int sdb_array_push_num(Sdb *s, const char *key, ut64 num, ut32 cas) {
|
||||
|
@ -87,7 +87,7 @@ static int match(struct cdb *c, const char *key, ut32 len, ut32 pos) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cdb_findnext(struct cdb *c, ut32 u, const char *key, unsigned int len) {
|
||||
int cdb_findnext(struct cdb *c, ut32 u, const char *key, ut32 len) {
|
||||
char buf[8];
|
||||
ut32 pos;
|
||||
int m;
|
||||
|
@ -8,10 +8,6 @@
|
||||
|
||||
#define KVLSZ 4
|
||||
|
||||
extern char *cdb_alloc(unsigned int n);
|
||||
extern void cdb_alloc_free(void*);
|
||||
extern int cdb_alloc_re(void);
|
||||
|
||||
/* TODO THIS MUST GTFO! */
|
||||
int cdb_getkvlen(int fd, ut32 *klen, ut32 *vlen);
|
||||
#define CDB_HASHSTART 5381
|
||||
@ -29,12 +25,11 @@ struct cdb {
|
||||
ut32 dlen; /* initialized if cdb_findnext() returns 1 */
|
||||
};
|
||||
|
||||
extern void cdb_free(struct cdb *);
|
||||
extern void cdb_init(struct cdb *,int fd);
|
||||
extern void cdb_findstart(struct cdb *);
|
||||
extern int cdb_read(struct cdb *,char *,unsigned int,ut32);
|
||||
extern int cdb_findnext(struct cdb *,ut32 u, const char *,unsigned int);
|
||||
extern int cdb_find(struct cdb *,const char *,unsigned int);
|
||||
void cdb_free(struct cdb *);
|
||||
void cdb_init(struct cdb *, int fd);
|
||||
void cdb_findstart(struct cdb *);
|
||||
int cdb_read(struct cdb *, char *, unsigned int, ut32);
|
||||
int cdb_findnext(struct cdb *, ut32 u, const char *, ut32);
|
||||
|
||||
#define cdb_datapos(c) ((c)->dpos)
|
||||
#define cdb_datalen(c) ((c)->dlen)
|
||||
|
@ -7,41 +7,65 @@
|
||||
#include "cdb.h"
|
||||
#include "cdb_make.h"
|
||||
|
||||
#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
|
||||
#define SPACE 4096 /* must be multiple of ALIGNMENT */
|
||||
#define ALIGNMENT sizeof (void*)
|
||||
#if 0
|
||||
#define SPACE 16384*128 /* must be multiple of ALIGNMENT */
|
||||
|
||||
typedef union { char irrelevant[ALIGNMENT]; double d; } aligned;
|
||||
static aligned realspace[SPACE / ALIGNMENT];
|
||||
#define space ((char *) realspace)
|
||||
static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
|
||||
static int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
|
||||
|
||||
char *cdb_alloc(unsigned int n) {
|
||||
n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
|
||||
if (n <= avail) { avail -= n; return space + avail; }
|
||||
// TODO: on osx use posix_memalign or valloc for BSD
|
||||
return (char*)malloc (n);
|
||||
}
|
||||
|
||||
void cdb_alloc_free(void *x) {
|
||||
if ((const char *)x >= space)
|
||||
if ((const char*)x < space + SPACE)
|
||||
return; /* XXX: assuming that pointers are flat */
|
||||
return;
|
||||
free (x);
|
||||
}
|
||||
/****/
|
||||
#else
|
||||
//5.2
|
||||
char *cdb_alloc(ut32 n) {
|
||||
return malloc (n);
|
||||
#if __APPLE__
|
||||
void *ret = NULL;
|
||||
if (!posix_memalign (&ret, ALIGNMENT, n))
|
||||
return ret;
|
||||
return NULL;
|
||||
#elif __WINDOWS__
|
||||
return _aligned_malloc (n, ALIGNMENT);
|
||||
#else
|
||||
return malloc (n);
|
||||
#endif
|
||||
}
|
||||
void cdb_alloc_free(void *x) {
|
||||
free (x);
|
||||
}
|
||||
#endif
|
||||
|
||||
int cdb_make_start(struct cdb_make *c, int fd) {
|
||||
int i;
|
||||
c->head = 0;
|
||||
c->split = 0;
|
||||
c->hash = 0;
|
||||
c->numentries = 0;
|
||||
c->fd = fd;
|
||||
c->pos = sizeof c->final;
|
||||
buffer_init (&c->b, (BufferOp)write, fd, c->bspace, sizeof c->bspace);
|
||||
buffer_init (&c->b, (BufferOp)write, fd,
|
||||
c->bspace, sizeof c->bspace);
|
||||
c->memsize = 1;
|
||||
for (i=0; i<256; i++)
|
||||
c->count[i] = 0;
|
||||
return seek_set (fd, c->pos);
|
||||
}
|
||||
|
||||
// WTF?!?
|
||||
static inline int posplus(struct cdb_make *c, ut32 len) {
|
||||
static inline int incpos(struct cdb_make *c, ut32 len) {
|
||||
ut32 newpos = c->pos + len;
|
||||
if (newpos < len)
|
||||
return 0;
|
||||
@ -49,7 +73,9 @@ static inline int posplus(struct cdb_make *c, ut32 len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define R_ANEW(x) (x*)cdb_alloc(sizeof(x))
|
||||
int cdb_make_addend(struct cdb_make *c, ut32 keylen, ut32 datalen, ut32 h) {
|
||||
ut32 u;
|
||||
struct cdb_hplist *head = c->head;
|
||||
if (!head || (head->num >= CDB_HPLIST)) {
|
||||
if (!(head = R_ANEW (struct cdb_hplist)))
|
||||
@ -60,14 +86,19 @@ int cdb_make_addend(struct cdb_make *c, ut32 keylen, ut32 datalen, ut32 h) {
|
||||
}
|
||||
head->hp[head->num].h = h;
|
||||
head->hp[head->num].p = c->pos;
|
||||
++head->num;
|
||||
++c->numentries;
|
||||
return posplus (c, KVLSZ+keylen+datalen);
|
||||
head->num++;
|
||||
c->numentries++;
|
||||
c->count[255 & h] ++;
|
||||
u = c->count[255 & h] * 2;
|
||||
if (u > c->memsize) {
|
||||
c->memsize = u;
|
||||
}
|
||||
return incpos (c, KVLSZ+keylen+datalen);
|
||||
}
|
||||
|
||||
static int pack_kvlen(ut8 *buf, ut32 klen, ut32 vlen) {
|
||||
if (klen>0xff) return 0; // 0xff = 254 chars+trailing zero
|
||||
if (vlen>0xffffff) return 0;
|
||||
if (klen > SDB_MAX_KEY) return 0; // 0xff = 254 chars+trailing zero
|
||||
if (vlen > SDB_MAX_VALUE) return 0;
|
||||
buf[0] = (ut8)klen;
|
||||
buf[1] = (ut8)((vlen ) & 0xff);
|
||||
buf[2] = (ut8)((vlen>>8 ) & 0xff);
|
||||
@ -75,14 +106,14 @@ static int pack_kvlen(ut8 *buf, ut32 klen, ut32 vlen) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen) {
|
||||
int cdb_make_addbegin(struct cdb_make *c, ut32 keylen, ut32 datalen) {
|
||||
ut8 buf[KVLSZ];
|
||||
if (!pack_kvlen (buf, keylen, datalen))
|
||||
return 0;
|
||||
return buffer_putalign (&c->b, (const char *)buf, KVLSZ);
|
||||
}
|
||||
|
||||
int cdb_make_add(struct cdb_make *c, const char *key, unsigned int keylen, const char *data, unsigned int datalen) {
|
||||
int cdb_make_add(struct cdb_make *c, const char *key, ut32 keylen, const char *data, ut32 datalen) {
|
||||
if (!cdb_make_addbegin (c, keylen, datalen)) return 0;
|
||||
if (!buffer_putalign (&c->b, key, keylen)) return 0;
|
||||
if (!buffer_putalign (&c->b, data, datalen)) return 0;
|
||||
@ -96,25 +127,8 @@ int cdb_make_finish(struct cdb_make *c) {
|
||||
struct cdb_hplist *x, *n;
|
||||
ut32 len, u, memsize, count, where;
|
||||
|
||||
for (i=0; i<256; i++)
|
||||
c->count[i] = 0;
|
||||
|
||||
for (x=c->head; x; x=x->next) {
|
||||
i = x->num;
|
||||
while (i--)
|
||||
c->count[255 & x->hp[i].h]++;
|
||||
}
|
||||
|
||||
memsize = 1;
|
||||
for (i=0; i<256; i++) {
|
||||
u = c->count[i] * 2;
|
||||
if (u > memsize)
|
||||
memsize = u;
|
||||
}
|
||||
memsize += c->numentries; /* no overflow possible up to now */
|
||||
u = UT32_MAX;
|
||||
u /= sizeof (struct cdb_hp);
|
||||
if (memsize > u) return 0;
|
||||
memsize = c->memsize + c->numentries;
|
||||
if (memsize > (UT32_MAX/sizeof(struct cdb_hp))) return 0;
|
||||
|
||||
c->split = (struct cdb_hp *) cdb_alloc (memsize * sizeof (struct cdb_hp));
|
||||
if (!c->split) return 0;
|
||||
@ -154,17 +168,16 @@ int cdb_make_finish(struct cdb_make *c) {
|
||||
ut32_pack (buf, c->hash[u].h);
|
||||
ut32_pack (buf + 4, c->hash[u].p);
|
||||
if (!buffer_putalign (&c->b, buf, 8)) return 0;
|
||||
if (!posplus (c, 8)) return 0;
|
||||
if (!incpos (c, 8)) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!buffer_flush (&c->b)) return 0;
|
||||
if (!seek_set (c->fd, 0)) return 0;
|
||||
|
||||
// free chills
|
||||
// free childs
|
||||
for (x = c->head; x;) {
|
||||
n = x->next;
|
||||
free (x);
|
||||
cdb_alloc_free (x);
|
||||
x = n;
|
||||
}
|
||||
cdb_alloc_free (c->split);
|
||||
|
@ -11,24 +11,25 @@
|
||||
struct cdb_hp { ut32 h; ut32 p; } ;
|
||||
|
||||
struct cdb_hplist {
|
||||
struct cdb_hp hp[CDB_HPLIST];
|
||||
struct cdb_hplist *next;
|
||||
int num;
|
||||
} ;
|
||||
struct cdb_hp hp[CDB_HPLIST];
|
||||
struct cdb_hplist *next;
|
||||
int num;
|
||||
};
|
||||
|
||||
struct cdb_make {
|
||||
char bspace[8192];
|
||||
char final[2048];
|
||||
ut32 count[256];
|
||||
ut32 start[256];
|
||||
struct cdb_hplist *head;
|
||||
struct cdb_hp *split; /* includes space for hash */
|
||||
struct cdb_hp *hash;
|
||||
ut32 numentries;
|
||||
buffer b;
|
||||
ut32 pos;
|
||||
int fd;
|
||||
} ;
|
||||
char bspace[8192];
|
||||
char final[2048];
|
||||
ut32 count[256];
|
||||
ut32 start[256];
|
||||
struct cdb_hplist *head;
|
||||
struct cdb_hp *split; /* includes space for hash */
|
||||
struct cdb_hp *hash;
|
||||
ut32 numentries;
|
||||
ut32 memsize;
|
||||
buffer b;
|
||||
ut32 pos;
|
||||
int fd;
|
||||
};
|
||||
|
||||
extern int cdb_make_start(struct cdb_make *,int);
|
||||
extern int cdb_make_addbegin(struct cdb_make *,unsigned int,unsigned int);
|
||||
|
@ -179,9 +179,8 @@ SDB_API ut64* sdb_fmt_array_num(const char *list) {
|
||||
}
|
||||
|
||||
SDB_API char** sdb_fmt_array(const char *list) {
|
||||
char **retp, **ret = NULL;
|
||||
char *_s, **retp, **ret = NULL;
|
||||
const char *next, *ptr = list;
|
||||
char *_s;
|
||||
if (list && *list) {
|
||||
int len = sdb_alen (list);
|
||||
retp = ret = (char**) malloc (2*strlen (list) +
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* sdb - LGPLv3 - Copyright 2012-2014 - pancake */
|
||||
/* sdb - LGPLv3 - Copyright 2012-2015 - pancake */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "sdb.h"
|
||||
@ -84,14 +84,15 @@ SDB_API int sdb_json_unset (Sdb *s, const char *k, const char *p, ut32 cas) {
|
||||
SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, ut32 cas) {
|
||||
const char *beg[3];
|
||||
const char *end[3];
|
||||
int l, idx, len[3];
|
||||
char *b, *js, *str = NULL;
|
||||
int jslen, l, idx, len[3];
|
||||
char *b, *str = NULL;
|
||||
const char *js;
|
||||
Rangstr rs;
|
||||
ut32 c;
|
||||
|
||||
if (!s || !k)
|
||||
return 0;
|
||||
js = sdb_get (s, k, &c);
|
||||
return 0;
|
||||
js = sdb_const_get_len (s, k, &jslen, &c);
|
||||
if (!js) {
|
||||
b = malloc (strlen (p)+strlen (v)+8);
|
||||
if (b) {
|
||||
@ -110,12 +111,11 @@ SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, u
|
||||
return 0;
|
||||
}
|
||||
if (cas && c != cas) {
|
||||
free (js);
|
||||
return 0;
|
||||
}
|
||||
rs = json_get (js, p);
|
||||
if (!rs.p) {
|
||||
char *b = malloc (strlen (js)+strlen(k)+strlen (v)+32);
|
||||
char *b = malloc (jslen+strlen(k)+strlen (v)+32);
|
||||
if (b) {
|
||||
int curlen, is_str = isstring (v);
|
||||
const char *q = is_str?"\"":"";
|
||||
@ -127,11 +127,9 @@ SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, u
|
||||
strcpy (b+curlen, js+1);
|
||||
// transfer ownership
|
||||
sdb_set_owned (s, k, b, cas);
|
||||
free (js);
|
||||
return 1;
|
||||
}
|
||||
// invalid json?
|
||||
free (js);
|
||||
return 0;
|
||||
}
|
||||
#define WLEN(x) (int)(size_t)(end[x]-beg[x])
|
||||
@ -147,7 +145,7 @@ SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, u
|
||||
}
|
||||
|
||||
beg[2] = rs.p + rs.t;
|
||||
end[2] = js + strlen (js);
|
||||
end[2] = js + jslen;
|
||||
len[2] = WLEN (2);
|
||||
|
||||
// TODO: accelerate with small buffer in stack for small jsons
|
||||
@ -157,6 +155,8 @@ SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, u
|
||||
if (msz<1)
|
||||
return 0;
|
||||
str = malloc (msz);
|
||||
if (!str)
|
||||
return 0;
|
||||
idx = len[0];
|
||||
memcpy (str, beg[0], idx);
|
||||
if (is_str) {
|
||||
@ -207,7 +207,6 @@ SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, u
|
||||
str[len[0]+len[2]] = 0;
|
||||
}
|
||||
sdb_set_owned (s, k, str, cas);
|
||||
free (js);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -145,8 +145,9 @@ static void walk_namespace (StrBuf *sb, char *root, int left, char *p, SdbNs *ns
|
||||
|
||||
SDB_API char *sdb_querys (Sdb *r, char *buf, size_t len, const char *_cmd) {
|
||||
int i, d, ok, w, alength, bufset = 0, is_ref = 0, encode = 0;
|
||||
char *eq, *tmp, *json, *next, *quot, *arroba, *res, *cmd, *newcmd = NULL, *oldcmd = NULL;
|
||||
const char *p, *q, *val = NULL;
|
||||
char *eq, *tmp, *json, *next, *quot, *arroba, *res,
|
||||
*cmd, *newcmd = NULL, *oldcmd = NULL;
|
||||
StrBuf *out;
|
||||
Sdb *s = r;
|
||||
ut64 n;
|
||||
@ -394,6 +395,7 @@ next_quote:
|
||||
if (bufset && len<0xff) {
|
||||
free (buf);
|
||||
buf = malloc (0xff);
|
||||
if (!buf) goto fail;
|
||||
}
|
||||
bufset = 1;
|
||||
snprintf (buf, 0xff, "0x%"ULLFMT"x", n);
|
||||
@ -404,6 +406,7 @@ next_quote:
|
||||
if (bufset && len<0xff) {
|
||||
free (buf);
|
||||
buf = malloc (0xff);
|
||||
if (!buf) goto fail;
|
||||
}
|
||||
bufset = 1;
|
||||
snprintf (buf, 0xff, "%"ULLFMT"d", n);
|
||||
@ -418,19 +421,19 @@ next_quote:
|
||||
alength = sdb_array_length (s, p);
|
||||
if (!buf) {
|
||||
buf = malloc (len+1);
|
||||
if (!buf) goto fail;
|
||||
bufset = 1;
|
||||
}
|
||||
w = snprintf (buf, len, "%d", alength);
|
||||
if (w<0 || (size_t)w>len) {
|
||||
if (bufset)
|
||||
free (buf);
|
||||
buf = malloc (64);
|
||||
buf = malloc (32);
|
||||
bufset = 1;
|
||||
snprintf (buf, 63, "%d", alength);
|
||||
snprintf (buf, 31, "%d", alength);
|
||||
}
|
||||
out_concat (buf);
|
||||
} else
|
||||
if (cmd[1]=='+'||cmd[1]=='-') {
|
||||
} else if (cmd[1]=='+'||cmd[1]=='-') {
|
||||
if (cmd[1] == cmd[2]) {
|
||||
// stack
|
||||
#if 0
|
||||
@ -468,15 +471,17 @@ next_quote:
|
||||
// [+]K = remove first element
|
||||
// XXX: this is a little strange syntax to remove an item
|
||||
ret = sdb_array_get (s, p, 0, 0);
|
||||
if (ret && *ret)
|
||||
if (ret && *ret) {
|
||||
out_concat (ret);
|
||||
}
|
||||
// (+)foo :: remove first element
|
||||
sdb_array_delete (s, p, 0, 0);
|
||||
} else {
|
||||
// [-]K = remove last element
|
||||
ret = sdb_array_get (s, p, -1, 0);
|
||||
if (ret && *ret)
|
||||
if (ret && *ret) {
|
||||
out_concat (ret);
|
||||
}
|
||||
// (-)foo :: remove last element
|
||||
sdb_array_delete (s, p, -1, 0);
|
||||
}
|
||||
@ -525,8 +530,7 @@ next_quote:
|
||||
eprintf ("TODO: [b]foo -> get index of b key inside foo array\n");
|
||||
// sdb_array_dels (s, p, cmd+1, 0);
|
||||
}
|
||||
} else
|
||||
if (i<0) {
|
||||
} else if (i<0) {
|
||||
/* [-3]foo */
|
||||
char *tmp = sdb_array_get (s, p, -i, NULL);
|
||||
if (tmp && *tmp) {
|
||||
@ -714,11 +718,15 @@ SDB_API int sdb_query_lines (Sdb *s, const char *cmd) {
|
||||
}
|
||||
|
||||
static char *slurp(const char *file) {
|
||||
int ret, fd = open (file, O_RDONLY);
|
||||
int ret, fd;
|
||||
char *text;
|
||||
long sz;
|
||||
if (fd == -1)
|
||||
if (!file || !*file)
|
||||
return NULL;
|
||||
fd = open (file, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
sz = lseek (fd, 0, SEEK_END);
|
||||
if (sz<0){
|
||||
close (fd);
|
||||
@ -734,14 +742,19 @@ static char *slurp(const char *file) {
|
||||
if (ret != sz) {
|
||||
free (text);
|
||||
text = NULL;
|
||||
} else text[sz] = 0;
|
||||
} else {
|
||||
text[sz] = 0;
|
||||
}
|
||||
close (fd);
|
||||
return text;
|
||||
}
|
||||
|
||||
SDB_API int sdb_query_file(Sdb *s, const char* file) {
|
||||
int ret = 0;
|
||||
char *txt = slurp (file);
|
||||
int ret = sdb_query_lines (s, txt);
|
||||
free (txt);
|
||||
if (txt) {
|
||||
ret = sdb_query_lines (s, txt);
|
||||
free (txt);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ SDB_API Sdb* sdb_new (const char *path, const char *name, int lock) {
|
||||
Sdb* s = R_NEW0 (Sdb);
|
||||
if (!s) return NULL;
|
||||
s->fd = -1;
|
||||
s->dir = NULL;
|
||||
s->refs = 1;
|
||||
if (path && !*path)
|
||||
path = NULL;
|
||||
|
||||
if (name && *name && strcmp (name, "-")) {
|
||||
if (path && *path) {
|
||||
int plen = strlen (path);
|
||||
@ -59,9 +59,10 @@ SDB_API Sdb* sdb_new (const char *path, const char *name, int lock) {
|
||||
break;
|
||||
}
|
||||
if (sdb_open (s, s->dir) != -1) {
|
||||
if (fstat (s->fd, &st) != -1)
|
||||
if (s->fd > -1 && fstat (s->fd, &st) != -1) {
|
||||
if ((S_IFREG & st.st_mode) != S_IFREG)
|
||||
goto fail;
|
||||
}
|
||||
s->last = st.st_mtime;
|
||||
} else {
|
||||
s->last = sdb_now ();
|
||||
@ -194,7 +195,7 @@ SDB_API const char *sdb_const_get (Sdb* s, const char *key, ut32 *cas) {
|
||||
|
||||
// TODO: add sdb_getf?
|
||||
|
||||
SDB_API char *sdb_get (Sdb* s, const char *key, /*OUT*/ut32 *cas) {
|
||||
SDB_API char *sdb_get_len (Sdb* s, const char *key, int *vlen, ut32 *cas) {
|
||||
ut32 hash, pos, len, keylen;
|
||||
ut64 now = 0LL;
|
||||
SdbKv *kv;
|
||||
@ -217,6 +218,7 @@ SDB_API char *sdb_get (Sdb* s, const char *key, /*OUT*/ut32 *cas) {
|
||||
}
|
||||
}
|
||||
if (cas) *cas = kv->cas;
|
||||
if (vlen) *vlen = kv->value_len;
|
||||
return strdup (kv->value);
|
||||
}
|
||||
return NULL;
|
||||
@ -230,6 +232,8 @@ SDB_API char *sdb_get (Sdb* s, const char *key, /*OUT*/ut32 *cas) {
|
||||
return NULL;
|
||||
if ((len = cdb_datalen (&s->db))<1)
|
||||
return NULL;
|
||||
if (vlen)
|
||||
*vlen = len;
|
||||
if (!(buf = malloc (len+1))) // XXX too many mallocs
|
||||
return NULL;
|
||||
pos = cdb_datapos (&s->db);
|
||||
@ -238,6 +242,10 @@ SDB_API char *sdb_get (Sdb* s, const char *key, /*OUT*/ut32 *cas) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
SDB_API char *sdb_get (Sdb* s, const char *key, ut32 *cas) {
|
||||
return sdb_get_len (s, key, NULL, cas);
|
||||
}
|
||||
|
||||
SDB_API int sdb_unset (Sdb* s, const char *key, ut32 cas) {
|
||||
return key? sdb_set (s, key, "", cas): 0;
|
||||
}
|
||||
@ -246,8 +254,8 @@ SDB_API int sdb_unset (Sdb* s, const char *key, ut32 cas) {
|
||||
SDB_API int sdb_uncat(Sdb *s, const char *key, const char *value, ut32 cas) {
|
||||
// remove 'value' from current key value.
|
||||
// TODO: cas is ignored here
|
||||
char *p, *v = sdb_get (s, key, NULL);
|
||||
int vlen = strlen (value);
|
||||
int vlen;
|
||||
char *p, *v = sdb_get_len (s, key, &vlen, NULL);
|
||||
int mod = 0;
|
||||
while ((p = strstr (v, value))) {
|
||||
memmove (p, p+vlen, strlen (p+vlen)+1);
|
||||
@ -303,26 +311,29 @@ SDB_API int sdb_exists (Sdb* s, const char *key) {
|
||||
SDB_API int sdb_open (Sdb *s, const char *file) {
|
||||
if (!s) return -1;
|
||||
if (file) {
|
||||
char *realfile = strdup (file);
|
||||
sdb_close (s);
|
||||
s->fd = open (realfile, O_RDONLY|O_BINARY);
|
||||
free (s->dir);
|
||||
s->dir = realfile;
|
||||
} else {
|
||||
if (s->fd != -1) {
|
||||
close (s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
if (s->dir) {
|
||||
s->fd = open (file, O_RDONLY|O_BINARY);
|
||||
if (file != s->dir) {
|
||||
free (s->dir);
|
||||
s->dir = NULL;
|
||||
s->dir = strdup (file);
|
||||
}
|
||||
}
|
||||
return s->fd;
|
||||
}
|
||||
|
||||
SDB_API void sdb_close (Sdb *s) {
|
||||
(void)sdb_open (s, NULL);
|
||||
if (!s) return;
|
||||
if (s->fd != -1) {
|
||||
close (s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
if (s->dir) {
|
||||
free (s->dir);
|
||||
s->dir = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SDB_API void sdb_reset (Sdb* s) {
|
||||
@ -575,8 +586,11 @@ SDB_API int sdb_dump_dupnext (Sdb* s, char **key, char **value, int *_vlen) {
|
||||
*_vlen = vlen;
|
||||
if (key) {
|
||||
*key = 0;
|
||||
if (klen>0 && klen<0xff) {
|
||||
if (klen>=SDB_MIN_KEY && klen<SDB_MAX_KEY) {
|
||||
*key = malloc (klen+1);
|
||||
if (!*key) {
|
||||
return 0;
|
||||
}
|
||||
if (getbytes (s, *key, klen) == -1) {
|
||||
free (*key);
|
||||
*key = NULL;
|
||||
@ -587,7 +601,7 @@ SDB_API int sdb_dump_dupnext (Sdb* s, char **key, char **value, int *_vlen) {
|
||||
}
|
||||
if (value) {
|
||||
*value = 0;
|
||||
if (vlen>0 && vlen<0xffffff) {
|
||||
if (vlen>=SDB_MIN_VALUE && vlen<SDB_MAX_VALUE) {
|
||||
*value = malloc (vlen+10);
|
||||
if (!*value) {
|
||||
if (key) {
|
||||
@ -633,7 +647,7 @@ SDB_API int sdb_expire_set(Sdb* s, const char *key, ut64 expire, ut32 cas) {
|
||||
if (!cas || cas == kv->cas) {
|
||||
kv->expire = parse_expire (expire);
|
||||
return 1;
|
||||
} else return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -736,9 +750,7 @@ SDB_API void sdb_config(Sdb *s, int options) {
|
||||
}
|
||||
|
||||
SDB_API int sdb_unlink (Sdb* s) {
|
||||
// nullify Sdb
|
||||
sdb_fini (s, 1);
|
||||
// remove from disk
|
||||
return sdb_disk_unlink (s);
|
||||
}
|
||||
|
||||
@ -750,17 +762,6 @@ SDB_API void sdb_drain(Sdb *s, Sdb *f) {
|
||||
free (f);
|
||||
}
|
||||
|
||||
#if 0
|
||||
SDB_API void sdb_drain(Sdb *s, Sdb *f) {
|
||||
// drain f contents into s
|
||||
sdb_fini (s, 0);
|
||||
memcpy (s, f, sizeof (Sdb));
|
||||
// invalidates f, but doenst free's
|
||||
// invalidate = close fd, free'd mem hashtable
|
||||
memset (f, 0, sizeof (Sdb));
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
Sdb *sdb;
|
||||
const char *key;
|
||||
@ -773,7 +774,6 @@ static int unset_cb(void *user, const char *k, const char *v) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: rename to sdb_unset_similar ?
|
||||
SDB_API int sdb_unset_matching(Sdb *s, const char *k) {
|
||||
UnsetCallbackData ucd = { s, k };
|
||||
return sdb_foreach (s, unset_cb, &ucd);
|
||||
|
@ -21,6 +21,12 @@ extern "C" {
|
||||
#undef r_offsetof
|
||||
#define r_offsetof(type, member) ((unsigned long) &((type*)0)->member)
|
||||
|
||||
/* Key value sizes */
|
||||
#define SDB_MIN_VALUE 1
|
||||
#define SDB_MAX_VALUE 0xffffff
|
||||
#define SDB_MIN_KEY 1
|
||||
#define SDB_MAX_KEY 0xff
|
||||
|
||||
#define SDB_MODE 0644
|
||||
//#define SDB_MODE 0600
|
||||
|
||||
@ -99,6 +105,7 @@ int sdb_exists (Sdb*, const char *key);
|
||||
int sdb_unset (Sdb*, const char *key, ut32 cas);
|
||||
int sdb_unset_matching(Sdb *s, const char *k);
|
||||
char *sdb_get (Sdb*, const char *key, ut32 *cas);
|
||||
char *sdb_get_len (Sdb*, const char *key, int *vlen, ut32 *cas);
|
||||
const char *sdb_const_get (Sdb*, const char *key, ut32 *cas);
|
||||
const char *sdb_const_get_len (Sdb* s, const char *key, int *vlen, ut32 *cas);
|
||||
int sdb_set (Sdb*, const char *key, const char *data, ut32 cas);
|
||||
@ -206,6 +213,7 @@ int sdb_array_remove_num (Sdb* s, const char *key, ut64 val, ut32 cas);
|
||||
char *sdb_anext(char *str, char **next);
|
||||
const char *sdb_const_anext(const char *str, const char **next);
|
||||
int sdb_alen(const char *str);
|
||||
int sdb_alen_ignore_empty(const char *str);
|
||||
int sdb_array_size(Sdb* s, const char *key);
|
||||
int sdb_array_length(Sdb* s, const char *key);
|
||||
|
||||
|
@ -65,7 +65,6 @@
|
||||
// TODO: deprecate R_NEW
|
||||
#define R_NEW(x) (x*)malloc(sizeof(x))
|
||||
#define R_NEW0(x) (x*)calloc(1,sizeof(x))
|
||||
#define R_ANEW(x) (x*)cdb_alloc(sizeof(x))
|
||||
#define UT32_MAX ((ut32)0xffffffff)
|
||||
#define UT64_MAX ((ut64)(0xffffffffffffffffLL))
|
||||
#endif
|
||||
|
@ -139,6 +139,22 @@ SDB_API int sdb_alen(const char *str) {
|
||||
return len;
|
||||
}
|
||||
|
||||
SDB_API int sdb_alen_ignore_empty(const char *str) {
|
||||
int len = 1;
|
||||
const char *n, *p = str;
|
||||
if (!p || !*p) return 0;
|
||||
while (*p == SDB_RS) p++;
|
||||
for (len=0; ; ) {
|
||||
n = strchr (p, SDB_RS);
|
||||
if (!n) break;
|
||||
p = n+1;
|
||||
if (*(p) == SDB_RS) continue;
|
||||
len++;
|
||||
}
|
||||
if (*p) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
SDB_API char *sdb_anext(char *str, char **next) {
|
||||
char *nxt, *p = strchr (str, SDB_RS);
|
||||
if (p) { *p = 0; nxt = p+1; } else nxt = NULL;
|
||||
@ -188,11 +204,8 @@ SDB_API ut64 sdb_unow () {
|
||||
}
|
||||
|
||||
SDB_API int sdb_isnum (const char *s) {
|
||||
if (*s=='-' || *s=='+')
|
||||
return 1;
|
||||
if (*s>='0' && *s<='9')
|
||||
return 1;
|
||||
return 0;
|
||||
const char vs = *s;
|
||||
return ((vs=='-' || vs=='+') || (vs>='0' && vs<='9'));
|
||||
}
|
||||
|
||||
SDB_API int sdb_num_base (const char *s) {
|
||||
@ -207,8 +220,7 @@ SDB_API int sdb_match (const char *str, const char *glob) {
|
||||
if (*glob=='^') {
|
||||
if (!strncmp (str, glob+1, strlen (glob+1)))
|
||||
return 1;
|
||||
} else
|
||||
if (glob[strlen(glob)-1]=='$') {
|
||||
} else if (glob[strlen(glob)-1]=='$') {
|
||||
int glob_len = strlen (glob)-1;
|
||||
int str_len = strlen (str);
|
||||
if (str_len > glob_len) {
|
||||
@ -216,9 +228,9 @@ SDB_API int sdb_match (const char *str, const char *glob) {
|
||||
if (!strncmp (str + n, glob, glob_len))
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
if (strstr (str, glob))
|
||||
} else if (strstr (str, glob)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -267,4 +279,3 @@ SDB_API int sdb_isjson (const char *k) {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user