X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/efc296a1d6068f4e0cde584415d4c14a963c175c..49128f0b9da725de992e427fa341a837bcc2991b:/doc/HackingStrings.html diff --git a/doc/HackingStrings.html b/doc/HackingStrings.html new file mode 100644 index 00000000..68ebb7a5 --- /dev/null +++ b/doc/HackingStrings.html @@ -0,0 +1,83 @@ + + + +
+ + + ++struct sdshdr { + long len; + long free; + char buf[]; +}; +The buf character array stores the actual string.
sds
is defined in sds.h to be a synonymn for a character pointer:+typedef char *sds; +
sdsnewlen
function defined in sds.c creates a new Redis String: +sds sdsnewlen(const void *init, size_t initlen) { + struct sdshdr *sh; + + 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); + else memset(sh->buf,0,initlen); + } + sh->buf[initlen] = '\0'; + return (char*)sh->buf; +} +Remember a Redis string is a variable of type
struct sdshdr
. But sdsnewlen
returns a character pointer!!sdsnewlen
like below:+sdsnewlen("redis", 5); +This creates a new variable of type
struct sdshdr
allocating memory for len and free
+fields as well as for the buf character array.+sh = zmalloc(sizeof(struct sdshdr)+initlen+1); // initlen is length of init argument. +After
sdsnewlen
succesfully creates a Redis string the result is something like:+----------- +|5|0|redis| +----------- +^ ^ +sh sh->buf +
sdsnewlen
returns sh->buf to the caller.sh
?sh
but you only have the pointer sh->buf
.sh
from sh->buf
?sh->buf
you get the pointer sh
. struct sdshdr
.sdslen
function and see this trick at work:+size_t sdslen(const sds s) { + struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr))); + return sh->len; +} +Knowing this trick you could easily go through the rest of the functions in sds.c.