Demo using MBED TLS

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

Committer:
markrad
Date:
Thu Jan 05 00:20:03 2017 +0000
Revision:
58:f50b97b08851
Sample using MBED TLS

Who changed what in which revision?

UserRevisionLine numberNew 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 }