SDB_API int sdb_array_delete(Sdb *s, const char *key, int idx, ut32 cas) { int i; char *p, *n, *str = sdb_get (s, key, 0); p = str; if (!str || !*str) { free (str); return 0; } if (idx < 0) { idx = sdb_alen (str); if (idx) idx--; } for (i = 0; i < idx; i++) { if ( (n = strchr (p, SDB_RS)) ) { p = n + 1; } else { free (str); return 0; } } n = strchr (p, SDB_RS); if (n) { memmove (p, n + 1, strlen (n)); } else { if (p != str) p--; // remove tailing SDB_RS *p = 0; p[1] = 0; } sdb_set_owned (s, key, str, cas); return 1; }
SDB_API char *sdb_array_get(Sdb *s, const char *key, int idx, ut32 *cas) { const char *str = sdb_const_get (s, key, cas); const char *p = str; char *o, *n; int i, len; if (!str || !*str) return NULL; if (idx<0) { int len = sdb_alen (str); idx = -idx; if (idx>len) return NULL; idx = (len-idx); } if (idx==0) { n = strchr (str, SDB_RS); if (!n) return strdup (str); len = n-str; o = malloc (len+1); memcpy (o, str, len); o[len] = 0; return o; } for (i=0; i<idx; i++) { n = strchr (p, SDB_RS); if (!n) return NULL; p = n+1; } n = strchr (p, SDB_RS); if (!n) return strdup (p); len = n-p; o = malloc (len+1); memcpy (o, p, len); o[len] = 0; return o; }
SDB_API int sdb_array_set(Sdb *s, const char *key, int idx, const char *val, ut32 cas) { int lstr, lval, len; const char *usr, *str = sdb_const_get_len (s, key, &lstr, 0); char *ptr; if (!str || !*str) { return sdb_set (s, key, val, cas); } // XXX: should we cache sdb_alen value inside kv? len = sdb_alen (str); lstr--; if (idx < 0 || idx == len) { // append return sdb_array_insert (s, key, -1, val, cas); } lval = strlen (val); if (idx > len) { int ret, i, ilen = idx-len; char *newkey = malloc (ilen + lval + 1); if (!newkey) { return 0; } for (i = 0; i < ilen; i++) { newkey [i] = SDB_RS; } memcpy (newkey + i, val, lval + 1); ret = sdb_array_insert (s, key, -1, newkey, cas); free (newkey); return ret; } //lstr = strlen (str); ptr = (char*)Aindexof (str, idx); if (ptr) { int diff = ptr - str; char *nstr = malloc (lstr + lval + 2); if (!nstr) { return false; } ptr = nstr + diff; //memcpy (nstr, str, lstr+1); memcpy (nstr, str, diff); memcpy (ptr, val, lval + 1); usr = Aindexof (str, idx + 1); if (usr) { ptr[lval] = SDB_RS; strcpy (ptr + lval + 1, usr); } return sdb_set_owned (s, key, nstr, 0); } return 0; }
// TODO: move this into fmt? SDB_API ut64* sdb_fmt_array_num(const char *list) { ut64 *retp, *ret = NULL; const char *next, *ptr = list; if (list && *list) { int len = sdb_alen (list); retp = ret = (ut64*) malloc (sizeof(ut64)*(len+1)); if (!ret) return NULL; *retp++ = len; do { const char *str = sdb_anext2 (ptr, &next); ut64 n = sdb_atoi (str); *retp++ = n; ptr = next; } while (next); } return ret; }
int main(int argc, char **argv) { int i, N; if (argc>1) N = atoi (argv[1]); else N = 1000; Sdb *s = sdb_new (NULL, NULL, 0); for (i=0;i<N;i++) sdb_array_push (s, "key", "foo", 0); #if 1 if (N != sdb_alen (sdb_const_get (s, "key", 0))) { printf ("FAIL IN VERY PUSH\n"); return 1; } eprintf ("--%d\n", (int)strlen (sdb_const_get (s, "key", 0))); #endif for (i=0;i<N;i++) free (sdb_array_pop (s, "key", 0)); sdb_free (s); return 0; }
SDB_API int sdb_array_size(Sdb *s, const char *key) { return sdb_alen (sdb_const_get (s, key, 0)); }