Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of azure_c_shared_utility by
string_tokenizer.c@6:c55b013dfc2a, 2016-07-01 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Jul 01 10:43:23 2016 -0700
- Revision:
- 6:c55b013dfc2a
- Parent:
- 1:9190c0f4d23a
- Child:
- 7:1af47e3a19b6
1.0.10
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Azure.IoT Build | 0:fa2de1b79154 | 1 | // Copyright (c) Microsoft. All rights reserved. |
| Azure.IoT Build | 0:fa2de1b79154 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
| Azure.IoT Build | 0:fa2de1b79154 | 3 | |
| Azure.IoT Build | 0:fa2de1b79154 | 4 | // |
| Azure.IoT Build | 0:fa2de1b79154 | 5 | // PUT NO INCLUDES BEFORE HERE |
| Azure.IoT Build | 0:fa2de1b79154 | 6 | // |
| Azure.IoT Build | 0:fa2de1b79154 | 7 | #ifdef _CRTDBG_MAP_ALLOC |
| Azure.IoT Build | 0:fa2de1b79154 | 8 | #include <crtdbg.h> |
| Azure.IoT Build | 0:fa2de1b79154 | 9 | #endif |
| Azure.IoT Build | 0:fa2de1b79154 | 10 | #include "azure_c_shared_utility/gballoc.h" |
| Azure.IoT Build | 0:fa2de1b79154 | 11 | |
| Azure.IoT Build | 0:fa2de1b79154 | 12 | // |
| Azure.IoT Build | 0:fa2de1b79154 | 13 | // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE |
| Azure.IoT Build | 0:fa2de1b79154 | 14 | // |
| Azure.IoT Build | 0:fa2de1b79154 | 15 | |
| Azure.IoT Build | 0:fa2de1b79154 | 16 | #include <stdbool.h> |
| Azure.IoT Build | 0:fa2de1b79154 | 17 | #include "azure_c_shared_utility/string_tokenizer.h" |
| Azure.IoT Build | 6:c55b013dfc2a | 18 | #include "azure_c_shared_utility/xlogging.h" |
| Azure.IoT Build | 0:fa2de1b79154 | 19 | #include "azure_c_shared_utility/crt_abstractions.h" |
| Azure.IoT Build | 0:fa2de1b79154 | 20 | |
| Azure.IoT Build | 0:fa2de1b79154 | 21 | typedef struct STRING_TOKEN_TAG |
| Azure.IoT Build | 0:fa2de1b79154 | 22 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 23 | const char* inputString; |
| Azure.IoT Build | 0:fa2de1b79154 | 24 | const char* currentPos; |
| Azure.IoT Build | 0:fa2de1b79154 | 25 | size_t sizeOfinputString; |
| Azure.IoT Build | 0:fa2de1b79154 | 26 | } STRING_TOKEN; |
| Azure.IoT Build | 0:fa2de1b79154 | 27 | |
| Azure.IoT Build | 0:fa2de1b79154 | 28 | STRING_TOKENIZER_HANDLE STRING_TOKENIZER_create(STRING_HANDLE handle) |
| Azure.IoT Build | 0:fa2de1b79154 | 29 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 30 | STRING_TOKENIZER_HANDLE result; |
| Azure.IoT Build | 0:fa2de1b79154 | 31 | |
| Azure.IoT Build | 0:fa2de1b79154 | 32 | /* Codes_SRS_STRING_04_001: [STRING_TOKENIZER_create shall return an NULL STRING_TOKENIZER_HANDLE if parameter handle is NULL] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 33 | if (handle == NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 34 | { |
| AzureIoTClient | 1:9190c0f4d23a | 35 | LogError("Invalid Argument. Handle cannot be NULL."); |
| Azure.IoT Build | 0:fa2de1b79154 | 36 | result = NULL; |
| Azure.IoT Build | 0:fa2de1b79154 | 37 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 38 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 39 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 40 | /* Codes_SRS_STRING_04_002: [STRING_TOKENIZER_create shall allocate a new STRING_TOKENIZER_HANDLE having the content of the STRING_HANDLE copied and current position pointing at the beginning of the string] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 41 | result = STRING_TOKENIZER_create_from_char(STRING_c_str(handle)); |
| Azure.IoT Build | 0:fa2de1b79154 | 42 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 43 | |
| Azure.IoT Build | 0:fa2de1b79154 | 44 | return result; |
| Azure.IoT Build | 0:fa2de1b79154 | 45 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 46 | |
| Azure.IoT Build | 0:fa2de1b79154 | 47 | extern STRING_TOKENIZER_HANDLE STRING_TOKENIZER_create_from_char(const char* input) |
| Azure.IoT Build | 0:fa2de1b79154 | 48 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 49 | STRING_TOKEN *result; |
| Azure.IoT Build | 0:fa2de1b79154 | 50 | char* inputStringToMalloc; |
| Azure.IoT Build | 0:fa2de1b79154 | 51 | |
| Azure.IoT Build | 0:fa2de1b79154 | 52 | /* Codes_SRS_STRING_07_001: [STRING_TOKENIZER_create shall return an NULL STRING_TOKENIZER_HANDLE if parameter input is NULL] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 53 | if (input == NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 54 | { |
| AzureIoTClient | 1:9190c0f4d23a | 55 | LogError("Invalid Argument. Handle cannot be NULL."); |
| Azure.IoT Build | 0:fa2de1b79154 | 56 | result = NULL; |
| Azure.IoT Build | 0:fa2de1b79154 | 57 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 58 | /* Codes_SRS_STRING_07_002: [STRING_TOKENIZER_create shall allocate a new STRING_TOKENIZER_HANDLE having the content of the STRING_HANDLE copied and current position pointing at the beginning of the string] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 59 | else if ((result = (STRING_TOKEN*)malloc(sizeof(STRING_TOKEN))) == NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 60 | { |
| AzureIoTClient | 1:9190c0f4d23a | 61 | LogError("Memory Allocation failed. Cannot allocate STRING_TOKENIZER."); |
| Azure.IoT Build | 0:fa2de1b79154 | 62 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 63 | else if ((mallocAndStrcpy_s(&inputStringToMalloc, input)) != 0) |
| Azure.IoT Build | 0:fa2de1b79154 | 64 | { |
| AzureIoTClient | 1:9190c0f4d23a | 65 | LogError("Memory Allocation Failed. Cannot allocate and copy string Content."); |
| Azure.IoT Build | 0:fa2de1b79154 | 66 | free(result); |
| Azure.IoT Build | 0:fa2de1b79154 | 67 | result = NULL; |
| Azure.IoT Build | 0:fa2de1b79154 | 68 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 69 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 70 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 71 | result->inputString = inputStringToMalloc; |
| Azure.IoT Build | 0:fa2de1b79154 | 72 | result->currentPos = result->inputString; //Current Pos will point to the initial position of Token. |
| Azure.IoT Build | 0:fa2de1b79154 | 73 | result->sizeOfinputString = strlen(result->inputString); //Calculate Size of Current String |
| Azure.IoT Build | 0:fa2de1b79154 | 74 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 75 | return (STRING_TOKENIZER_HANDLE)result; |
| Azure.IoT Build | 0:fa2de1b79154 | 76 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 77 | |
| Azure.IoT Build | 0:fa2de1b79154 | 78 | int STRING_TOKENIZER_get_next_token(STRING_TOKENIZER_HANDLE tokenizer, STRING_HANDLE output, const char* delimiters) |
| Azure.IoT Build | 0:fa2de1b79154 | 79 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 80 | int result; |
| Azure.IoT Build | 0:fa2de1b79154 | 81 | /* Codes_SRS_STRING_04_004: [STRING_TOKENIZER_get_next_token shall return a nonzero value if any of the 3 parameters is NULL] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 82 | if (tokenizer == NULL || output == NULL || delimiters == NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 83 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 84 | result = __LINE__; |
| Azure.IoT Build | 0:fa2de1b79154 | 85 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 86 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 87 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 88 | STRING_TOKEN* token = (STRING_TOKEN*)tokenizer; |
| Azure.IoT Build | 0:fa2de1b79154 | 89 | /* Codes_SRS_STRING_04_011: [Each subsequent call to STRING_TOKENIZER_get_next_token starts searching from the saved position on t and behaves as described above.] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 90 | size_t remainingInputStringSize = token->sizeOfinputString - (token->currentPos - token->inputString); |
| Azure.IoT Build | 0:fa2de1b79154 | 91 | size_t delimitterSize = strlen(delimiters); |
| Azure.IoT Build | 0:fa2de1b79154 | 92 | |
| Azure.IoT Build | 0:fa2de1b79154 | 93 | /* First Check if we reached the end of the string*/ |
| Azure.IoT Build | 0:fa2de1b79154 | 94 | /* Codes_SRS_STRING_TOKENIZER_04_014: [STRING_TOKENIZER_get_next_token shall return nonzero value if t contains an empty string.] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 95 | if (remainingInputStringSize == 0) |
| Azure.IoT Build | 0:fa2de1b79154 | 96 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 97 | result = __LINE__; |
| Azure.IoT Build | 0:fa2de1b79154 | 98 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 99 | else if (delimitterSize == 0) |
| Azure.IoT Build | 0:fa2de1b79154 | 100 | { |
| AzureIoTClient | 1:9190c0f4d23a | 101 | LogError("Empty delimiters parameter."); |
| Azure.IoT Build | 0:fa2de1b79154 | 102 | result = __LINE__; |
| Azure.IoT Build | 0:fa2de1b79154 | 103 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 104 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 105 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 106 | size_t i; |
| Azure.IoT Build | 0:fa2de1b79154 | 107 | size_t j; |
| Azure.IoT Build | 0:fa2de1b79154 | 108 | /* Codes_SRS_STRING_04_005: [STRING_TOKENIZER_get_next_token searches the string inside STRING_TOKENIZER_HANDLE for the first character that is NOT contained in the current delimiter] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 109 | for (i = 0; i < remainingInputStringSize; i++) |
| Azure.IoT Build | 0:fa2de1b79154 | 110 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 111 | bool foundDelimitter = false; |
| Azure.IoT Build | 0:fa2de1b79154 | 112 | for (j = 0; j < delimitterSize; j++) |
| Azure.IoT Build | 0:fa2de1b79154 | 113 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 114 | if (token->currentPos[i] == delimiters[j]) |
| Azure.IoT Build | 0:fa2de1b79154 | 115 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 116 | foundDelimitter = true; |
| Azure.IoT Build | 0:fa2de1b79154 | 117 | break; |
| Azure.IoT Build | 0:fa2de1b79154 | 118 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 119 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 120 | |
| Azure.IoT Build | 0:fa2de1b79154 | 121 | /* Codes_SRS_STRING_04_007: [If such a character is found, STRING_TOKENIZER_get_next_token consider it as the start of a token.] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 122 | if (!foundDelimitter) |
| Azure.IoT Build | 0:fa2de1b79154 | 123 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 124 | break; |
| Azure.IoT Build | 0:fa2de1b79154 | 125 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 126 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 127 | |
| Azure.IoT Build | 0:fa2de1b79154 | 128 | /* Codes_SRS_STRING_04_006: [If no such character is found, then STRING_TOKENIZER_get_next_token shall return a nonzero Value (You've reach the end of the string or the string consists with only delimiters).] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 129 | //At this point update Current Pos to the character of the last token found or end of String. |
| Azure.IoT Build | 0:fa2de1b79154 | 130 | token->currentPos += i; |
| Azure.IoT Build | 0:fa2de1b79154 | 131 | |
| Azure.IoT Build | 0:fa2de1b79154 | 132 | //Update the remainingInputStringSize |
| Azure.IoT Build | 0:fa2de1b79154 | 133 | remainingInputStringSize -= i; |
| Azure.IoT Build | 0:fa2de1b79154 | 134 | |
| Azure.IoT Build | 0:fa2de1b79154 | 135 | /* Codes_SRS_STRING_04_006: [If no such character is found, then STRING_TOKENIZER_get_next_token shall return a nonzero Value (You've reach the end of the string or the string consists with only delimiters).] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 136 | if (remainingInputStringSize == 0) |
| Azure.IoT Build | 0:fa2de1b79154 | 137 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 138 | result = __LINE__; |
| Azure.IoT Build | 0:fa2de1b79154 | 139 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 140 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 141 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 142 | bool foundDelimitter = false; |
| Azure.IoT Build | 0:fa2de1b79154 | 143 | char* endOfTokenPosition=NULL; |
| Azure.IoT Build | 0:fa2de1b79154 | 144 | size_t amountOfCharactersToCopy; |
| Azure.IoT Build | 0:fa2de1b79154 | 145 | size_t j; |
| Azure.IoT Build | 0:fa2de1b79154 | 146 | //At this point the Current Pos is pointing to a character that is point to a nonDelimiter. So, now search for a Delimiter, till the end of the String. |
| Azure.IoT Build | 0:fa2de1b79154 | 147 | /*Codes_SRS_STRING_04_008: [STRING_TOKENIZER_get_next_token than searches from the start of a token for a character that is contained in the delimiters string.] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 148 | /* Codes_SRS_STRING_04_009: [If no such character is found, STRING_TOKENIZER_get_next_token extends the current token to the end of the string inside t, copies the token to output and returns 0.] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 149 | /* Codes_SRS_STRING_04_010: [If such a character is found, STRING_TOKENIZER_get_next_token consider it the end of the token and copy it's content to output, updates the current position inside t to the next character and returns 0.] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 150 | for (j = 0; j < delimitterSize; j++) |
| Azure.IoT Build | 0:fa2de1b79154 | 151 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 152 | if ((endOfTokenPosition = strchr(token->currentPos, delimiters[j])) != NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 153 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 154 | foundDelimitter = true; |
| Azure.IoT Build | 0:fa2de1b79154 | 155 | break; |
| Azure.IoT Build | 0:fa2de1b79154 | 156 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 157 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 158 | |
| Azure.IoT Build | 0:fa2de1b79154 | 159 | //If token not found, than update the EndOfToken to the end of the inputString; |
| Azure.IoT Build | 0:fa2de1b79154 | 160 | if (endOfTokenPosition == NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 161 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 162 | amountOfCharactersToCopy = remainingInputStringSize; |
| Azure.IoT Build | 0:fa2de1b79154 | 163 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 164 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 165 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 166 | amountOfCharactersToCopy = endOfTokenPosition - token->currentPos; |
| Azure.IoT Build | 0:fa2de1b79154 | 167 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 168 | |
| Azure.IoT Build | 0:fa2de1b79154 | 169 | //copy here the string to output. |
| Azure.IoT Build | 0:fa2de1b79154 | 170 | if (STRING_copy_n(output, token->currentPos, amountOfCharactersToCopy) != 0) |
| Azure.IoT Build | 0:fa2de1b79154 | 171 | { |
| AzureIoTClient | 1:9190c0f4d23a | 172 | LogError("Problem copying token to output String."); |
| Azure.IoT Build | 0:fa2de1b79154 | 173 | result = __LINE__; |
| Azure.IoT Build | 0:fa2de1b79154 | 174 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 175 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 176 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 177 | //Update the Current position. |
| Azure.IoT Build | 0:fa2de1b79154 | 178 | //Check if end of String reached so, currentPos points to the end of String. |
| Azure.IoT Build | 0:fa2de1b79154 | 179 | if (foundDelimitter) |
| Azure.IoT Build | 0:fa2de1b79154 | 180 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 181 | token->currentPos += amountOfCharactersToCopy + 1; |
| Azure.IoT Build | 0:fa2de1b79154 | 182 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 183 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 184 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 185 | token->currentPos += amountOfCharactersToCopy; |
| Azure.IoT Build | 0:fa2de1b79154 | 186 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 187 | |
| Azure.IoT Build | 0:fa2de1b79154 | 188 | result = 0; //Result will be on the output. |
| Azure.IoT Build | 0:fa2de1b79154 | 189 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 190 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 191 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 192 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 193 | |
| Azure.IoT Build | 0:fa2de1b79154 | 194 | return result; |
| Azure.IoT Build | 0:fa2de1b79154 | 195 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 196 | |
| Azure.IoT Build | 0:fa2de1b79154 | 197 | |
| Azure.IoT Build | 0:fa2de1b79154 | 198 | /* Codes_SRS_STRING_TOKENIZER_04_012: [STRING_TOKENIZER_destroy shall free the memory allocated by the STRING_TOKENIZER_create ] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 199 | void STRING_TOKENIZER_destroy(STRING_TOKENIZER_HANDLE t) |
| Azure.IoT Build | 0:fa2de1b79154 | 200 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 201 | /* Codes_SRS_STRING_TOKENIZER_04_013: [When the t argument is NULL, then STRING_TOKENIZER_destroy shall not attempt to free] */ |
| Azure.IoT Build | 0:fa2de1b79154 | 202 | if (t != NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 203 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 204 | STRING_TOKEN* value = (STRING_TOKEN*)t; |
| Azure.IoT Build | 0:fa2de1b79154 | 205 | free((char*)value->inputString); |
| Azure.IoT Build | 0:fa2de1b79154 | 206 | value->inputString = NULL; |
| Azure.IoT Build | 0:fa2de1b79154 | 207 | free(value); |
| Azure.IoT Build | 0:fa2de1b79154 | 208 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 209 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 210 |
