/* SDSLib, A C dynamic strings library
*
- * Copyright (c) 2006-2009, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* POSSIBILITY OF SUCH DAMAGE.
*/
- /* TODO: check if it can happen that _len+free > USHRT_MAX */
-
#define SDS_ABORT_ON_OOM
#include "sds.h"
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
- if (initlen >= USHRT_MAX) {
- sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
- sh->len = initlen;
- sh->_len = USHRT_MAX;
- #ifdef SDS_ABORT_ON_OOM
- if (sh == NULL) sdsOomAbort();
- #else
- if (sh == NULL) return NULL;
- #endif
- } else {
- sh = zmalloc(sizeof(int)+initlen+1);
- sh = (struct sdshdr*) (((char*)sh)-sizeof(int));
- #ifdef SDS_ABORT_ON_OOM
- if (sh == NULL) sdsOomAbort();
- #else
- if (sh == NULL) return NULL;
- #endif
- sh->_len = initlen;
- }
+ sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
+#ifdef SDS_ABORT_ON_OOM
+ if (sh == NULL) sdsOomAbort();
+#else
+ if (sh == NULL) return NULL;
+#endif
+ sh->len = initlen;
sh->free = 0;
if (initlen) {
if (init) memcpy(sh->buf, init, initlen);
size_t sdslen(const sds s) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
- if (sh->_len == USHRT_MAX)
- return sh->len;
- else
- return sh->_len;
+ return sh->len;
}
sds sdsdup(const sds s) {
}
void sdsfree(sds s) {
- struct sdshdr *sh;
-
if (s == NULL) return;
- sh = (void*) (s-(sizeof(struct sdshdr)));
- if (sh->_len == USHRT_MAX)
- zfree(s-sizeof(struct sdshdr));
- else
- zfree(s-sizeof(struct sdshdr)+sizeof(int));
+ zfree(s-sizeof(struct sdshdr));
}
size_t sdsavail(sds s) {
void sdsupdatelen(sds s) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
int reallen = strlen(s);
-
- if (sh->_len == USHRT_MAX) {
- sh->free += (sh->len-reallen);
- sh->len = reallen;
- } else {
- sh->free += (sh->_len-reallen);
- sh->_len = reallen;
- }
+ sh->free += (sh->len-reallen);
+ sh->len = reallen;
}
static sds sdsMakeRoomFor(sds s, size_t addlen) {
struct sdshdr *sh, *newsh;
size_t free = sdsavail(s);
- size_t len, newlen, newfree;
+ size_t len, newlen;
- if (free >= addlen) {
- sh = (void*) (s-(sizeof(struct sdshdr)));
- if (sh->_len == USHRT_MAX) {
- sh->len += addlen;
- } else {
- sh->_len += addlen;
- }
- sh->free -= addlen;
- return s;
- }
+ if (free >= addlen) return s;
len = sdslen(s);
sh = (void*) (s-(sizeof(struct sdshdr)));
- newlen = (len+addlen);
- newfree = ((addlen*2) > USHRT_MAX) ? USHRT_MAX : (addlen*2);
- if (newlen+newfree >= USHRT_MAX || sh->_len == USHRT_MAX) {
- if (sh->_len == USHRT_MAX) {
- newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1+newfree);
- } else {
- newsh = zmalloc(sizeof(struct sdshdr)+newlen+1+newfree);
- if (!newsh) return NULL;
- memcpy(newsh->buf,sh->buf,len);
- newsh->buf[len] = '\0';
- zfree(((char*)sh)+sizeof(int));
- }
-#ifdef SDS_ABORT_ON_OOM
- if (newsh == NULL) sdsOomAbort();
-#else
- if (newsh == NULL) return NULL;
-#endif
- newsh->_len = USHRT_MAX;
- newsh->free = newfree;
- newsh->len = newlen;
- } else {
- newsh = zrealloc(((char*)sh)+sizeof(int), sizeof(int)+newlen+1+newfree);
- newsh = (struct sdshdr*) (((char*)newsh)-sizeof(int));
+ newlen = (len+addlen)*2;
+ newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
#ifdef SDS_ABORT_ON_OOM
- if (newsh == NULL) sdsOomAbort();
+ if (newsh == NULL) sdsOomAbort();
#else
- if (newsh == NULL) return NULL;
+ if (newsh == NULL) return NULL;
#endif
- newsh->_len = newlen;
- newsh->free = newfree;
- }
+
+ newsh->free = newlen - len;
return newsh->buf;
}
sds sdscatlen(sds s, void *t, size_t len) {
+ struct sdshdr *sh;
size_t curlen = sdslen(s);
s = sdsMakeRoomFor(s,len);
if (s == NULL) return NULL;
+ sh = (void*) (s-(sizeof(struct sdshdr)));
memcpy(s+curlen, t, len);
+ sh->len = curlen+len;
+ sh->free = sh->free-len;
s[curlen+len] = '\0';
return s;
}
sds sdscpylen(sds s, char *t, size_t len) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
- size_t totlen;
-
- if (sh->_len == USHRT_MAX) {
- totlen = sh->free+sh->len;
- } else {
- totlen = sh->free+sh->_len;
- }
+ size_t totlen = sh->free+sh->len;
if (totlen < len) {
- s = sdsMakeRoomFor(s,len-totlen);
+ s = sdsMakeRoomFor(s,len-sh->len);
if (s == NULL) return NULL;
+ sh = (void*) (s-(sizeof(struct sdshdr)));
+ totlen = sh->free+sh->len;
}
memcpy(s, t, len);
s[len] = '\0';
+ sh->len = len;
+ sh->free = totlen-len;
return s;
}
sds sdscatprintf(sds s, const char *fmt, ...) {
va_list ap;
char *buf, *t;
- size_t buflen = 32;
+ size_t buflen = 16;
while(1) {
buf = zmalloc(buflen);
len = (sp > ep) ? 0 : ((ep-sp)+1);
if (sh->buf != sp) memmove(sh->buf, sp, len);
sh->buf[len] = '\0';
- if (sh->_len == USHRT_MAX) {
- sh->free = sh->free+(sh->len-len);
- sh->len = len;
- } else {
- sh->free = sh->free+(sh->_len-len);
- sh->_len = len;
- }
+ sh->free = sh->free+(sh->len-len);
+ sh->len = len;
return s;
}
}
if (start != 0) memmove(sh->buf, sh->buf+start, newlen);
sh->buf[newlen] = 0;
- if (sh->_len == USHRT_MAX) {
- sh->free = sh->free+(sh->len-newlen);
- sh->len = newlen;
- } else {
- sh->free = sh->free+(sh->_len-newlen);
- sh->_len = newlen;
- }
+ sh->free = sh->free+(sh->len-newlen);
+ sh->len = newlen;
return s;
}
if (tokens == NULL) sdsOomAbort();
#endif
if (seplen < 1 || len < 0 || tokens == NULL) return NULL;
+ if (len == 0) {
+ *count = 0;
+ return tokens;
+ }
for (j = 0; j < (len-(seplen-1)); j++) {
/* make sure there is room for the next element and the final one */
if (slots < elements+2) {
}
#endif
}
+
+void sdsfreesplitres(sds *tokens, int count) {
+ if (!tokens) return;
+ while(count--)
+ sdsfree(tokens[count]);
+ zfree(tokens);
+}
+
+sds sdsfromlonglong(long long value) {
+ char buf[32], *p;
+ unsigned long long v;
+
+ v = (value < 0) ? -value : value;
+ p = buf+31; /* point to the last character */
+ do {
+ *p-- = '0'+(v%10);
+ v /= 10;
+ } while(v);
+ if (value < 0) *p-- = '-';
+ p++;
+ return sdsnewlen(p,32-(p-buf));
+}