Update string library
This commit is contained in:
parent
c6b8bd77c0
commit
7aa5fa102e
120
sds.c
120
sds.c
@ -115,6 +115,25 @@ static sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|||||||
return newsh->buf;
|
return newsh->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Grow the sds to have the specified length. Bytes that were not part of
|
||||||
|
* the original length of the sds will be set to zero. */
|
||||||
|
sds sdsgrowzero(sds s, size_t len) {
|
||||||
|
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
|
||||||
|
size_t totlen, curlen = sh->len;
|
||||||
|
|
||||||
|
if (len <= curlen) return s;
|
||||||
|
s = sdsMakeRoomFor(s,len-curlen);
|
||||||
|
if (s == NULL) return NULL;
|
||||||
|
|
||||||
|
/* Make sure added region doesn't contain garbage */
|
||||||
|
sh = (void*)(s-(sizeof(struct sdshdr)));
|
||||||
|
memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
|
||||||
|
totlen = sh->len+sh->free;
|
||||||
|
sh->len = len;
|
||||||
|
sh->free = totlen-sh->len;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
sds sdscatlen(sds s, const void *t, size_t len) {
|
sds sdscatlen(sds s, const void *t, size_t len) {
|
||||||
struct sdshdr *sh;
|
struct sdshdr *sh;
|
||||||
size_t curlen = sdslen(s);
|
size_t curlen = sdslen(s);
|
||||||
@ -222,13 +241,16 @@ sds sdsrange(sds s, int start, int end) {
|
|||||||
}
|
}
|
||||||
newlen = (start > end) ? 0 : (end-start)+1;
|
newlen = (start > end) ? 0 : (end-start)+1;
|
||||||
if (newlen != 0) {
|
if (newlen != 0) {
|
||||||
if (start >= (signed)len) start = len-1;
|
if (start >= (signed)len) {
|
||||||
if (end >= (signed)len) end = len-1;
|
newlen = 0;
|
||||||
newlen = (start > end) ? 0 : (end-start)+1;
|
} else if (end >= (signed)len) {
|
||||||
|
end = len-1;
|
||||||
|
newlen = (start > end) ? 0 : (end-start)+1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
if (start != 0) memmove(sh->buf, sh->buf+start, newlen);
|
if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
|
||||||
sh->buf[newlen] = 0;
|
sh->buf[newlen] = 0;
|
||||||
sh->free = sh->free+(sh->len-newlen);
|
sh->free = sh->free+(sh->len-newlen);
|
||||||
sh->len = newlen;
|
sh->len = newlen;
|
||||||
@ -477,3 +499,93 @@ err:
|
|||||||
if (current) sdsfree(current);
|
if (current) sdsfree(current);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SDS_TEST_MAIN
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "testhelp.h"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
{
|
||||||
|
sds x = sdsnew("foo"), y;
|
||||||
|
|
||||||
|
test_cond("Create a string and obtain the length",
|
||||||
|
sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
|
||||||
|
|
||||||
|
sdsfree(x);
|
||||||
|
x = sdsnewlen("foo",2);
|
||||||
|
test_cond("Create a string with specified length",
|
||||||
|
sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
|
||||||
|
|
||||||
|
x = sdscat(x,"bar");
|
||||||
|
test_cond("Strings concatenation",
|
||||||
|
sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
|
||||||
|
|
||||||
|
x = sdscpy(x,"a");
|
||||||
|
test_cond("sdscpy() against an originally longer string",
|
||||||
|
sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
|
||||||
|
|
||||||
|
x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
|
||||||
|
test_cond("sdscpy() against an originally shorter string",
|
||||||
|
sdslen(x) == 33 &&
|
||||||
|
memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
|
||||||
|
|
||||||
|
sdsfree(x);
|
||||||
|
x = sdscatprintf(sdsempty(),"%d",123);
|
||||||
|
test_cond("sdscatprintf() seems working in the base case",
|
||||||
|
sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
|
||||||
|
|
||||||
|
sdsfree(x);
|
||||||
|
x = sdstrim(sdsnew("xxciaoyyy"),"xy");
|
||||||
|
test_cond("sdstrim() correctly trims characters",
|
||||||
|
sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
|
||||||
|
|
||||||
|
y = sdsrange(sdsdup(x),1,1);
|
||||||
|
test_cond("sdsrange(...,1,1)",
|
||||||
|
sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
y = sdsrange(sdsdup(x),1,-1);
|
||||||
|
test_cond("sdsrange(...,1,-1)",
|
||||||
|
sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
y = sdsrange(sdsdup(x),-2,-1);
|
||||||
|
test_cond("sdsrange(...,-2,-1)",
|
||||||
|
sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
y = sdsrange(sdsdup(x),2,1);
|
||||||
|
test_cond("sdsrange(...,2,1)",
|
||||||
|
sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
y = sdsrange(sdsdup(x),1,100);
|
||||||
|
test_cond("sdsrange(...,1,100)",
|
||||||
|
sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
y = sdsrange(sdsdup(x),100,100);
|
||||||
|
test_cond("sdsrange(...,100,100)",
|
||||||
|
sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
sdsfree(x);
|
||||||
|
x = sdsnew("foo");
|
||||||
|
y = sdsnew("foa");
|
||||||
|
test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
sdsfree(x);
|
||||||
|
x = sdsnew("bar");
|
||||||
|
y = sdsnew("bar");
|
||||||
|
test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
|
||||||
|
|
||||||
|
sdsfree(y);
|
||||||
|
sdsfree(x);
|
||||||
|
x = sdsnew("aar");
|
||||||
|
y = sdsnew("bar");
|
||||||
|
test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
|
||||||
|
}
|
||||||
|
test_report()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
1
sds.h
1
sds.h
@ -49,6 +49,7 @@ size_t sdslen(const sds s);
|
|||||||
sds sdsdup(const sds s);
|
sds sdsdup(const sds s);
|
||||||
void sdsfree(sds s);
|
void sdsfree(sds s);
|
||||||
size_t sdsavail(sds s);
|
size_t sdsavail(sds s);
|
||||||
|
sds sdsgrowzero(sds s, size_t len);
|
||||||
sds sdscatlen(sds s, const void *t, size_t len);
|
sds sdscatlen(sds s, const void *t, size_t len);
|
||||||
sds sdscat(sds s, const char *t);
|
sds sdscat(sds s, const char *t);
|
||||||
sds sdscpylen(sds s, char *t, size_t len);
|
sds sdscpylen(sds s, char *t, size_t len);
|
||||||
|
Loading…
Reference in New Issue
Block a user