Mark Radbourne / Mbed 2 deprecated iothub_client_sample_amqp

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

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