#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
*/