/* 切割字符串,*count存储的切割后的子串数目 */ /* 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; /* slots的初始值为5,此时是假设s最多被分为5个子串,不够时可以扩展 */ sds *tokens = zmalloc(sizeof(sds)*slots); #ifdef SDS_ABORT_ON_OOM if (tokens == NULL) sdsOomAbort(); /* 分配内存失败 */ #endif if (seplen < 1 || len < 0 || tokens == NULL) returnNULL; 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) { /* slots的值不足 */ sds *newtokens;
slots *= 2; /* 增大slots */ 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; #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); returnNULL; } #endif }