in src/string_token.c [297:393]
int StringToken_Split(const char* source, size_t length, const char** delimiters, size_t n_delims, bool include_empty, char*** tokens, size_t* token_count)
{
int result;
// Codes_SRS_STRING_TOKENIZER_09_022: [ If source, delimiters, token or token_count are NULL, or n_delims is zero the function shall return a non-zero value ]
if (source == NULL || delimiters == NULL || n_delims == 0 || tokens == NULL || token_count == NULL)
{
LogError("Invalid argument (source=%p, delimiters=%p, n_delims=%lu, tokens=%p, token_count=%p)", source, delimiters, (unsigned long)n_delims, tokens, token_count);
result = MU_FAILURE;
}
else
{
STRING_TOKEN_HANDLE tokenizer;
// Codes_SRS_STRING_TOKENIZER_09_023: [ source (up to length) shall be split into individual tokens separated by any of delimiters ]
tokenizer = StringToken_GetFirst(source, length, delimiters, n_delims);
*token_count = 0;
*tokens = NULL;
// Codes_SRS_STRING_TOKENIZER_09_027: [ If no failures occur the function shall return zero ]
result = 0;
if (tokenizer != NULL)
{
do
{
const char* tokenValue;
size_t tokenLength;
tokenValue = StringToken_GetValue(tokenizer);
tokenLength = StringToken_GetLength(tokenizer);
if ((tokenValue != NULL && tokenLength == 0) || (tokenValue == NULL && tokenLength > 0))
{
LogError("Unexpected token value (%p) or length (%lu)", tokenValue, (unsigned long)tokenLength);
result = MU_FAILURE;
break;
}
// Codes_SRS_STRING_TOKENIZER_09_024: [ All NULL tokens shall be ommited if include_empty is not TRUE ]
else if (tokenValue != NULL || include_empty)
{
char** temp_token;
// Codes_SRS_STRING_TOKENIZER_09_025: [ The tokens shall be stored in tokens, and their count stored in token_count ]
*token_count = (*token_count) + 1;
size_t realloc_size = safe_multiply_size_t(sizeof(char*), (*token_count));
if (realloc_size == SIZE_MAX ||
(temp_token = (char**)realloc(*tokens, realloc_size)) == NULL)
{
// Codes_SRS_STRING_TOKENIZER_09_026: [ If any failures splitting or storing the tokens occur the function shall return a non-zero value ]
LogError("Failed re-allocating the token array, size=%zu", realloc_size);
(*token_count)--;
result = MU_FAILURE;
break;
}
else
{
*tokens = temp_token;
size_t malloc_size;
if (tokenLength == 0)
{
(*tokens)[(*token_count) - 1] = NULL;
}
else if ((malloc_size = safe_multiply_size_t(safe_add_size_t(tokenLength, 1), sizeof(char))) == SIZE_MAX ||
((*tokens)[(*token_count) - 1] = (char*)malloc(malloc_size)) == NULL)
{
// Codes_SRS_STRING_TOKENIZER_09_026: [ If any failures splitting or storing the tokens occur the function shall return a non-zero value ]
LogError("Failed copying token into array, size=%zu", malloc_size);
*token_count = (*token_count) - 1;
result = MU_FAILURE;
break;
}
else
{
(void)memcpy((*tokens)[(*token_count) - 1], tokenValue, tokenLength);
(*tokens)[(*token_count) - 1][tokenLength] = '\0';
}
}
}
} while (StringToken_GetNext(tokenizer, delimiters, n_delims));
StringToken_Destroy(tokenizer);
if (result != 0)
{
while ((*token_count) > 0 && *tokens != NULL)
{
*token_count = (*token_count) - 1;
free((*tokens)[*token_count]);
}
free(*tokens);
}
}
}
return result;
}