这里这要是映射,其实可以通过数组来实现:
- static inline char sdsReqType(size_t string_size) {
- if (string_size < 1<<5)
- return SDS_TYPE_5;
- if (string_size < 1<<8)
- return SDS_TYPE_8;
- if (string_size < 1<<16)
- return SDS_TYPE_16;
- #if (LONG_MAX == LLONG_MAX)
- if (string_size < 1ll<<32)
- return SDS_TYPE_32;
- return SDS_TYPE_64;
- #else
- return SDS_TYPE_32;
- #endif
- }
-
- static inline size_t sdsTypeMaxSize(char type) {
- if (type == SDS_TYPE_5)
- return (1<<5) - 1;
- if (type == SDS_TYPE_8)
- return (1<<8) - 1;
- if (type == SDS_TYPE_16)
- return (1<<16) - 1;
- #if (LONG_MAX == LLONG_MAX)
- if (type == SDS_TYPE_32)
- return (1ll<<32) - 1;
- #endif
- return -1; /* this is equivalent to the max SDS_TYPE_64 or SDS_TYPE_32 */
- }
-
- /* 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.
- * If SDS_NOINIT is used, the buffer is left uninitialized;
- *
- * 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, int trymalloc) {
- void *sh;
- sds s;
- char type = sdsReqType(initlen);
- /* Empty strings are usually created in order to append. Use type 8
- * since type 5 is not good at this. */
- if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8;
- int hdrlen = sdsHdrSize(type);
- unsigned char *fp; /* flags pointer. */
- size_t usable;
-
- assert(initlen + hdrlen + 1 > initlen); /* Catch size_t overflow */
- sh = trymalloc?
- s_trymalloc_usable(hdrlen+initlen+1, &usable) :
- s_malloc_usable(hdrlen+initlen+1, &usable);
- if (sh == NULL) return NULL;
- if (init==SDS_NOINIT)
- init = NULL;
- else if (!init)
- memset(sh, 0, hdrlen+initlen+1);
- s = (char*)sh+hdrlen;
- fp = ((unsigned char*)s)-1;
- usable = usable-hdrlen-1;
- if (usable > sdsTypeMaxSize(type))
- usable = sdsTypeMaxSize(type);
- switch(type) {
- case SDS_TYPE_5: {
- *fp = type | (initlen << SDS_TYPE_BITS);
- break;
- }
- case SDS_TYPE_8: {
- SDS_HDR_VAR(8,s);
- sh->len = initlen;
- sh->alloc = usable;
- *fp = type;
- break;
- }
- case SDS_TYPE_16: {
- SDS_HDR_VAR(16,s);
- sh->len = initlen;
- sh->alloc = usable;
- *fp = type;
- break;
- }
- case SDS_TYPE_32: {
- SDS_HDR_VAR(32,s);
- sh->len = initlen;
- sh->alloc = usable;
- *fp = type;
- break;
- }
- case SDS_TYPE_64: {
- SDS_HDR_VAR(64,s);
- sh->len = initlen;
- sh->alloc = usable;
- *fp = type;
- break;
- }
- }
- if (initlen && init)
- memcpy(s, init, initlen);
- s[initlen] = '\0';
- return s;
- }
-
- sds sdsnewlen(const void *init, size_t initlen) {
- return _sdsnewlen(init, initlen, 0);
- }
-
- sds sdstrynewlen(const void *init, size_t initlen) {
- return _sdsnewlen(init, initlen, 1);
- }
-
- /* Create an empty (zero length) sds string. Even in this case the string
- * always has an implicit null term. */
- sds sdsempty(void) {
- return sdsnewlen("",0);
- }
-
- /* Create a new sds string starting from a null terminated C string. */
- sds sdsnew(const char *init) {
- size_t initlen = (init == NULL) ? 0 : strlen(init);
- return sdsnewlen(init, initlen);
- }
-
- /* Duplicate an sds string. */
- sds sdsdup(const sds s) {
- return sdsnewlen(s, sdslen(s));
- }
-
- /* Free an sds string. No operation is performed if 's' is NULL. */
- void sdsfree(sds s) {
- if (s == NULL) return;
- s_free((char*)s-sdsHdrSize(s[-1]));
- }