Nigel Rantor / azure_c_shared_utility

Fork of azure_c_shared_utility by Azure IoT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers map.c Source File

map.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 #include <stdlib.h>
00005 #include "azure_c_shared_utility/gballoc.h"
00006 #include "azure_c_shared_utility/map.h"
00007 #include "azure_c_shared_utility/optimize_size.h"
00008 #include "azure_c_shared_utility/xlogging.h"
00009 #include "azure_c_shared_utility/strings.h"
00010 
00011 DEFINE_ENUM_STRINGS(MAP_RESULT, MAP_RESULT_VALUES);
00012 
00013 typedef struct MAP_HANDLE_DATA_TAG
00014 {
00015     char** keys;
00016     char** values;
00017     size_t count;
00018     MAP_FILTER_CALLBACK mapFilterCallback;
00019 }MAP_HANDLE_DATA;
00020 
00021 #define LOG_MAP_ERROR LogError("result = %s", ENUM_TO_STRING(MAP_RESULT, result));
00022 
00023 MAP_HANDLE Map_Create(MAP_FILTER_CALLBACK mapFilterFunc)
00024 {
00025     /*Codes_SRS_MAP_02_001: [Map_Create shall create a new, empty map.]*/
00026     MAP_HANDLE_DATA* result = (MAP_HANDLE_DATA*)malloc(sizeof(MAP_HANDLE_DATA));
00027     /*Codes_SRS_MAP_02_002: [If during creation there are any error, then Map_Create shall return NULL.]*/
00028     if (result != NULL)
00029     {
00030         /*Codes_SRS_MAP_02_003: [Otherwise, it shall return a non-NULL handle that can be used in subsequent calls.] */
00031         result->keys = NULL;
00032         result->values = NULL;
00033         result->count = 0;
00034         result->mapFilterCallback = mapFilterFunc;
00035     }
00036     return (MAP_HANDLE)result;
00037 }
00038 
00039 void Map_Destroy(MAP_HANDLE handle)
00040 {
00041     /*Codes_SRS_MAP_02_005: [If parameter handle is NULL then Map_Destroy shall take no action.] */
00042     if (handle != NULL)
00043     {
00044         /*Codes_SRS_MAP_02_004: [Map_Destroy shall release all resources associated with the map.] */
00045         MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
00046         size_t i;
00047       
00048         for (i = 0; i < handleData->count; i++)
00049         {
00050             free(handleData->keys[i]);
00051             free(handleData->values[i]);
00052         }
00053         free(handleData->keys);
00054         free(handleData->values);
00055         free(handleData);
00056     }
00057 }
00058 
00059 /*makes a copy of a vector of const char*, having size "size". source cannot be NULL*/
00060 /*returns NULL if it fails*/
00061 static char** Map_CloneVector(const char*const * source, size_t count)
00062 {
00063     char** result;
00064     result = (char**)malloc(count *sizeof(char*));
00065     if (result == NULL)
00066     {
00067         /*do nothing, just return it (NULL)*/
00068     }
00069     else
00070     {
00071         size_t i;
00072         for (i = 0; i < count; i++)
00073         {
00074             if (mallocAndStrcpy_s(result + i, source[i]) != 0)
00075             {
00076                 break;
00077             }
00078         }
00079 
00080         if (i == count)
00081         {
00082             /*it is all good, proceed to return result*/
00083         }
00084         else
00085         {
00086             size_t j;
00087             for (j = 0; j < i; j++)
00088             {
00089                 free(result[j]);
00090             }
00091             free(result);
00092             result = NULL;
00093         }
00094     }
00095     return result;
00096 }
00097 
00098 /*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.]*/
00099 MAP_HANDLE Map_Clone(MAP_HANDLE handle)
00100 {
00101     MAP_HANDLE_DATA* result;
00102     if (handle == NULL)
00103     {
00104         /*Codes_SRS_MAP_02_038: [Map_Clone returns NULL if parameter handle is NULL.]*/
00105         result = NULL;
00106         LogError("invalid arg to Map_Clone (NULL)");
00107     }
00108     else
00109     {
00110         MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle;
00111         result = (MAP_HANDLE_DATA*)malloc(sizeof(MAP_HANDLE_DATA));
00112         if (result == NULL)
00113         {
00114             /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
00115             /*do nothing, proceed to return it, this is an error case*/
00116             LogError("unable to malloc");
00117         }
00118         else
00119         {
00120             if (handleData->count == 0)  
00121             {
00122                 result->count = 0;
00123                 result->keys = NULL;
00124                 result->values = NULL;
00125                 result->mapFilterCallback = NULL;
00126             }
00127             else
00128             {
00129                 result->mapFilterCallback = handleData->mapFilterCallback;
00130                 result->count = handleData->count;
00131                 if( (result->keys = Map_CloneVector((const char* const*)handleData->keys, handleData->count))==NULL)
00132                 {
00133                     /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
00134                     LogError("unable to clone keys");
00135                     free(result);
00136                     result = NULL;
00137                 }
00138                 else if ((result->values = Map_CloneVector((const char* const*)handleData->values, handleData->count)) == NULL)
00139                 {
00140                     size_t i;
00141                     /*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
00142                     LogError("unable to clone values");
00143                     for (i = 0; i < result->count; i++)
00144                     {
00145                         free(result->keys[i]); 
00146                     }
00147                     free(result->keys);
00148                     free(result);
00149                     result = NULL;
00150                 }
00151                 else
00152                 {
00153                     /*all fine, return it*/
00154                 }
00155             }
00156         }
00157     }
00158     return (MAP_HANDLE)result;
00159 }
00160 
00161 static int Map_IncreaseStorageKeysValues(MAP_HANDLE_DATA* handleData)
00162 {
00163     int result;
00164     char** newKeys = (char**)realloc(handleData->keys, (handleData->count + 1) * sizeof(char*));
00165     if (newKeys == NULL)
00166     {
00167         LogError("realloc error");
00168         result = __FAILURE__;
00169     }
00170     else
00171     {
00172         char** newValues;
00173         handleData->keys = newKeys;
00174         handleData->keys[handleData->count] = NULL;
00175         newValues = (char**)realloc(handleData->values, (handleData->count + 1) * sizeof(char*));
00176         if (newValues == NULL)
00177         {
00178             LogError("realloc error");
00179             if (handleData->count == 0) /*avoiding an implementation defined behavior */
00180             {
00181                 free(handleData->keys);
00182                 handleData->keys = NULL;
00183             }
00184             else
00185             {
00186                 char** undoneKeys = (char**)realloc(handleData->keys, (handleData->count) * sizeof(char*));
00187                 if (undoneKeys == NULL)
00188                 {
00189                     LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size");
00190                 }
00191                 else
00192                 {
00193                     handleData->keys = undoneKeys;
00194                 }
00195             }
00196             result = __FAILURE__;
00197         }
00198         else
00199         {
00200             handleData->values = newValues;
00201             handleData->values[handleData->count] = NULL;
00202             handleData->count++;
00203             result = 0;
00204         }
00205     }
00206     return result;
00207 }
00208 
00209 static void Map_DecreaseStorageKeysValues(MAP_HANDLE_DATA* handleData)
00210 {
00211     if (handleData->count == 1)
00212     {
00213         free(handleData->keys);
00214         handleData->keys = NULL;
00215         free(handleData->values);
00216         handleData->values = NULL;
00217         handleData->count = 0;
00218         handleData->mapFilterCallback = NULL;
00219     }
00220     else
00221     {
00222         /*certainly > 1...*/
00223         char** undoneValues;
00224         char** undoneKeys = (char**)realloc(handleData->keys, sizeof(char*)* (handleData->count - 1)); 
00225         if (undoneKeys == NULL)
00226         {
00227             LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size");
00228         }
00229         else
00230         {
00231             handleData->keys = undoneKeys;
00232         }
00233 
00234         undoneValues = (char**)realloc(handleData->values, sizeof(char*)* (handleData->count - 1));
00235         if (undoneValues == NULL)
00236         {
00237             LogError("CATASTROPHIC error, unable to undo through realloc to a smaller size");
00238         }
00239         else
00240         {
00241             handleData->values = undoneValues;
00242         }
00243 
00244         handleData->count--;
00245     }
00246 }
00247 
00248 static char** findKey(MAP_HANDLE_DATA* handleData, const char* key)
00249 {
00250     char** result;
00251     if (handleData->keys == NULL)
00252     {
00253         result = NULL;
00254     }
00255     else
00256     {
00257         size_t i;
00258         result = NULL;
00259         for (i = 0; i < handleData->count; i++)
00260         {
00261             if (strcmp(handleData->keys[i], key) == 0)
00262             {
00263                 result = handleData->keys + i;
00264                 break;
00265             }
00266         }
00267     }
00268     return result;
00269 }
00270 
00271 static char** findValue(MAP_HANDLE_DATA* handleData, const char* value)
00272 {
00273     char** result;
00274     if (handleData->values == NULL)
00275     {
00276         result = NULL;
00277     }
00278     else
00279     {
00280         size_t i;
00281         result = NULL;
00282         for (i = 0; i < handleData->count; i++)
00283         {
00284             if (strcmp(handleData->values[i], value) == 0)
00285             {
00286                 result = handleData->values + i;
00287                 break;
00288             }
00289         }
00290     }
00291     return result;
00292 }
00293 
00294 static int insertNewKeyValue(MAP_HANDLE_DATA* handleData, const char* key, const char* value)
00295 {
00296     int result;
00297     if (Map_IncreaseStorageKeysValues(handleData) != 0) /*this increases handleData->count*/
00298     {
00299         result = __FAILURE__;
00300     }
00301     else
00302     {
00303         if (mallocAndStrcpy_s(&(handleData->keys[handleData->count - 1]), key) != 0)
00304         {
00305             Map_DecreaseStorageKeysValues(handleData);
00306             LogError("unable to mallocAndStrcpy_s");
00307             result = __FAILURE__;
00308         }
00309         else
00310         {
00311             if (mallocAndStrcpy_s(&(handleData->values[handleData->count - 1]), value) != 0)
00312             {
00313                 free(handleData->keys[handleData->count - 1]);
00314                 Map_DecreaseStorageKeysValues(handleData);
00315                 LogError("unable to mallocAndStrcpy_s");
00316                 result = __FAILURE__;
00317             }
00318             else
00319             {
00320                 result = 0;
00321             }
00322         }
00323     }
00324     return result; 
00325 }
00326 
00327 MAP_RESULT Map_Add(MAP_HANDLE handle, const char* key, const char* value)
00328 {
00329     MAP_RESULT result;
00330     /*Codes_SRS_MAP_02_006: [If parameter handle is NULL then Map_Add shall return MAP_INVALID_ARG.] */
00331     /*Codes_SRS_MAP_02_007: [If parameter key is NULL then Map_Add shall return MAP_INVALID_ARG.]*/
00332     /*Codes_SRS_MAP_02_008: [If parameter value is NULL then Map_Add shall return MAP_INVALID_ARG.] */
00333     if (
00334         (handle == NULL) ||
00335         (key == NULL) ||
00336         (value == NULL)
00337         )
00338     {
00339         result = MAP_INVALIDARG;
00340         LOG_MAP_ERROR; 
00341     }
00342     else
00343     {
00344         MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
00345         /*Codes_SRS_MAP_02_009: [If the key already exists, then Map_Add shall return MAP_KEYEXISTS.] */
00346         if (findKey(handleData, key) != NULL)
00347         {
00348             result = MAP_KEYEXISTS;
00349         }
00350         else
00351         {
00352             /* 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.] */
00353             if ( (handleData->mapFilterCallback != NULL) && (handleData->mapFilterCallback(key, value) != 0) )
00354             {
00355                 result = MAP_FILTER_REJECT;
00356             }
00357             else
00358             {
00359                 /*Codes_SRS_MAP_02_010: [Otherwise, Map_Add shall add the pair <key,value> to the map.] */
00360                 if (insertNewKeyValue(handleData, key, value) != 0)
00361                 {
00362                     /*Codes_SRS_MAP_02_011: [If adding the pair <key,value> fails then Map_Add shall return MAP_ERROR.] */
00363                     result = MAP_ERROR;
00364                     LOG_MAP_ERROR;
00365                 }
00366                 else
00367                 {
00368                     /*Codes_SRS_MAP_02_012: [Otherwise, Map_Add shall return MAP_OK.] */
00369                     result = MAP_OK;
00370                 }
00371             }
00372         }
00373     }
00374     return result;
00375 }
00376 
00377 MAP_RESULT Map_AddOrUpdate(MAP_HANDLE handle, const char* key, const char* value)
00378 {
00379     MAP_RESULT result;
00380     /*Codes_SRS_MAP_02_013: [If parameter handle is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.]*/
00381     /*Codes_SRS_MAP_02_014: [If parameter key is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.]*/
00382     /*Codes_SRS_MAP_02_015: [If parameter value is NULL then Map_AddOrUpdate shall return MAP_INVALID_ARG.] */
00383     if (
00384         (handle == NULL) ||
00385         (key == NULL) ||
00386         (value == NULL)
00387         )
00388     {
00389         result = MAP_INVALIDARG;
00390         LOG_MAP_ERROR;
00391     }
00392     else
00393     {
00394         MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
00395 
00396         /* 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.] */
00397         if (handleData->mapFilterCallback != NULL && handleData->mapFilterCallback(key, value) != 0)
00398         {
00399             result = MAP_FILTER_REJECT;
00400         }
00401         else
00402         {
00403             char** whereIsIt = findKey(handleData, key);
00404             if (whereIsIt == NULL)
00405             {
00406                 /*Codes_SRS_MAP_02_017: [Otherwise, Map_AddOrUpdate shall add the pair <key,value> to the map.]*/
00407                 if (insertNewKeyValue(handleData, key, value) != 0)
00408                 {
00409                     result = MAP_ERROR;
00410                     LOG_MAP_ERROR;
00411                 }
00412                 else
00413                 {
00414                     result = MAP_OK;
00415                 }
00416             }
00417             else
00418             {
00419                 /*Codes_SRS_MAP_02_016: [If the key already exists, then Map_AddOrUpdate shall overwrite the value of the existing key with parameter value.]*/
00420                 size_t index = whereIsIt - handleData->keys;
00421                 size_t valueLength = strlen(value);
00422                 /*try to realloc value of this key*/
00423                 char* newValue = (char*)realloc(handleData->values[index],valueLength  + 1);
00424                 if (newValue == NULL)
00425                 {
00426                     result = MAP_ERROR;
00427                     LOG_MAP_ERROR;
00428                 }
00429                 else
00430                 {
00431                     (void)memcpy(newValue, value, valueLength + 1);
00432                     handleData->values[index] = newValue;
00433                     /*Codes_SRS_MAP_02_019: [Otherwise, Map_AddOrUpdate shall return MAP_OK.] */
00434                     result = MAP_OK;
00435                 }
00436             }
00437         }
00438     }
00439     return result;
00440 }
00441 
00442 MAP_RESULT Map_Delete(MAP_HANDLE handle, const char* key)
00443 {
00444     MAP_RESULT result;
00445     /*Codes_SRS_MAP_02_020: [If parameter handle is NULL then Map_Delete shall return MAP_INVALIDARG.]*/
00446     /*Codes_SRS_MAP_02_021: [If parameter key is NULL then Map_Delete shall return MAP_INVALIDARG.]*/
00447     if (
00448         (handle == NULL) ||
00449         (key == NULL)
00450         )
00451     {
00452         result = MAP_INVALIDARG;
00453         LOG_MAP_ERROR;
00454     }
00455     else
00456     {
00457         MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
00458         char** whereIsIt = findKey(handleData,key);
00459         if (whereIsIt == NULL)
00460         {
00461             /*Codes_SRS_MAP_02_022: [If key does not exist then Map_Delete shall return MAP_KEYNOTFOUND.]*/
00462             result = MAP_KEYNOTFOUND;
00463         }
00464         else
00465         {
00466             /*Codes_SRS_MAP_02_023: [Otherwise, Map_Delete shall remove the key and its associated value from the map and return MAP_OK.]*/
00467             size_t index = whereIsIt - handleData->keys;
00468             free(handleData->keys[index]);
00469             free(handleData->values[index]);
00470             memmove(handleData->keys + index, handleData->keys + index + 1, (handleData->count - index - 1)*sizeof(char*)); /*if order doesn't matter... then this can be optimized*/
00471             memmove(handleData->values + index, handleData->values + index + 1, (handleData->count - index - 1)*sizeof(char*));
00472             Map_DecreaseStorageKeysValues(handleData);
00473             result = MAP_OK;
00474         }
00475 
00476     }
00477     return result;
00478 }
00479 
00480 MAP_RESULT Map_ContainsKey(MAP_HANDLE handle, const char* key, bool* keyExists)
00481 {
00482     MAP_RESULT result;
00483     /*Codes_SRS_MAP_02_024: [If parameter handle, key or keyExists are NULL then Map_ContainsKey shall return MAP_INVALIDARG.]*/
00484     if (
00485         (handle ==NULL) ||
00486         (key == NULL) ||
00487         (keyExists == NULL)
00488         )
00489     {
00490         result = MAP_INVALIDARG;
00491         LOG_MAP_ERROR;
00492     }
00493     else
00494     {
00495         MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
00496         /*Codes_SRS_MAP_02_025: [Otherwise if a key exists then Map_ContainsKey shall return MAP_OK and shall write in keyExists "true".]*/
00497         /*Codes_SRS_MAP_02_026: [If a key doesn't exist, then Map_ContainsKey shall return MAP_OK and write in keyExists "false".] */
00498         *keyExists = (findKey(handleData, key) != NULL) ? true: false;
00499         result = MAP_OK;
00500     }
00501     return result;
00502 }
00503 
00504 MAP_RESULT Map_ContainsValue(MAP_HANDLE handle, const char* value, bool* valueExists)
00505 {
00506     MAP_RESULT result;
00507     /*Codes_SRS_MAP_02_027: [If parameter handle, value or valueExists is NULL then Map_ContainsValue shall return MAP_INVALIDARG.] */
00508     if (
00509         (handle == NULL) ||
00510         (value == NULL) ||
00511         (valueExists == NULL)
00512         )
00513     {
00514         result = MAP_INVALIDARG;
00515         LOG_MAP_ERROR;
00516     }
00517     else
00518     {
00519         MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA*)handle;
00520         /*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".]*/
00521         /*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".] */
00522         *valueExists = (findValue(handleData, value) != NULL) ? true : false;
00523         result = MAP_OK;
00524     }
00525     return result;
00526 }
00527 
00528 const char* Map_GetValueFromKey(MAP_HANDLE handle, const char* key)
00529 {
00530     const char* result;
00531     /*Codes_SRS_MAP_02_040: [If parameter handle or key is NULL then Map_GetValueFromKey returns NULL.]*/
00532     if (
00533         (handle == NULL) ||
00534         (key == NULL)
00535         )
00536     {
00537         result = NULL;
00538         LogError("invalid parameter to Map_GetValueFromKey");
00539     }
00540     else
00541     {
00542         MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle;
00543         char** whereIsIt = findKey(handleData, key);
00544         if(whereIsIt == NULL)
00545         {
00546             /*Codes_SRS_MAP_02_041: [If the key is not found, then Map_GetValueFromKey returns NULL.]*/
00547             result = NULL;
00548         }
00549         else
00550         {
00551             /*Codes_SRS_MAP_02_042: [Otherwise, Map_GetValueFromKey returns the key's value.] */
00552             size_t index = whereIsIt - handleData->keys;
00553             result = handleData->values[index];
00554         }
00555     }
00556     return result;
00557 }
00558 
00559 MAP_RESULT Map_GetInternals(MAP_HANDLE handle, const char*const** keys, const char*const** values, size_t* count)
00560 {
00561     MAP_RESULT result;
00562     /*Codes_SRS_MAP_02_046: [If parameter handle, keys, values or count is NULL then Map_GetInternals shall return MAP_INVALIDARG.] */
00563     if (
00564         (handle == NULL) ||
00565         (keys == NULL) ||
00566         (values == NULL) ||
00567         (count == NULL)
00568         )
00569     {
00570         result = MAP_INVALIDARG;
00571         LOG_MAP_ERROR;
00572     }
00573     else
00574     {
00575         /*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.]*/
00576         /*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.]*/
00577         /*Codes_SRS_MAP_02_045: [  Map_GetInternals shall produce in *count the number of stored keys and values.]*/
00578         MAP_HANDLE_DATA * handleData = (MAP_HANDLE_DATA *)handle;
00579         *keys =(const char* const*)(handleData->keys);
00580         *values = (const char* const*)(handleData->values);
00581         *count = handleData->count;
00582         result = MAP_OK;
00583     }
00584     return result;
00585 }
00586 
00587 STRING_HANDLE Map_ToJSON(MAP_HANDLE handle)
00588 {
00589     STRING_HANDLE result;
00590     /*Codes_SRS_MAP_02_052: [If parameter handle is NULL then Map_ToJSON shall return NULL.] */
00591     if (handle == NULL)
00592     {
00593         result = NULL;
00594         LogError("invalid arg (NULL)");
00595     }
00596     else
00597     {
00598         /*Codes_SRS_MAP_02_048: [Map_ToJSON shall produce a STRING_HANDLE representing the content of the MAP.] */
00599         result = STRING_construct("{");
00600         if (result == NULL)
00601         {
00602             LogError("STRING_construct failed");
00603         }
00604         else
00605         {
00606             size_t i;
00607             MAP_HANDLE_DATA* handleData = (MAP_HANDLE_DATA *)handle;
00608             /*Codes_SRS_MAP_02_049: [If the MAP is empty, then Map_ToJSON shall produce the string "{}".*/
00609             bool breakFor = false; /*used to break out of for*/
00610             for (i = 0; (i < handleData->count) && (!breakFor); i++)
00611             {
00612                 /*add one entry to the JSON*/
00613                 /*Codes_SRS_MAP_02_050: [If the map has properties then Map_ToJSON shall produce the following string:{"name1":"value1", "name2":"value2" ...}]*/
00614                 STRING_HANDLE key = STRING_new_JSON(handleData->keys[i]);
00615                 if (key == NULL)
00616                 {
00617                     LogError("STRING_new_JSON failed");
00618                     STRING_delete(result);
00619                     result = NULL;
00620                     breakFor = true;
00621                 }
00622                 else
00623                 {
00624                     STRING_HANDLE value = STRING_new_JSON(handleData->values[i]);
00625                     if (value == NULL)
00626                     {
00627                         LogError("STRING_new_JSON failed");
00628                         STRING_delete(result);
00629                         result = NULL;
00630                         breakFor = true;
00631                     }
00632                     else
00633                     {
00634                         if (!(
00635                             ((i>0) ? (STRING_concat(result, ",") == 0) : 1) &&
00636                             (STRING_concat_with_STRING(result, key) == 0) &&
00637                             (STRING_concat(result, ":") == 0) &&
00638                             (STRING_concat_with_STRING(result, value) == 0)
00639                             ))
00640                         {
00641                             LogError("failed to build the JSON");
00642                             STRING_delete(result);
00643                             result = NULL;
00644                             breakFor = true;
00645                         }
00646                         else
00647                         {
00648                             /*all nice, go to the next element in the map*/
00649                         }
00650                         STRING_delete(value);
00651                     }
00652                     STRING_delete(key);
00653                 }
00654             }
00655                 
00656             if (breakFor)
00657             {
00658                 LogError("error happened during JSON string builder");
00659             }
00660             else
00661             {
00662                 if (STRING_concat(result, "}") != 0)
00663                 {
00664                     LogError("failed to build the JSON");
00665                     STRING_delete(result);
00666                     result = NULL;
00667                 }
00668                 else
00669                 {
00670                     /*return as is, JSON has been build*/
00671                 }
00672             }
00673         }
00674     }
00675     return result;
00676 
00677 }