//内存出错函数**封装的一个报错函数staticvoidsdsOomAbort(void){//发生内存错误时向标准输出设备输出出错信息fprintf(stderr,"SDS: Out Of Memory (SDS_ABORT_ON_OOM defined)\n");abort();//出错时直接终止程序}
/* Split 's' with separator in 'sep'. An array
* of sds strings is returned. *count will be set
* by reference to the number of tokens returned.
*
* On out of memory, zero length string, zero length
* separator, NULL is returned.
*
* Note that 'sep' is able to split a string using
* a multi-character separator. For example
* sdssplit("foo_-_bar","_-_"); will return two
* elements "foo" and "bar".
*
* This version of the function is binary-safe but
* requires length arguments. sdssplit() is just the
* same function but for zero-terminated strings.
*/
sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {
int elements = 0, slots = 5, start = 0, j;
//开设5字节的内存空间
//实际开设时会开设6字节,具体可以参看zmallo.c里的源代码
sds *tokens = zmalloc(sizeof(sds)*slots);
#ifdef SDS_ABORT_ON_OOM
if (tokens == NULL) sdsOomAbort();
#endif
if (seplen < 1 || len < 0 || tokens == NULL) return NULL;
for (j = 0; j < (len-(seplen-1)); j++) {
/* make sure there is room for the next element and the final one */
if (slots < elements+2) {
sds *newtokens;
slots *= 2;
newtokens = zrealloc(tokens,sizeof(sds)*slots);
if (newtokens == NULL) {
#ifdef SDS_ABORT_ON_OOM
sdsOomAbort();
#else
goto cleanup;
#endif
}
tokens = newtokens;
}
/* search the separator */
if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
//计算分割符以前的字符串的长度
tokens[elements] = sdsnewlen(s+start,j-start);
if (tokens[elements] == NULL) {
#ifdef SDS_ABORT_ON_OOM
sdsOomAbort();//失败的情况下,如果定义了内存失败函数,将直接调用
#else
goto cleanup;//否则跳到cleanup函数,进行一个一个的释放
#endif
}
elements++;
start = j+seplen;
j = j+seplen-1; /* skip the separator */
}
}
/* Add the final element. We are sure there is room in the tokens array. */
//分割串里面的最后一个字符串
tokens[elements] = sdsnewlen(s+start,len-start);
if (tokens[elements] == NULL) {
#ifdef SDS_ABORT_ON_OOM
sdsOomAbort();
#else
goto cleanup;
#endif
}
elements++;
//传的是个引用,可以获取最终分割为多少个数组
*count = elements;
return tokens;
#ifndef SDS_ABORT_ON_OOM
//如果没有定义分配失败的情况下,内存操作函数
//将会一个一个的调用内存失败处理函数
cleanup:
{
int i;
for (i = 0; i < elements; i++) sdsfree(tokens[i]);
zfree(tokens);
return NULL;
}
#endif
}