diff --git a/libr/include/sdb/sdb.h b/libr/include/sdb/sdb.h index a1a25f1029ae2..3de4aa5961574 100644 --- a/libr/include/sdb/sdb.h +++ b/libr/include/sdb/sdb.h @@ -16,6 +16,11 @@ extern "C" { #include "cdb_make.h" #include "sdb-version.h" +#undef R_MAX +#define R_MAX(x,y) (((x)>(y))?(x):(y)) +#undef r_offsetof +#define r_offsetof(type, member) ((unsigned long) &((type*)0)->member) + //#define SDB_RS '\x1e' #define SDB_RS ',' #define SDB_SS "," @@ -194,9 +199,15 @@ 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); +char *sdb_encode(const ut8 *bin, int len); +void sdb_encode_raw(char *bout, const ut8 *bin, int len); +int sdb_decode_raw(ut8 *bout, const char *bin, int len); + +// binfmt +int sdb_fmt_init (void *p, const char *fmt); +void sdb_fmt_free (void *p, const char *fmt); +int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru); +char *sdb_fmt_tostr(void *stru, const char *fmt); #ifdef __cplusplus } diff --git a/shlr/sdb/config.mk b/shlr/sdb/config.mk index f22fbb7e6aee7..89673698206df 100644 --- a/shlr/sdb/config.mk +++ b/shlr/sdb/config.mk @@ -30,6 +30,7 @@ CFLAGS+=$(shell gcc -v 2>&1 | grep -q LLVM && echo '-Wno-initializer-overrides') CFLAGS+=-Wall #CFLAGS+=-O3 #CFLAGS+=-ggdb -g -Wall -O0 +CFLAGS+=-g HAVE_VALA=#$(shell valac --version 2> /dev/null) # This is hacky diff --git a/shlr/sdb/src/Makefile b/shlr/sdb/src/Makefile index 694b7b2a7a43a..81a3c7cd6d3d1 100644 --- a/shlr/sdb/src/Makefile +++ b/shlr/sdb/src/Makefile @@ -2,7 +2,7 @@ include ../config.mk CFLAGS+= -g -ggdb 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 +OBJ+=json.o ns.o lock.o util.o disk.o query.o array.o fmt.o SOBJ=$(subst .o,._o,${OBJ}) diff --git a/shlr/sdb/src/array.c b/shlr/sdb/src/array.c index f6f0878b8112f..ae0f52bf3ccc8 100644 --- a/shlr/sdb/src/array.c +++ b/shlr/sdb/src/array.c @@ -19,6 +19,7 @@ SDB_API const char *sdb_array_next(const char *str) { return str+strlen (str)+1; } +// TODO: nxt can be a pointer to the string, not a bool and we can get ird of array_next() SDB_API char *sdb_array_string(char *str, int *hasnext) { int nxt = 0; char *p = strchr (str, SDB_RS); diff --git a/shlr/sdb/src/base64.c b/shlr/sdb/src/base64.c index b8e6dfde46b36..0ec69c860aef7 100644 --- a/shlr/sdb/src/base64.c +++ b/shlr/sdb/src/base64.c @@ -59,7 +59,7 @@ SDB_API char *sdb_encode(const ut8 *bin, int len) { len = strlen ((const char *)bin)+1; if (len==0) return strdup (""); - out = malloc (len+8); + out = malloc (len*2); if (!out) return NULL; memset (out, 0, len+8); @@ -70,7 +70,9 @@ SDB_API char *sdb_encode(const ut8 *bin, int len) { SDB_API ut8 *sdb_decode (const char *in, int *len) { ut8 *out; int olen, ilen = strlen (in); - out = malloc (ilen+8); + if (ilen<1) + return NULL; + out = malloc (ilen*2); if (!out) return NULL; memset (out, 0, ilen+8); diff --git a/shlr/sdb/src/fmt.c b/shlr/sdb/src/fmt.c new file mode 100644 index 0000000000000..85e2aca8f5639 --- /dev/null +++ b/shlr/sdb/src/fmt.c @@ -0,0 +1,135 @@ +/* sdb - LGPLv3 - Copyright 2014 - pancake */ + +#include "sdb.h" + +// SLOW CONCAT +#define out_concat(x) if (x) { \ + char *o =(void*)realloc((void*)out, 2+strlen(x)+(out?strlen(out):0)); \ + if (o) { if (*o) strcat (o, ","); out=o; strcat (o, x); } \ +} + +SDB_API char *sdb_fmt_tostr(void *stru, const char *fmt) { + const char *num; + char *out = NULL; + ut8 *p = stru; + char buf[128]; + int n, len = 0; + + for (; *fmt; fmt++) { + n = 4; + switch (*fmt) { + case 'b': + num = sdb_itoa ((ut64)*((ut8*)(p+len)), buf, 10); + out_concat (num); + break; + case 'h': + num = sdb_itoa ((ut64)*((short*)(p+len)), buf, 10); + out_concat (num); + break; + case 'd': + num = sdb_itoa ((ut64)*((int*)(p+len)), buf, 10); + out_concat (num); + break; + case 'q': + num = sdb_itoa (*((ut64*)(p+len)), buf, 10); + out_concat (num); + n = 8; + break; + case 's': + { + char *e_str = sdb_encode ((const ut8*)*((char**)(p+len)), 0); + out_concat (e_str); + free (e_str); + } + break; + case 'p': + num = sdb_itoa ((ut64)*((size_t*)(p+len)), buf, 16); + out_concat (num); + n = sizeof (size_t); + break; + } + len += R_MAX (sizeof (void*), n); // align + } + return out; +} + +// TODO: return false if array length != fmt length +SDB_API int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru) { + int nxt, n, idx = 0; + char *str, *ptr, *word; + str = ptr = strdup (_str); + for (; *fmt; fmt++) { + word = sdb_array_string (ptr, &nxt); + if (!word || !*word) + break; + n = 4; // ALIGN + switch (*fmt) { + case 'q': *((ut64*)(stru + idx)) = sdb_atoi (word); n=8; break; + case 'h': *((short*)(stru + idx)) = (short)sdb_atoi (word); break; + case 'd': *((int*)(stru + idx)) = (int)sdb_atoi (word); break; + case 's': + { + ut8 *e_str = sdb_decode (word, 0); + if (!e_str) e_str = (ut8*)word; + *((char**)(stru + idx)) = (char*)e_str; + } + break; + case 'p': *((void**)(stru + idx)) = (void*)(size_t)sdb_atoi (word); + break; + default: eprintf ("WTF\n"); break; + } + idx += R_MAX(sizeof (void*), n); // align + if (!nxt) + break; + ptr = (char*)sdb_array_next (word); + } + return 1; +} + +SDB_API void sdb_fmt_free (void *p, const char *fmt) { + // TODO: free() 's' and memset the rest +} + +SDB_API int sdb_fmt_init (void *p, const char *fmt) { + int len = 0; + for (; *fmt; fmt++) { + switch (*fmt) { + case 'b': len += sizeof (ut8); break; // 1 + case 'h': len += sizeof (short); break; // 2 + case 'd': len += sizeof (ut32); break; // 4 + case 'q': len += sizeof (ut64); break; // 8 + case 's': len += sizeof (char*); break; // void* + case 'p': len += sizeof (char*); break; // void * + } + } + if (p) memset (p, 0, len); + return len; +} + + +#if 0 +main() { + #define STRUCT_PERSON_FORMAT "ds" + #define STRUCT_PERSON_SIZE sizeof (struct Person) + typedef struct person { + int foo; + char *str; + ut64 fin; + int end; + } Person; + + Person p; + + sdb_fmt_init (&p, "dsqd"); + sdb_fmt_tobin ("123,bar,321,1", "dsqd", &p); + eprintf ("--> %d,%s\n", p.foo, p.str); + eprintf ("--> %lld,%d\n", p.fin, p.end); + + { + char *o = sdb_fmt_tostr (&p, "dsqd"); + eprintf ("== %s\n", o); + free (o); + } + sdb_fmt_free (&p, "ds"); +} +#endif diff --git a/shlr/sdb/src/sdb.h b/shlr/sdb/src/sdb.h index a1a25f1029ae2..3de4aa5961574 100644 --- a/shlr/sdb/src/sdb.h +++ b/shlr/sdb/src/sdb.h @@ -16,6 +16,11 @@ extern "C" { #include "cdb_make.h" #include "sdb-version.h" +#undef R_MAX +#define R_MAX(x,y) (((x)>(y))?(x):(y)) +#undef r_offsetof +#define r_offsetof(type, member) ((unsigned long) &((type*)0)->member) + //#define SDB_RS '\x1e' #define SDB_RS ',' #define SDB_SS "," @@ -194,9 +199,15 @@ 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); +char *sdb_encode(const ut8 *bin, int len); +void sdb_encode_raw(char *bout, const ut8 *bin, int len); +int sdb_decode_raw(ut8 *bout, const char *bin, int len); + +// binfmt +int sdb_fmt_init (void *p, const char *fmt); +void sdb_fmt_free (void *p, const char *fmt); +int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru); +char *sdb_fmt_tostr(void *stru, const char *fmt); #ifdef __cplusplus } diff --git a/shlr/sdb/src/util.c b/shlr/sdb/src/util.c index 53a5cc103bbf6..24358a1e686ba 100644 --- a/shlr/sdb/src/util.c +++ b/shlr/sdb/src/util.c @@ -18,22 +18,12 @@ SDB_API int sdb_check_value(const char *s) { } SDB_API int sdb_check_key(const char *s) { + const char *special_chars = "\"+-=[]:$;"; if (!s || !*s) return 0; - for (; *s; s++) { - switch (*s) { - case '"': - case '+': - case '-': - case '=': - case '[': - case ']': - case ':': - case '$': // eval value of given key - case ';': + for (; *s; s++) + if (strchr (special_chars, *s)) return 0; - } - } return 1; } @@ -41,39 +31,33 @@ SDB_API int sdb_check_key(const char *s) { SDB_API ut32 sdb_hash(const char *s, int len) { ut32 h = CDB_HASHSTART; if (len<1) { - while (*s) { - h += (h<<5); - h ^= *s++; - } + while (*s) + h = (h+(h<<5))^*s++; } else { - while (len--) { - h += (h<<5); - h ^= *s++; - } + while (len--) + h = (h+(h<<5))^*s++; } return h; } +// assert (sizeof (s)>64) SDB_API char *sdb_itoa(ut64 n, char *s, int base) { + static const char* lookup = "0123456789abcdef"; int i = 62; if (!s) { s = malloc (64); + if (!s) return NULL; memset (s, 0, 64); } s[63] = '\0'; if (base==16) { - static const char* lookup = "0123456789abcdef"; - do { + for (; n && i>0; n/=16) s[i--] = lookup[(n % 16)]; - if (i==0) break; - } while(n/=16); s[i--] = 'x'; s[i--] = '0'; } else { - do { + for (; n && i>0; n/=10) s[i--] = (n % 10) + '0'; - if (i==0) break; - } while (n/=10); } return s+i+1; } @@ -102,19 +86,21 @@ SDB_API int sdb_alen(const char *str) { } SDB_API ut64 sdb_now () { - struct timeval now; - gettimeofday (&now, NULL); - return now.tv_sec; + struct timeval now; + if (!gettimeofday (&now, NULL)) + return now.tv_sec; + return 0LL; } SDB_API ut64 sdb_unow () { ut64 x; struct timeval now; - gettimeofday (&now, NULL); - x = now.tv_sec; - x <<= 32; - x += now.tv_usec; - return x; + if (!gettimeofday (&now, NULL)) { + x = now.tv_sec; + x <<= 32; + x += now.tv_usec; + } else x = 0LL; + return x; } SDB_API int sdb_isnum (const char *s) {