Demo using MBED TLS
Dependencies: EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed
Fork of iothub_client_sample_amqp by
azure_c_shared_utility/map.c@58:f50b97b08851, 2017-01-05 (annotated)
- Committer:
- markrad
- Date:
- Thu Jan 05 00:20:03 2017 +0000
- Revision:
- 58:f50b97b08851
Sample using MBED TLS
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
markrad | 58:f50b97b08851 | 1 | // Copyright (c) Microsoft. All rights reserved. |
markrad | 58:f50b97b08851 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
markrad | 58:f50b97b08851 | 3 | |
markrad | 58:f50b97b08851 | 4 | #include <stdlib.h> |
markrad | 58:f50b97b08851 | 5 | #ifdef _CRTDBG_MAP_ALLOC |
markrad | 58:f50b97b08851 | 6 | #include <crtdbg.h> |
markrad | 58:f50b97b08851 | 7 | #endif |
markrad | 58:f50b97b08851 | 8 | |
markrad | 58:f50b97b08851 | 9 | #include "azure_c_shared_utility/gballoc.h" |
markrad | 58:f50b97b08851 | 10 | #include "azure_c_shared_utility/map.h" |
markrad | 58:f50b97b08851 | 11 | #include "azure_c_shared_utility/xlogging.h" |
markrad | 58:f50b97b08851 | 12 | #include "azure_c_shared_utility/strings.h" |
markrad | 58:f50b97b08851 | 13 | |
markrad | 58:f50b97b08851 | 14 | DEFINE_ENUM_STRINGS(MAP_RESULT, MAP_RESULT_VALUES); |
markrad | 58:f50b97b08851 | 15 | |
markrad | 58:f50b97b08851 | 16 | typedef struct MAP_HANDLE_DATA_TAG |
markrad | 58:f50b97b08851 | 17 | { |
markrad | 58:f50b97b08851 | 18 | char** keys; |
markrad | 58:f50b97b08851 | 19 | char** values; |
markrad | 58:f50b97b08851 | 20 | size_t count; |
markrad | 58:f50b97b08851 | 21 | MAP_FILTER_CALLBACK mapFilterCallback; |
markrad | 58:f50b97b08851 | 22 | }MAP_HANDLE_DATA; |
markrad | 58:f50b97b08851 | 23 | |
markrad | 58:f50b97b08851 | 24 | #define LOG_MAP_ERROR LogError("result = %s", ENUM_TO_STRING(MAP_RESULT, result)); |
markrad | 58:f50b97b08851 | 25 | |
markrad | 58:f50b97b08851 | 26 | MAP_HANDLE Map_Create(MAP_FILTER_CALLBACK mapFilterFunc) |
markrad | 58:f50b97b08851 | 27 | { |
markrad | 58:f50b97b08851 | 28 | /*Codes_SRS_MAP_02_001: [Map_Create shall create a new, empty map.]*/ |
markrad | 58:f50b97b08851 | 29 | MAP_HANDLE_DATA* result = (MAP_HANDLE_DATA*)malloc(sizeof(MAP_HANDLE_DATA)); |
markrad | 58:f50b97b08851 | 30 | /*Codes_SRS_MAP_02_002: [If during creation there are any error, then Map_Create shall return NULL.]*/ |
markrad | 58:f50b97b08851 | 31 | if (result != NULL) |
markrad | 58:f50b97b08851 | 32 | { |
markrad | 58:f50b97b08851 | 33 | /*Codes_SRS_MAP_02_003: [Otherwise, it shall return a non-NULL handle that can be used in subsequent calls.] */ |
markrad | 58:f50b97b08851 | 34 | result->keys = NULL; |
markrad | 58:f50b97b08851 | 35 | result->values = NULL; |
markrad | 58:f50b97b08851 | 36 | result->count = 0; |
markrad | 58:f50b97b08851 | 37 | result->mapFilterCallback = mapFilterFunc; |
markrad | 58:f50b97b08851 | 38 | } |
markrad | 58:f50b97b08851 | 39 | return (MAP_HANDLE)result; |
markrad | 58:f50b97b08851 | 40 | } |
markrad | 58:f50b97b08851 | 41 | |
markrad | 58:f50b97b08851 | 42 | void Map_Destroy(MAP_HANDLE handle) |
markrad | 58:f50b97b08851 | 43 | { |
markrad | 58:f50b97b08851 | 44 | /*Codes_SRS_MAP_02_005: [If parameter handle is NULL then Map_Destroy shall take no action.] */ |
markrad | 58:f50b97b08851 | 45 | if (handle != NULL) |
markrad | 58:f50b97b08851 | 46 | { |
markrad | 58:f50b97b08851 | 47 | /*Codes_SRS_MAP_02_004: [Map_Destroy shall release all resources associated with the map.] */ |
markrad | 58:f50b97b08851 | 48 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle; |
markrad | 58:f50b97b08851 | 49 | size_t i; |
markrad | 58:f50b97b08851 | 50 | |
markrad | 58:f50b97b08851 | 51 | for (i = 0; i < handleData->count; i++) |
markrad | 58:f50b97b08851 | 52 | { |
markrad | 58:f50b97b08851 | 53 | free(handleData->keys[i]); |
markrad | 58:f50b97b08851 | 54 | free(handleData->values[i]); |
markrad | 58:f50b97b08851 | 55 | } |
markrad | 58:f50b97b08851 | 56 | free(handleData->keys); |
markrad | 58:f50b97b08851 | 57 | free(handleData->values); |
markrad | 58:f50b97b08851 | 58 | free(handleData); |
markrad | 58:f50b97b08851 | 59 | } |
markrad | 58:f50b97b08851 | 60 | } |
markrad | 58:f50b97b08851 | 61 | |
markrad | 58:f50b97b08851 | 62 | /*makes a copy of a vector of const char*, having size "size". source cannot be NULL*/ |
markrad | 58:f50b97b08851 | 63 | /*returns NULL if it fails*/ |
markrad | 58:f50b97b08851 | 64 | static char** Map_CloneVector(const char*const * source, size_t count) |
markrad | 58:f50b97b08851 | 65 | { |
markrad | 58:f50b97b08851 | 66 | char** result; |
markrad | 58:f50b97b08851 | 67 | result = (char**)malloc(count *sizeof(char*)); |
markrad | 58:f50b97b08851 | 68 | if (result == NULL) |
markrad | 58:f50b97b08851 | 69 | { |
markrad | 58:f50b97b08851 | 70 | /*do nothing, just return it (NULL)*/ |
markrad | 58:f50b97b08851 | 71 | } |
markrad | 58:f50b97b08851 | 72 | else |
markrad | 58:f50b97b08851 | 73 | { |
markrad | 58:f50b97b08851 | 74 | size_t i; |
markrad | 58:f50b97b08851 | 75 | for (i = 0; i < count; i++) |
markrad | 58:f50b97b08851 | 76 | { |
markrad | 58:f50b97b08851 | 77 | if (mallocAndStrcpy_s(result + i, source[i]) != 0) |
markrad | 58:f50b97b08851 | 78 | { |
markrad | 58:f50b97b08851 | 79 | break; |
markrad | 58:f50b97b08851 | 80 | } |
markrad | 58:f50b97b08851 | 81 | } |
markrad | 58:f50b97b08851 | 82 | |
markrad | 58:f50b97b08851 | 83 | if (i == count) |
markrad | 58:f50b97b08851 | 84 | { |
markrad | 58:f50b97b08851 | 85 | /*it is all good, proceed to return result*/ |
markrad | 58:f50b97b08851 | 86 | } |
markrad | 58:f50b97b08851 | 87 | else |
markrad | 58:f50b97b08851 | 88 | { |
markrad | 58:f50b97b08851 | 89 | size_t j; |
markrad | 58:f50b97b08851 | 90 | for (j = 0; j < i; j++) |
markrad | 58:f50b97b08851 | 91 | { |
markrad | 58:f50b97b08851 | 92 | free(result[j]); |
markrad | 58:f50b97b08851 | 93 | } |
markrad | 58:f50b97b08851 | 94 | free(result); |
markrad | 58:f50b97b08851 | 95 | result = NULL; |
markrad | 58:f50b97b08851 | 96 | } |
markrad | 58:f50b97b08851 | 97 | } |
markrad | 58:f50b97b08851 | 98 | return result; |
markrad | 58:f50b97b08851 | 99 | } |
markrad | 58:f50b97b08851 | 100 | |
markrad | 58:f50b97b08851 | 101 | /*Codes_SRS_MAP_02_039: [Map_Clone shall make a copy of the map indicated by parameter handle and return a non-NULL handle to it.]*/ |
markrad | 58:f50b97b08851 | 102 | MAP_HANDLE Map_Clone(MAP_HANDLE handle) |
markrad | 58:f50b97b08851 | 103 | { |
markrad | 58:f50b97b08851 | 104 | MAP_HANDLE_DATA* result; |
markrad | 58:f50b97b08851 | 105 | if (handle == NULL) |
markrad | 58:f50b97b08851 | 106 | { |
markrad | 58:f50b97b08851 | 107 | /*Codes_SRS_MAP_02_038: [Map_Clone returns NULL if parameter handle is NULL.]*/ |
markrad | 58:f50b97b08851 | 108 | result = NULL; |
markrad | 58:f50b97b08851 | 109 | LogError("invalid arg to Map_Clone (NULL)"); |
markrad | 58:f50b97b08851 | 110 | } |
markrad | 58:f50b97b08851 | 111 | else |
markrad | 58:f50b97b08851 | 112 | { |
markrad | 58:f50b97b08851 | 113 | MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle; |
markrad | 58:f50b97b08851 | 114 | result = (MAP_HANDLE_DATA*)malloc(sizeof(MAP_HANDLE_DATA)); |
markrad | 58:f50b97b08851 | 115 | if (result == NULL) |
markrad | 58:f50b97b08851 | 116 | { |
markrad | 58:f50b97b08851 | 117 | /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */ |
markrad | 58:f50b97b08851 | 118 | /*do nothing, proceed to return it, this is an error case*/ |
markrad | 58:f50b97b08851 | 119 | LogError("unable to malloc"); |
markrad | 58:f50b97b08851 | 120 | } |
markrad | 58:f50b97b08851 | 121 | else |
markrad | 58:f50b97b08851 | 122 | { |
markrad | 58:f50b97b08851 | 123 | if (handleData->count == 0) |
markrad | 58:f50b97b08851 | 124 | { |
markrad | 58:f50b97b08851 | 125 | result->count = 0; |
markrad | 58:f50b97b08851 | 126 | result->keys = NULL; |
markrad | 58:f50b97b08851 | 127 | result->values = NULL; |
markrad | 58:f50b97b08851 | 128 | result->mapFilterCallback = NULL; |
markrad | 58:f50b97b08851 | 129 | } |
markrad | 58:f50b97b08851 | 130 | else |
markrad | 58:f50b97b08851 | 131 | { |
markrad | 58:f50b97b08851 | 132 | result->mapFilterCallback = handleData->mapFilterCallback; |
markrad | 58:f50b97b08851 | 133 | result->count = handleData->count; |
markrad | 58:f50b97b08851 | 134 | if( (result->keys = Map_CloneVector((const char* const*)handleData->keys, handleData->count))==NULL) |
markrad | 58:f50b97b08851 | 135 | { |
markrad | 58:f50b97b08851 | 136 | /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */ |
markrad | 58:f50b97b08851 | 137 | LogError("unable to clone keys"); |
markrad | 58:f50b97b08851 | 138 | free(result); |
markrad | 58:f50b97b08851 | 139 | result = NULL; |
markrad | 58:f50b97b08851 | 140 | } |
markrad | 58:f50b97b08851 | 141 | else if ((result->values = Map_CloneVector((const char* const*)handleData->values, handleData->count)) == NULL) |
markrad | 58:f50b97b08851 | 142 | { |
markrad | 58:f50b97b08851 | 143 | /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */ |
markrad | 58:f50b97b08851 | 144 | LogError("unable to clone values"); |
markrad | 58:f50b97b08851 | 145 | size_t i; |
markrad | 58:f50b97b08851 | 146 | for (i = 0; i < result->count; i++) |
markrad | 58:f50b97b08851 | 147 | { |
markrad | 58:f50b97b08851 | 148 | free(result->keys[i]); |
markrad | 58:f50b97b08851 | 149 | } |
markrad | 58:f50b97b08851 | 150 | free(result->keys); |
markrad | 58:f50b97b08851 | 151 | free(result); |
markrad | 58:f50b97b08851 | 152 | result = NULL; |
markrad | 58:f50b97b08851 | 153 | } |
markrad | 58:f50b97b08851 | 154 | else |
markrad | 58:f50b97b08851 | 155 | { |
markrad | 58:f50b97b08851 | 156 | /*all fine, return it*/ |
markrad | 58:f50b97b08851 | 157 | } |
markrad | 58:f50b97b08851 | 158 | } |
markrad | 58:f50b97b08851 | 159 | } |
markrad | 58:f50b97b08851 | 160 | } |
markrad | 58:f50b97b08851 | 161 | return (MAP_HANDLE)result; |
markrad | 58:f50b97b08851 | 162 | } |
markrad | 58:f50b97b08851 | 163 | |
markrad | 58:f50b97b08851 | 164 | static int Map_IncreaseStorageKeysValues(MAP_HANDLE_DATA* handleData) |
markrad | 58:f50b97b08851 | 165 | { |
markrad | 58:f50b97b08851 | 166 | int result; |
markrad | 58:f50b97b08851 | 167 | char** newKeys = (char**)realloc(handleData->keys, (handleData->count + 1) * sizeof(char*)); |
markrad | 58:f50b97b08851 | 168 | if (newKeys == NULL) |
markrad | 58:f50b97b08851 | 169 | { |
markrad | 58:f50b97b08851 | 170 | LogError("realloc error"); |
markrad | 58:f50b97b08851 | 171 | result = __LINE__; |
markrad | 58:f50b97b08851 | 172 | } |
markrad | 58:f50b97b08851 | 173 | else |
markrad | 58:f50b97b08851 | 174 | { |
markrad | 58:f50b97b08851 | 175 | char** newValues; |
markrad | 58:f50b97b08851 | 176 | handleData->keys = newKeys; |
markrad | 58:f50b97b08851 | 177 | handleData->keys[handleData->count] = NULL; |
markrad | 58:f50b97b08851 | 178 | newValues = (char**)realloc(handleData->values, (handleData->count + 1) * sizeof(char*)); |
markrad | 58:f50b97b08851 | 179 | if (newValues == NULL) |
markrad | 58:f50b97b08851 | 180 | { |
markrad | 58:f50b97b08851 | 181 | LogError("realloc error"); |
markrad | 58:f50b97b08851 | 182 | if (handleData->count == 0) /*avoiding an implementation defined behavior */ |
markrad | 58:f50b97b08851 | 183 | { |
markrad | 58:f50b97b08851 | 184 | free(handleData->keys); |
markrad | 58:f50b97b08851 | 185 | handleData->keys = NULL; |
markrad | 58:f50b97b08851 | 186 | } |
markrad | 58:f50b97b08851 | 187 | else |
markrad | 58:f50b97b08851 | 188 | { |
markrad | 58:f50b97b08851 | 189 | char** undoneKeys = (char**)realloc(handleData->keys, (handleData->count) * sizeof(char*)); |
markrad | 58:f50b97b08851 | 190 | if (undoneKeys == NULL) |
markrad | 58:f50b97b08851 | 191 | { |
markrad | 58:f50b97b08851 | 192 | LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size"); |
markrad | 58:f50b97b08851 | 193 | } |
markrad | 58:f50b97b08851 | 194 | else |
markrad | 58:f50b97b08851 | 195 | { |
markrad | 58:f50b97b08851 | 196 | handleData->keys = undoneKeys; |
markrad | 58:f50b97b08851 | 197 | } |
markrad | 58:f50b97b08851 | 198 | } |
markrad | 58:f50b97b08851 | 199 | result = __LINE__; |
markrad | 58:f50b97b08851 | 200 | } |
markrad | 58:f50b97b08851 | 201 | else |
markrad | 58:f50b97b08851 | 202 | { |
markrad | 58:f50b97b08851 | 203 | handleData->values = newValues; |
markrad | 58:f50b97b08851 | 204 | handleData->values[handleData->count] = NULL; |
markrad | 58:f50b97b08851 | 205 | handleData->count++; |
markrad | 58:f50b97b08851 | 206 | result = 0; |
markrad | 58:f50b97b08851 | 207 | } |
markrad | 58:f50b97b08851 | 208 | } |
markrad | 58:f50b97b08851 | 209 | return result; |
markrad | 58:f50b97b08851 | 210 | } |
markrad | 58:f50b97b08851 | 211 | |
markrad | 58:f50b97b08851 | 212 | static void Map_DecreaseStorageKeysValues(MAP_HANDLE_DATA* handleData) |
markrad | 58:f50b97b08851 | 213 | { |
markrad | 58:f50b97b08851 | 214 | if (handleData->count == 1) |
markrad | 58:f50b97b08851 | 215 | { |
markrad | 58:f50b97b08851 | 216 | free(handleData->keys); |
markrad | 58:f50b97b08851 | 217 | handleData->keys = NULL; |
markrad | 58:f50b97b08851 | 218 | free(handleData->values); |
markrad | 58:f50b97b08851 | 219 | handleData->values = NULL; |
markrad | 58:f50b97b08851 | 220 | handleData->count = 0; |
markrad | 58:f50b97b08851 | 221 | handleData->mapFilterCallback = NULL; |
markrad | 58:f50b97b08851 | 222 | } |
markrad | 58:f50b97b08851 | 223 | else |
markrad | 58:f50b97b08851 | 224 | { |
markrad | 58:f50b97b08851 | 225 | /*certainly > 1...*/ |
markrad | 58:f50b97b08851 | 226 | char** undoneValues; |
markrad | 58:f50b97b08851 | 227 | char** undoneKeys = (char**)realloc(handleData->keys, sizeof(char*)* (handleData->count - 1)); |
markrad | 58:f50b97b08851 | 228 | if (undoneKeys == NULL) |
markrad | 58:f50b97b08851 | 229 | { |
markrad | 58:f50b97b08851 | 230 | LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size"); |
markrad | 58:f50b97b08851 | 231 | } |
markrad | 58:f50b97b08851 | 232 | else |
markrad | 58:f50b97b08851 | 233 | { |
markrad | 58:f50b97b08851 | 234 | handleData->keys = undoneKeys; |
markrad | 58:f50b97b08851 | 235 | } |
markrad | 58:f50b97b08851 | 236 | |
markrad | 58:f50b97b08851 | 237 | undoneValues = (char**)realloc(handleData->values, sizeof(char*)* (handleData->count - 1)); |
markrad | 58:f50b97b08851 | 238 | if (undoneValues == NULL) |
markrad | 58:f50b97b08851 | 239 | { |
markrad | 58:f50b97b08851 | 240 | LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size"); |
markrad | 58:f50b97b08851 | 241 | } |
markrad | 58:f50b97b08851 | 242 | else |
markrad | 58:f50b97b08851 | 243 | { |
markrad | 58:f50b97b08851 | 244 | handleData->values = undoneValues; |
markrad | 58:f50b97b08851 | 245 | } |
markrad | 58:f50b97b08851 | 246 | |
markrad | 58:f50b97b08851 | 247 | handleData->count--; |
markrad | 58:f50b97b08851 | 248 | } |
markrad | 58:f50b97b08851 | 249 | } |
markrad | 58:f50b97b08851 | 250 | |
markrad | 58:f50b97b08851 | 251 | static char** findKey(MAP_HANDLE_DATA* handleData, const char* key) |
markrad | 58:f50b97b08851 | 252 | { |
markrad | 58:f50b97b08851 | 253 | char** result; |
markrad | 58:f50b97b08851 | 254 | if (handleData->keys == NULL) |
markrad | 58:f50b97b08851 | 255 | { |
markrad | 58:f50b97b08851 | 256 | result = NULL; |
markrad | 58:f50b97b08851 | 257 | } |
markrad | 58:f50b97b08851 | 258 | else |
markrad | 58:f50b97b08851 | 259 | { |
markrad | 58:f50b97b08851 | 260 | size_t i; |
markrad | 58:f50b97b08851 | 261 | result = NULL; |
markrad | 58:f50b97b08851 | 262 | for (i = 0; i < handleData->count; i++) |
markrad | 58:f50b97b08851 | 263 | { |
markrad | 58:f50b97b08851 | 264 | if (strcmp(handleData->keys[i], key) == 0) |
markrad | 58:f50b97b08851 | 265 | { |
markrad | 58:f50b97b08851 | 266 | result = handleData->keys + i; |
markrad | 58:f50b97b08851 | 267 | break; |
markrad | 58:f50b97b08851 | 268 | } |
markrad | 58:f50b97b08851 | 269 | } |
markrad | 58:f50b97b08851 | 270 | } |
markrad | 58:f50b97b08851 | 271 | return result; |
markrad | 58:f50b97b08851 | 272 | } |
markrad | 58:f50b97b08851 | 273 | |
markrad | 58:f50b97b08851 | 274 | static char** findValue(MAP_HANDLE_DATA* handleData, const char* value) |
markrad | 58:f50b97b08851 | 275 | { |
markrad | 58:f50b97b08851 | 276 | char** result; |
markrad | 58:f50b97b08851 | 277 | if (handleData->values == NULL) |
markrad | 58:f50b97b08851 | 278 | { |
markrad | 58:f50b97b08851 | 279 | result = NULL; |
markrad | 58:f50b97b08851 | 280 | } |
markrad | 58:f50b97b08851 | 281 | else |
markrad | 58:f50b97b08851 | 282 | { |
markrad | 58:f50b97b08851 | 283 | size_t i; |
markrad | 58:f50b97b08851 | 284 | result = NULL; |
markrad | 58:f50b97b08851 | 285 | for (i = 0; i < handleData->count; i++) |
markrad | 58:f50b97b08851 | 286 | { |
markrad | 58:f50b97b08851 | 287 | if (strcmp(handleData->values[i], value) == 0) |
markrad | 58:f50b97b08851 | 288 | { |
markrad | 58:f50b97b08851 | 289 | result = handleData->values + i; |
markrad | 58:f50b97b08851 | 290 | break; |
markrad | 58:f50b97b08851 | 291 | } |
markrad | 58:f50b97b08851 | 292 | } |
markrad | 58:f50b97b08851 | 293 | } |
markrad | 58:f50b97b08851 | 294 | return result; |
markrad | 58:f50b97b08851 | 295 | } |
markrad | 58:f50b97b08851 | 296 | |
markrad | 58:f50b97b08851 | 297 | static int insertNewKeyValue(MAP_HANDLE_DATA* handleData, const char* key, const char* value) |
markrad | 58:f50b97b08851 | 298 | { |
markrad | 58:f50b97b08851 | 299 | int result; |
markrad | 58:f50b97b08851 | 300 | if (Map_IncreaseStorageKeysValues(handleData) != 0) /*this increases handleData->count*/ |
markrad | 58:f50b97b08851 | 301 | { |
markrad | 58:f50b97b08851 | 302 | result = __LINE__; |
markrad | 58:f50b97b08851 | 303 | } |
markrad | 58:f50b97b08851 | 304 | else |
markrad | 58:f50b97b08851 | 305 | { |
markrad | 58:f50b97b08851 | 306 | if (mallocAndStrcpy_s(&(handleData->keys[handleData->count - 1]), key) != 0) |
markrad | 58:f50b97b08851 | 307 | { |
markrad | 58:f50b97b08851 | 308 | Map_DecreaseStorageKeysValues(handleData); |
markrad | 58:f50b97b08851 | 309 | LogError("unable to mallocAndStrcpy_s"); |
markrad | 58:f50b97b08851 | 310 | result = __LINE__; |
markrad | 58:f50b97b08851 | 311 | } |
markrad | 58:f50b97b08851 | 312 | else |
markrad | 58:f50b97b08851 | 313 | { |
markrad | 58:f50b97b08851 | 314 | if (mallocAndStrcpy_s(&(handleData->values[handleData->count - 1]), value) != 0) |
markrad | 58:f50b97b08851 | 315 | { |
markrad | 58:f50b97b08851 | 316 | free(handleData->keys[handleData->count - 1]); |
markrad | 58:f50b97b08851 | 317 | Map_DecreaseStorageKeysValues(handleData); |
markrad | 58:f50b97b08851 | 318 | LogError("unable to mallocAndStrcpy_s"); |
markrad | 58:f50b97b08851 | 319 | result = __LINE__; |
markrad | 58:f50b97b08851 | 320 | } |
markrad | 58:f50b97b08851 | 321 | else |
markrad | 58:f50b97b08851 | 322 | { |
markrad | 58:f50b97b08851 | 323 | result = 0; |
markrad | 58:f50b97b08851 | 324 | } |
markrad | 58:f50b97b08851 | 325 | } |
markrad | 58:f50b97b08851 | 326 | } |
markrad | 58:f50b97b08851 | 327 | return result; |
markrad | 58:f50b97b08851 | 328 | } |
markrad | 58:f50b97b08851 | 329 | |
markrad | 58:f50b97b08851 | 330 | MAP_RESULT Map_Add(MAP_HANDLE handle, const char* key, const char* value) |
markrad | 58:f50b97b08851 | 331 | { |
markrad | 58:f50b97b08851 | 332 | MAP_RESULT result; |
markrad | 58:f50b97b08851 | 333 | /*Codes_SRS_MAP_02_006: [If parameter handle is NULL then Map_Add shall return MAP_INVALID_ARG.] */ |
markrad | 58:f50b97b08851 | 334 | /*Codes_SRS_MAP_02_007: [If parameter key is NULL then Map_Add shall return MAP_INVALID_ARG.]*/ |
markrad | 58:f50b97b08851 | 335 | /*Codes_SRS_MAP_02_008: [If parameter value is NULL then Map_Add shall return MAP_INVALID_ARG.] */ |
markrad | 58:f50b97b08851 | 336 | if ( |
markrad | 58:f50b97b08851 | 337 | (handle == NULL) || |
markrad | 58:f50b97b08851 | 338 | (key == NULL) || |
markrad | 58:f50b97b08851 | 339 | (value == NULL) |
markrad | 58:f50b97b08851 | 340 | ) |
markrad | 58:f50b97b08851 | 341 | { |
markrad | 58:f50b97b08851 | 342 | result = MAP_INVALIDARG; |
markrad | 58:f50b97b08851 | 343 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 344 | } |
markrad | 58:f50b97b08851 | 345 | else |
markrad | 58:f50b97b08851 | 346 | { |
markrad | 58:f50b97b08851 | 347 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle; |
markrad | 58:f50b97b08851 | 348 | /*Codes_SRS_MAP_02_009: [If the key already exists, then Map_Add shall return MAP_KEYEXISTS.] */ |
markrad | 58:f50b97b08851 | 349 | if (findKey(handleData, key) != NULL) |
markrad | 58:f50b97b08851 | 350 | { |
markrad | 58:f50b97b08851 | 351 | result = MAP_KEYEXISTS; |
markrad | 58:f50b97b08851 | 352 | } |
markrad | 58:f50b97b08851 | 353 | else |
markrad | 58:f50b97b08851 | 354 | { |
markrad | 58:f50b97b08851 | 355 | /* Codes_SRS_MAP_07_009: [If the mapFilterCallback function is not NULL, then the return value will be check and if it is not zero then Map_Add shall return MAP_FILTER_REJECT.] */ |
markrad | 58:f50b97b08851 | 356 | if ( (handleData->mapFilterCallback != NULL) && (handleData->mapFilterCallback(key, value) != 0) ) |
markrad | 58:f50b97b08851 | 357 | { |
markrad | 58:f50b97b08851 | 358 | result = MAP_FILTER_REJECT; |
markrad | 58:f50b97b08851 | 359 | } |
markrad | 58:f50b97b08851 | 360 | else |
markrad | 58:f50b97b08851 | 361 | { |
markrad | 58:f50b97b08851 | 362 | /*Codes_SRS_MAP_02_010: [Otherwise, Map_Add shall add the pair <key,value> to the map.] */ |
markrad | 58:f50b97b08851 | 363 | if (insertNewKeyValue(handleData, key, value) != 0) |
markrad | 58:f50b97b08851 | 364 | { |
markrad | 58:f50b97b08851 | 365 | /*Codes_SRS_MAP_02_011: [If adding the pair <key,value> fails then Map_Add shall return MAP_ERROR.] */ |
markrad | 58:f50b97b08851 | 366 | result = MAP_ERROR; |
markrad | 58:f50b97b08851 | 367 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 368 | } |
markrad | 58:f50b97b08851 | 369 | else |
markrad | 58:f50b97b08851 | 370 | { |
markrad | 58:f50b97b08851 | 371 | /*Codes_SRS_MAP_02_012: [Otherwise, Map_Add shall return MAP_OK.] */ |
markrad | 58:f50b97b08851 | 372 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 373 | } |
markrad | 58:f50b97b08851 | 374 | } |
markrad | 58:f50b97b08851 | 375 | } |
markrad | 58:f50b97b08851 | 376 | } |
markrad | 58:f50b97b08851 | 377 | return result; |
markrad | 58:f50b97b08851 | 378 | } |
markrad | 58:f50b97b08851 | 379 | |
markrad | 58:f50b97b08851 | 380 | MAP_RESULT Map_AddOrUpdate(MAP_HANDLE handle, const char* key, const char* value) |
markrad | 58:f50b97b08851 | 381 | { |
markrad | 58:f50b97b08851 | 382 | MAP_RESULT result; |
markrad | 58:f50b97b08851 | 383 | /*Codes_SRS_MAP_02_013: [If parameter handle is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.]*/ |
markrad | 58:f50b97b08851 | 384 | /*Codes_SRS_MAP_02_014: [If parameter key is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.]*/ |
markrad | 58:f50b97b08851 | 385 | /*Codes_SRS_MAP_02_015: [If parameter value is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.] */ |
markrad | 58:f50b97b08851 | 386 | if ( |
markrad | 58:f50b97b08851 | 387 | (handle == NULL) || |
markrad | 58:f50b97b08851 | 388 | (key == NULL) || |
markrad | 58:f50b97b08851 | 389 | (value == NULL) |
markrad | 58:f50b97b08851 | 390 | ) |
markrad | 58:f50b97b08851 | 391 | { |
markrad | 58:f50b97b08851 | 392 | result = MAP_INVALIDARG; |
markrad | 58:f50b97b08851 | 393 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 394 | } |
markrad | 58:f50b97b08851 | 395 | else |
markrad | 58:f50b97b08851 | 396 | { |
markrad | 58:f50b97b08851 | 397 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle; |
markrad | 58:f50b97b08851 | 398 | |
markrad | 58:f50b97b08851 | 399 | /* Codes_SRS_MAP_07_008: [If the mapFilterCallback function is not NULL, then the return value will be check and if it is not zero then Map_AddOrUpdate shall return MAP_FILTER_REJECT.] */ |
markrad | 58:f50b97b08851 | 400 | if (handleData->mapFilterCallback != NULL && handleData->mapFilterCallback(key, value) != 0) |
markrad | 58:f50b97b08851 | 401 | { |
markrad | 58:f50b97b08851 | 402 | result = MAP_FILTER_REJECT; |
markrad | 58:f50b97b08851 | 403 | } |
markrad | 58:f50b97b08851 | 404 | else |
markrad | 58:f50b97b08851 | 405 | { |
markrad | 58:f50b97b08851 | 406 | char** whereIsIt = findKey(handleData, key); |
markrad | 58:f50b97b08851 | 407 | if (whereIsIt == NULL) |
markrad | 58:f50b97b08851 | 408 | { |
markrad | 58:f50b97b08851 | 409 | /*Codes_SRS_MAP_02_017: [Otherwise, Map_AddOrUpdate shall add the pair <key,value> to the map.]*/ |
markrad | 58:f50b97b08851 | 410 | if (insertNewKeyValue(handleData, key, value) != 0) |
markrad | 58:f50b97b08851 | 411 | { |
markrad | 58:f50b97b08851 | 412 | result = MAP_ERROR; |
markrad | 58:f50b97b08851 | 413 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 414 | } |
markrad | 58:f50b97b08851 | 415 | else |
markrad | 58:f50b97b08851 | 416 | { |
markrad | 58:f50b97b08851 | 417 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 418 | } |
markrad | 58:f50b97b08851 | 419 | } |
markrad | 58:f50b97b08851 | 420 | else |
markrad | 58:f50b97b08851 | 421 | { |
markrad | 58:f50b97b08851 | 422 | /*Codes_SRS_MAP_02_016: [If the key already exists, then Map_AddOrUpdate shall overwrite the value of the existing key with parameter value.]*/ |
markrad | 58:f50b97b08851 | 423 | size_t index = whereIsIt - handleData->keys; |
markrad | 58:f50b97b08851 | 424 | size_t valueLength = strlen(value); |
markrad | 58:f50b97b08851 | 425 | /*try to realloc value of this key*/ |
markrad | 58:f50b97b08851 | 426 | char* newValue = (char*)realloc(handleData->values[index],valueLength + 1); |
markrad | 58:f50b97b08851 | 427 | if (newValue == NULL) |
markrad | 58:f50b97b08851 | 428 | { |
markrad | 58:f50b97b08851 | 429 | result = MAP_ERROR; |
markrad | 58:f50b97b08851 | 430 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 431 | } |
markrad | 58:f50b97b08851 | 432 | else |
markrad | 58:f50b97b08851 | 433 | { |
markrad | 58:f50b97b08851 | 434 | memcpy(newValue, value, valueLength + 1); |
markrad | 58:f50b97b08851 | 435 | handleData->values[index] = newValue; |
markrad | 58:f50b97b08851 | 436 | /*Codes_SRS_MAP_02_019: [Otherwise, Map_AddOrUpdate shall return MAP_OK.] */ |
markrad | 58:f50b97b08851 | 437 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 438 | } |
markrad | 58:f50b97b08851 | 439 | } |
markrad | 58:f50b97b08851 | 440 | } |
markrad | 58:f50b97b08851 | 441 | } |
markrad | 58:f50b97b08851 | 442 | return result; |
markrad | 58:f50b97b08851 | 443 | } |
markrad | 58:f50b97b08851 | 444 | |
markrad | 58:f50b97b08851 | 445 | MAP_RESULT Map_Delete(MAP_HANDLE handle, const char* key) |
markrad | 58:f50b97b08851 | 446 | { |
markrad | 58:f50b97b08851 | 447 | MAP_RESULT result; |
markrad | 58:f50b97b08851 | 448 | /*Codes_SRS_MAP_02_020: [If parameter handle is NULL then Map_Delete shall return MAP_INVALIDARG.]*/ |
markrad | 58:f50b97b08851 | 449 | /*Codes_SRS_MAP_02_021: [If parameter key is NULL then Map_Delete shall return MAP_INVALIDARG.]*/ |
markrad | 58:f50b97b08851 | 450 | if ( |
markrad | 58:f50b97b08851 | 451 | (handle == NULL) || |
markrad | 58:f50b97b08851 | 452 | (key == NULL) |
markrad | 58:f50b97b08851 | 453 | ) |
markrad | 58:f50b97b08851 | 454 | { |
markrad | 58:f50b97b08851 | 455 | result = MAP_INVALIDARG; |
markrad | 58:f50b97b08851 | 456 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 457 | } |
markrad | 58:f50b97b08851 | 458 | else |
markrad | 58:f50b97b08851 | 459 | { |
markrad | 58:f50b97b08851 | 460 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle; |
markrad | 58:f50b97b08851 | 461 | char** whereIsIt = findKey(handleData,key); |
markrad | 58:f50b97b08851 | 462 | if (whereIsIt == NULL) |
markrad | 58:f50b97b08851 | 463 | { |
markrad | 58:f50b97b08851 | 464 | /*Codes_SRS_MAP_02_022: [If key does not exist then Map_Delete shall return MAP_KEYNOTFOUND.]*/ |
markrad | 58:f50b97b08851 | 465 | result = MAP_KEYNOTFOUND; |
markrad | 58:f50b97b08851 | 466 | } |
markrad | 58:f50b97b08851 | 467 | else |
markrad | 58:f50b97b08851 | 468 | { |
markrad | 58:f50b97b08851 | 469 | /*Codes_SRS_MAP_02_023: [Otherwise, Map_Delete shall remove the key and its associated value from the map and return MAP_OK.]*/ |
markrad | 58:f50b97b08851 | 470 | size_t index = whereIsIt - handleData->keys; |
markrad | 58:f50b97b08851 | 471 | free(handleData->keys[index]); |
markrad | 58:f50b97b08851 | 472 | free(handleData->values[index]); |
markrad | 58:f50b97b08851 | 473 | memmove(handleData->keys + index, handleData->keys + index + 1, (handleData->count - index - 1)*sizeof(char*)); /*if order doesn't matter... then this can be optimized*/ |
markrad | 58:f50b97b08851 | 474 | memmove(handleData->values + index, handleData->values + index + 1, (handleData->count - index - 1)*sizeof(char*)); |
markrad | 58:f50b97b08851 | 475 | Map_DecreaseStorageKeysValues(handleData); |
markrad | 58:f50b97b08851 | 476 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 477 | } |
markrad | 58:f50b97b08851 | 478 | |
markrad | 58:f50b97b08851 | 479 | } |
markrad | 58:f50b97b08851 | 480 | return result; |
markrad | 58:f50b97b08851 | 481 | } |
markrad | 58:f50b97b08851 | 482 | |
markrad | 58:f50b97b08851 | 483 | MAP_RESULT Map_ContainsKey(MAP_HANDLE handle, const char* key, bool* keyExists) |
markrad | 58:f50b97b08851 | 484 | { |
markrad | 58:f50b97b08851 | 485 | MAP_RESULT result; |
markrad | 58:f50b97b08851 | 486 | /*Codes_SRS_MAP_02_024: [If parameter handle, key or keyExists are NULL then Map_ContainsKey shall return MAP_INVALIDARG.]*/ |
markrad | 58:f50b97b08851 | 487 | if ( |
markrad | 58:f50b97b08851 | 488 | (handle ==NULL) || |
markrad | 58:f50b97b08851 | 489 | (key == NULL) || |
markrad | 58:f50b97b08851 | 490 | (keyExists == NULL) |
markrad | 58:f50b97b08851 | 491 | ) |
markrad | 58:f50b97b08851 | 492 | { |
markrad | 58:f50b97b08851 | 493 | result = MAP_INVALIDARG; |
markrad | 58:f50b97b08851 | 494 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 495 | } |
markrad | 58:f50b97b08851 | 496 | else |
markrad | 58:f50b97b08851 | 497 | { |
markrad | 58:f50b97b08851 | 498 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle; |
markrad | 58:f50b97b08851 | 499 | /*Codes_SRS_MAP_02_025: [Otherwise if a key exists then Map_ContainsKey shall return MAP_OK and shall write in keyExists "true".]*/ |
markrad | 58:f50b97b08851 | 500 | /*Codes_SRS_MAP_02_026: [If a key doesn't exist, then Map_ContainsKey shall return MAP_OK and write in keyExists "false".] */ |
markrad | 58:f50b97b08851 | 501 | *keyExists = (findKey(handleData, key) != NULL) ? true: false; |
markrad | 58:f50b97b08851 | 502 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 503 | } |
markrad | 58:f50b97b08851 | 504 | return result; |
markrad | 58:f50b97b08851 | 505 | } |
markrad | 58:f50b97b08851 | 506 | |
markrad | 58:f50b97b08851 | 507 | MAP_RESULT Map_ContainsValue(MAP_HANDLE handle, const char* value, bool* valueExists) |
markrad | 58:f50b97b08851 | 508 | { |
markrad | 58:f50b97b08851 | 509 | MAP_RESULT result; |
markrad | 58:f50b97b08851 | 510 | /*Codes_SRS_MAP_02_027: [If parameter handle, value or valueExists is NULL then Map_ContainsValue shall return MAP_INVALIDARG.] */ |
markrad | 58:f50b97b08851 | 511 | if ( |
markrad | 58:f50b97b08851 | 512 | (handle == NULL) || |
markrad | 58:f50b97b08851 | 513 | (value == NULL) || |
markrad | 58:f50b97b08851 | 514 | (valueExists == NULL) |
markrad | 58:f50b97b08851 | 515 | ) |
markrad | 58:f50b97b08851 | 516 | { |
markrad | 58:f50b97b08851 | 517 | result = MAP_INVALIDARG; |
markrad | 58:f50b97b08851 | 518 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 519 | } |
markrad | 58:f50b97b08851 | 520 | else |
markrad | 58:f50b97b08851 | 521 | { |
markrad | 58:f50b97b08851 | 522 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle; |
markrad | 58:f50b97b08851 | 523 | /*Codes_SRS_MAP_02_028: [Otherwise, if a pair <key, value> has its value equal to the parameter value, the Map_ContainsValue shall return MAP_OK and shall write in valueExists "true".]*/ |
markrad | 58:f50b97b08851 | 524 | /*Codes_SRS_MAP_02_029: [Otherwise, if such a <key, value> does not exist, then Map_ContainsValue shall return MAP_OK and shall write in valueExists "false".] */ |
markrad | 58:f50b97b08851 | 525 | *valueExists = (findValue(handleData, value) != NULL) ? true : false; |
markrad | 58:f50b97b08851 | 526 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 527 | } |
markrad | 58:f50b97b08851 | 528 | return result; |
markrad | 58:f50b97b08851 | 529 | } |
markrad | 58:f50b97b08851 | 530 | |
markrad | 58:f50b97b08851 | 531 | const char* Map_GetValueFromKey(MAP_HANDLE handle, const char* key) |
markrad | 58:f50b97b08851 | 532 | { |
markrad | 58:f50b97b08851 | 533 | const char* result; |
markrad | 58:f50b97b08851 | 534 | /*Codes_SRS_MAP_02_040: [If parameter handle or key is NULL then Map_GetValueFromKey returns NULL.]*/ |
markrad | 58:f50b97b08851 | 535 | if ( |
markrad | 58:f50b97b08851 | 536 | (handle == NULL) || |
markrad | 58:f50b97b08851 | 537 | (key == NULL) |
markrad | 58:f50b97b08851 | 538 | ) |
markrad | 58:f50b97b08851 | 539 | { |
markrad | 58:f50b97b08851 | 540 | result = NULL; |
markrad | 58:f50b97b08851 | 541 | LogError("invalid parameter to Map_GetValueFromKey"); |
markrad | 58:f50b97b08851 | 542 | } |
markrad | 58:f50b97b08851 | 543 | else |
markrad | 58:f50b97b08851 | 544 | { |
markrad | 58:f50b97b08851 | 545 | MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle; |
markrad | 58:f50b97b08851 | 546 | char** whereIsIt = findKey(handleData, key); |
markrad | 58:f50b97b08851 | 547 | if(whereIsIt == NULL) |
markrad | 58:f50b97b08851 | 548 | { |
markrad | 58:f50b97b08851 | 549 | /*Codes_SRS_MAP_02_041: [If the key is not found, then Map_GetValueFromKey returns NULL.]*/ |
markrad | 58:f50b97b08851 | 550 | result = NULL; |
markrad | 58:f50b97b08851 | 551 | } |
markrad | 58:f50b97b08851 | 552 | else |
markrad | 58:f50b97b08851 | 553 | { |
markrad | 58:f50b97b08851 | 554 | /*Codes_SRS_MAP_02_042: [Otherwise, Map_GetValueFromKey returns the key's value.] */ |
markrad | 58:f50b97b08851 | 555 | size_t index = whereIsIt - handleData->keys; |
markrad | 58:f50b97b08851 | 556 | result = handleData->values[index]; |
markrad | 58:f50b97b08851 | 557 | } |
markrad | 58:f50b97b08851 | 558 | } |
markrad | 58:f50b97b08851 | 559 | return result; |
markrad | 58:f50b97b08851 | 560 | } |
markrad | 58:f50b97b08851 | 561 | |
markrad | 58:f50b97b08851 | 562 | MAP_RESULT Map_GetInternals(MAP_HANDLE handle, const char*const** keys, const char*const** values, size_t* count) |
markrad | 58:f50b97b08851 | 563 | { |
markrad | 58:f50b97b08851 | 564 | MAP_RESULT result; |
markrad | 58:f50b97b08851 | 565 | /*Codes_SRS_MAP_02_046: [If parameter handle, keys, values or count is NULL then Map_GetInternals shall return MAP_INVALIDARG.] */ |
markrad | 58:f50b97b08851 | 566 | if ( |
markrad | 58:f50b97b08851 | 567 | (handle == NULL) || |
markrad | 58:f50b97b08851 | 568 | (keys == NULL) || |
markrad | 58:f50b97b08851 | 569 | (values == NULL) || |
markrad | 58:f50b97b08851 | 570 | (count == NULL) |
markrad | 58:f50b97b08851 | 571 | ) |
markrad | 58:f50b97b08851 | 572 | { |
markrad | 58:f50b97b08851 | 573 | result = MAP_INVALIDARG; |
markrad | 58:f50b97b08851 | 574 | LOG_MAP_ERROR; |
markrad | 58:f50b97b08851 | 575 | } |
markrad | 58:f50b97b08851 | 576 | else |
markrad | 58:f50b97b08851 | 577 | { |
markrad | 58:f50b97b08851 | 578 | /*Codes_SRS_MAP_02_043: [Map_GetInternals shall produce in *keys an pointer to an array of const char* having all the keys stored so far by the map.]*/ |
markrad | 58:f50b97b08851 | 579 | /*Codes_SRS_MAP_02_044: [Map_GetInternals shall produce in *values a pointer to an array of const char* having all the values stored so far by the map.]*/ |
markrad | 58:f50b97b08851 | 580 | /*Codes_SRS_MAP_02_045: [ Map_GetInternals shall produce in *count the number of stored keys and values.]*/ |
markrad | 58:f50b97b08851 | 581 | MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle; |
markrad | 58:f50b97b08851 | 582 | *keys =(const char* const*)(handleData->keys); |
markrad | 58:f50b97b08851 | 583 | *values = (const char* const*)(handleData->values); |
markrad | 58:f50b97b08851 | 584 | *count = handleData->count; |
markrad | 58:f50b97b08851 | 585 | result = MAP_OK; |
markrad | 58:f50b97b08851 | 586 | } |
markrad | 58:f50b97b08851 | 587 | return result; |
markrad | 58:f50b97b08851 | 588 | } |
markrad | 58:f50b97b08851 | 589 | |
markrad | 58:f50b97b08851 | 590 | STRING_HANDLE Map_ToJSON(MAP_HANDLE handle) |
markrad | 58:f50b97b08851 | 591 | { |
markrad | 58:f50b97b08851 | 592 | STRING_HANDLE result; |
markrad | 58:f50b97b08851 | 593 | /*Codes_SRS_MAP_02_052: [If parameter handle is NULL then Map_ToJSON shall return NULL.] */ |
markrad | 58:f50b97b08851 | 594 | if (handle == NULL) |
markrad | 58:f50b97b08851 | 595 | { |
markrad | 58:f50b97b08851 | 596 | result = NULL; |
markrad | 58:f50b97b08851 | 597 | LogError("invalid arg (NULL)"); |
markrad | 58:f50b97b08851 | 598 | } |
markrad | 58:f50b97b08851 | 599 | else |
markrad | 58:f50b97b08851 | 600 | { |
markrad | 58:f50b97b08851 | 601 | /*Codes_SRS_MAP_02_048: [Map_ToJSON shall produce a STRING_HANDLE representing the content of the MAP.] */ |
markrad | 58:f50b97b08851 | 602 | result = STRING_construct("{"); |
markrad | 58:f50b97b08851 | 603 | if (result == NULL) |
markrad | 58:f50b97b08851 | 604 | { |
markrad | 58:f50b97b08851 | 605 | LogError("STRING_construct failed"); |
markrad | 58:f50b97b08851 | 606 | } |
markrad | 58:f50b97b08851 | 607 | else |
markrad | 58:f50b97b08851 | 608 | { |
markrad | 58:f50b97b08851 | 609 | size_t i; |
markrad | 58:f50b97b08851 | 610 | MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA *)handle; |
markrad | 58:f50b97b08851 | 611 | /*Codes_SRS_MAP_02_049: [If the MAP is empty, then Map_ToJSON shall produce the string "{}".*/ |
markrad | 58:f50b97b08851 | 612 | bool breakFor = false; /*used to break out of for*/ |
markrad | 58:f50b97b08851 | 613 | for (i = 0; (i < handleData->count) && (!breakFor); i++) |
markrad | 58:f50b97b08851 | 614 | { |
markrad | 58:f50b97b08851 | 615 | /*add one entry to the JSON*/ |
markrad | 58:f50b97b08851 | 616 | /*Codes_SRS_MAP_02_050: [If the map has properties then Map_ToJSON shall produce the following string:{"name1":"value1", "name2":"value2" ...}]*/ |
markrad | 58:f50b97b08851 | 617 | STRING_HANDLE key = STRING_new_JSON(handleData->keys[i]); |
markrad | 58:f50b97b08851 | 618 | if (key == NULL) |
markrad | 58:f50b97b08851 | 619 | { |
markrad | 58:f50b97b08851 | 620 | LogError("STRING_new_JSON failed"); |
markrad | 58:f50b97b08851 | 621 | STRING_delete(result); |
markrad | 58:f50b97b08851 | 622 | result = NULL; |
markrad | 58:f50b97b08851 | 623 | breakFor = true; |
markrad | 58:f50b97b08851 | 624 | } |
markrad | 58:f50b97b08851 | 625 | else |
markrad | 58:f50b97b08851 | 626 | { |
markrad | 58:f50b97b08851 | 627 | STRING_HANDLE value = STRING_new_JSON(handleData->values[i]); |
markrad | 58:f50b97b08851 | 628 | if (value == NULL) |
markrad | 58:f50b97b08851 | 629 | { |
markrad | 58:f50b97b08851 | 630 | LogError("STRING_new_JSON failed"); |
markrad | 58:f50b97b08851 | 631 | STRING_delete(result); |
markrad | 58:f50b97b08851 | 632 | result = NULL; |
markrad | 58:f50b97b08851 | 633 | breakFor = true; |
markrad | 58:f50b97b08851 | 634 | } |
markrad | 58:f50b97b08851 | 635 | else |
markrad | 58:f50b97b08851 | 636 | { |
markrad | 58:f50b97b08851 | 637 | if (!( |
markrad | 58:f50b97b08851 | 638 | ((i>0) ? (STRING_concat(result, ",") == 0) : 1) && |
markrad | 58:f50b97b08851 | 639 | (STRING_concat_with_STRING(result, key) == 0) && |
markrad | 58:f50b97b08851 | 640 | (STRING_concat(result, ":") == 0) && |
markrad | 58:f50b97b08851 | 641 | (STRING_concat_with_STRING(result, value) == 0) |
markrad | 58:f50b97b08851 | 642 | )) |
markrad | 58:f50b97b08851 | 643 | { |
markrad | 58:f50b97b08851 | 644 | LogError("failed to build the JSON"); |
markrad | 58:f50b97b08851 | 645 | STRING_delete(result); |
markrad | 58:f50b97b08851 | 646 | result = NULL; |
markrad | 58:f50b97b08851 | 647 | breakFor = true; |
markrad | 58:f50b97b08851 | 648 | } |
markrad | 58:f50b97b08851 | 649 | else |
markrad | 58:f50b97b08851 | 650 | { |
markrad | 58:f50b97b08851 | 651 | /*all nice, go to the next element in the map*/ |
markrad | 58:f50b97b08851 | 652 | } |
markrad | 58:f50b97b08851 | 653 | STRING_delete(value); |
markrad | 58:f50b97b08851 | 654 | } |
markrad | 58:f50b97b08851 | 655 | STRING_delete(key); |
markrad | 58:f50b97b08851 | 656 | } |
markrad | 58:f50b97b08851 | 657 | } |
markrad | 58:f50b97b08851 | 658 | |
markrad | 58:f50b97b08851 | 659 | if (breakFor) |
markrad | 58:f50b97b08851 | 660 | { |
markrad | 58:f50b97b08851 | 661 | LogError("error happened during JSON string builder"); |
markrad | 58:f50b97b08851 | 662 | } |
markrad | 58:f50b97b08851 | 663 | else |
markrad | 58:f50b97b08851 | 664 | { |
markrad | 58:f50b97b08851 | 665 | if (STRING_concat(result, "}") != 0) |
markrad | 58:f50b97b08851 | 666 | { |
markrad | 58:f50b97b08851 | 667 | LogError("failed to build the JSON"); |
markrad | 58:f50b97b08851 | 668 | STRING_delete(result); |
markrad | 58:f50b97b08851 | 669 | result = NULL; |
markrad | 58:f50b97b08851 | 670 | } |
markrad | 58:f50b97b08851 | 671 | else |
markrad | 58:f50b97b08851 | 672 | { |
markrad | 58:f50b97b08851 | 673 | /*return as is, JSON has been build*/ |
markrad | 58:f50b97b08851 | 674 | } |
markrad | 58:f50b97b08851 | 675 | } |
markrad | 58:f50b97b08851 | 676 | } |
markrad | 58:f50b97b08851 | 677 | } |
markrad | 58:f50b97b08851 | 678 | return result; |
markrad | 58:f50b97b08851 | 679 | |
markrad | 58:f50b97b08851 | 680 | } |