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
| 101 | * end of the string. However the string is binary safe and can contain |
| 102 | * \0 characters in the middle, as the length is stored in the sds header. */ |
| 103 | sds _sdsnewlen(const void *init, size_t initlen, int trymalloc) { |
| 104 | void *sh; |
| 105 | sds s; |
| 106 | char type = sdsReqType(initlen); |
| 107 | /* Empty strings are usually created in order to append. Use type 8 |
| 108 | * since type 5 is not good at this. */ |
| 109 | if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8; |
| 110 | int hdrlen = sdsHdrSize(type); |
| 111 | unsigned char *fp; /* flags pointer. */ |
| 112 | size_t usable; |
| 113 | |
| 114 | assert(initlen + hdrlen + 1 > initlen); /* Catch size_t overflow */ |
| 115 | sh = trymalloc? |
| 116 | s_trymalloc_usable(hdrlen+initlen+1, &usable) : |
| 117 | s_malloc_usable(hdrlen+initlen+1, &usable); |
| 118 | if (sh == NULL) return NULL; |
| 119 | if (init==SDS_NOINIT) |
| 120 | init = NULL; |
| 121 | else if (!init) |
| 122 | memset(sh, 0, hdrlen+initlen+1); |
| 123 | s = (char*)sh+hdrlen; |
| 124 | fp = ((unsigned char*)s)-1; |
| 125 | usable = usable-hdrlen-1; |
| 126 | if (usable > sdsTypeMaxSize(type)) |
| 127 | usable = sdsTypeMaxSize(type); |
| 128 | switch(type) { |
| 129 | case SDS_TYPE_5: { |
| 130 | *fp = type | (initlen << SDS_TYPE_BITS); |
| 131 | break; |
| 132 | } |
| 133 | case SDS_TYPE_8: { |
| 134 | SDS_HDR_VAR(8,s); |
| 135 | sh->len = initlen; |
| 136 | sh->alloc = usable; |
| 137 | *fp = type; |
| 138 | break; |
| 139 | } |
| 140 | case SDS_TYPE_16: { |
| 141 | SDS_HDR_VAR(16,s); |
| 142 | sh->len = initlen; |
| 143 | sh->alloc = usable; |
| 144 | *fp = type; |
| 145 | break; |
| 146 | } |
| 147 | case SDS_TYPE_32: { |
| 148 | SDS_HDR_VAR(32,s); |
| 149 | sh->len = initlen; |
| 150 | sh->alloc = usable; |
| 151 | *fp = type; |
| 152 | break; |
| 153 | } |
| 154 | case SDS_TYPE_64: { |
| 155 | SDS_HDR_VAR(64,s); |
| 156 | sh->len = initlen; |
| 157 | sh->alloc = usable; |
| 158 | *fp = type; |
| 159 | break; |
| 160 | } |
no test coverage detected