Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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