示例#1
0
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;
}
示例#2
0
文件: array.c 项目: AmesianX/radare2
// TODO: done, but there's room for improvement
SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
	int lnstr, lstr, lval;
	char *x, *ptr;
	const char *str = sdb_const_get_len (s, key, &lstr, 0);
	if (!str || !*str) {
		return sdb_set (s, key, val, cas);
	}
	lval = strlen (val);
	lstr--;
	//lstr = strlen (str); // we can optimize this by caching value len in memory . add sdb_const_get_size()
	x = malloc (lval + lstr + 2);
	if (idx == -1) {
		memcpy (x, str, lstr);
		x[lstr] = SDB_RS;
		memcpy (x+lstr+1, val, lval + 1);
	} else if (idx == 0) {
		memcpy (x, val, lval);
		x[lval] = SDB_RS;
		memcpy (x + lval + 1, str, lstr + 1);
	} else {
		char *nstr = malloc (lstr + 1);
		if (!nstr) {
			free (x);
			return false;
		}
		memcpy (nstr, str, lstr + 1);
		ptr = (char *)Aindexof (nstr, idx);
		if (ptr) {
			int lptr = (nstr+lstr+1)-ptr;
			*(ptr-1) = 0;
			lnstr = ptr-nstr-1;
			memcpy (x, nstr, lnstr);
			x[lnstr] = SDB_RS;
			memcpy (x + lnstr + 1, val, lval);
			x[lnstr + lval + 1] = SDB_RS;
			// TODO: this strlen hurts performance
			memcpy (x + lval + 2 + lnstr, ptr, lptr); //strlen (ptr)+1);
			free (nstr);
		} else {
			// this is not efficient
			free (nstr);
			free (x);
			// fallback for empty buckets
			return sdb_array_set (s, key, idx, val, cas);
		}
	}
	return sdb_set_owned (s, key, x, cas);
}
示例#3
0
// TODO: done, but there's room for improvement
SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val,
			      ut32 cas) {
	int lnstr, lstr;
	size_t lval;
	char *x, *ptr;
	const char *str = sdb_const_get_len (s, key, &lstr, 0);
	if (!str || !*str) {
		return sdb_set (s, key, val, cas);
	}
	lval = strlen (val);
	lstr--;
	// XXX: lstr is wrongly computed in sdb_const_get_with an off-by-one
	// we can optimize this by caching value len in memory . add
	// sdb_const_get_size()
	lstr = strlen (str); 

	// When removing strlen this conversion should be checked
	size_t lstr_tmp = lstr;
	if (SZT_ADD_OVFCHK (lval, lstr_tmp) || SZT_ADD_OVFCHK (lval + lstr_tmp, 2)) {
		return false;
	}
	x = malloc (lval + lstr_tmp + 2);
	if (!x) {
		return false;
	}

	if (idx == -1) {
		memcpy (x, str, lstr);
		x[lstr] = SDB_RS;
		memcpy (x + lstr + 1, val, lval + 1);
	} else if (!idx) {
		memcpy (x, val, lval);
		x[lval] = SDB_RS;
		memcpy (x + lval + 1, str, lstr + 1);
	} else {
		char *nstr = malloc (lstr + 1);
		if (!nstr) {
			free (x);
			return false;
		}
		memcpy (nstr, str, lstr + 1);
		ptr = (char *)Aindexof (nstr, idx);
		if (ptr) {
			int lptr = (nstr + lstr + 1) - ptr;
			char *p_1 = ptr > nstr? ptr - 1: ptr;
			*p_1 = 0;
			lnstr = ptr - nstr - 1;
			memcpy (x, nstr, lnstr);
			x[lnstr] = SDB_RS;
			memcpy (x + lnstr + 1, val, lval);
			x[lnstr + lval + 1] = SDB_RS;
			// TODO: this strlen hurts performance
			memcpy (x + lval + 2 + lnstr, ptr, lptr); //strlen (ptr)+1);
			free (nstr);
		} else {
			// this is not efficient
			free (nstr);
			free (x);
			// fallback for empty buckets
			return sdb_array_set (s, key, idx, val, cas);
		}
	}
	return sdb_set_owned (s, key, x, cas);
}