#include <stdio.h> #include <string.h> #include "zmalloc.h" #include "testhelp.h" typedef char *sds; struct sdshdr { unsigned int len; unsigned int free; char buf[]; }; static inline size_t sdslen(const sds s) { printf("sizeof(struct sdshdr)=%d\n",sizeof(struct sdshdr)); struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); printf("sh->buf=%s\n",sh->buf); printf("sh->len=%d\n",sh->len); return sh->len; } /* Create a new sds string with the content specified by the 'init' pointer * and 'initlen'. * If NULL is used for 'init' the string is initialized with zero bytes. * * The string is always null-termined (all the sds strings are, always) so * even if you create an sds string with: * * mystring = sdsnewlen("abc",3); * * You can print the string with printf() as there is an implicit \0 at the * end of the string. However the string is binary safe and can contain * \0 characters in the middle, as the length is stored in the sds header. */ sds sdsnewlen(const void *init, size_t initlen) { struct sdshdr *sh; printf("***sdsnewlen init=%s len=%d***\n",init,initlen); printf("sizeof(struct sdshdr)+initlen+1=%d***\n",sizeof(struct sdshdr)+initlen+1); if (init) { sh = zmalloc(sizeof(struct sdshdr)+initlen+1); } else { sh = zcalloc(sizeof(struct sdshdr)+initlen+1); } if (sh == NULL) return NULL; sh->len = initlen; sh->free = 0; if (initlen && init) memcpy(sh->buf, init, initlen); sh->buf[initlen] = '\0'; return (char*)sh->buf; } /* Create a new sds string starting from a null termined C string. */ sds sdsnew(const char *init) { size_t initlen = (init == NULL) ? 0 : strlen(init); return sdsnewlen(init, initlen); } int main() { struct sdshdr *sh; sds x = sdsnew("foo"), y; test_cond("Create a string and obtain the length", sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0); } /*
gcc sds.c zmalloc.c
[root@rac1 Sds]# ./a.out 123 ***sdsnewlen init=foo len=3*** sizeof(struct sdshdr)+initlen+1=12*** 1 - Create a string and obtain the length: sizeof(struct sdshdr)=8 sh->buf=foo sh->len=3 PASSED */