]> git.saurik.com Git - redis.git/blobdiff - sds.c
basic support to tag tests
[redis.git] / sds.c
diff --git a/sds.c b/sds.c
index b63a4a766173fbaed81daac13a9c272729654414..feb1a6212e657661dbe0a1de5a9b028b1e79e7af 100644 (file)
--- a/sds.c
+++ b/sds.c
@@ -1,6 +1,6 @@
 /* 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
@@ -28,8 +28,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
- /* TODO: check if it can happen that _len+free > USHRT_MAX */
-
 #define SDS_ABORT_ON_OOM
 
 #include "sds.h"
@@ -48,25 +46,13 @@ static void sdsOomAbort(void) {
 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);
@@ -87,10 +73,7 @@ sds sdsnew(const char *init) {
 
 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) {
@@ -98,14 +81,8 @@ 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) {
@@ -116,73 +93,40 @@ 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;
 }
@@ -193,20 +137,18 @@ sds sdscat(sds s, char *t) {
 
 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;
 }
 
@@ -217,7 +159,7 @@ sds sdscpy(sds s, char *t) {
 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);
@@ -254,13 +196,8 @@ sds sdstrim(sds s, const char *cset) {
     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;
 }
 
@@ -287,13 +224,8 @@ sds sdsrange(sds s, long start, long end) {
     }
     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;
 }
 
@@ -345,6 +277,10 @@ sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {
     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) {
@@ -399,3 +335,25 @@ cleanup:
     }
 #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));
+}