Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Revision:
7:1af47e3a19b6
Child:
19:2e0811512ceb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/optionhandler.c	Fri Jul 29 16:01:07 2016 -0700
@@ -0,0 +1,190 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "azure_c_shared_utility/optionhandler.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/vector.h"
+
+typedef struct OPTION_TAG
+{
+    const char* name;
+    void* storage;
+}OPTION;
+
+typedef struct OPTIONHANDLER_HANDLE_DATA_TAG
+{
+    pfCloneOption cloneOption;
+    pfDestroyOption destroyOption;
+    pfSetOption setOption;
+    VECTOR_HANDLE storage;
+}OPTIONHANDLER_HANDLE_DATA;
+
+OPTIONHANDLER_HANDLE OptionHandler_Create(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption)
+{
+    /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/
+    OPTIONHANDLER_HANDLE_DATA* result;
+    if (
+        (cloneOption == NULL) ||
+        (destroyOption == NULL) ||
+        (setOption == NULL)
+        )
+    {
+        LogError("invalid parameter = pfCloneOption cloneOption=%p, pfDestroyOption destroyOption=%p, pfSetOption setOption=%p", cloneOption, destroyOption, setOption);
+        result = NULL;
+    }
+    else
+    {
+        result = (OPTIONHANDLER_HANDLE_DATA*)malloc(sizeof(OPTIONHANDLER_HANDLE_DATA));
+        if (result == NULL)
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/
+            LogError("unable to malloc");
+            /*return as is*/
+        }
+        else
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_002: [ OptionHandler_Create shall create an empty VECTOR that will hold pairs of const char* and void*. ]*/
+            result->storage = VECTOR_create(sizeof(OPTION));
+            if (result->storage == NULL)
+            {
+                /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/
+                LogError("unable to VECTOR_create");
+                free(result);
+                result= NULL;
+            }
+            else
+            {
+                /*Codes_SRS_OPTIONHANDLER_02_003: [ If all the operations succeed then OptionHandler_Create shall succeed and return a non-NULL handle. ]*/
+                result->cloneOption = cloneOption;
+                result->destroyOption = destroyOption;
+                result->setOption = setOption;
+                /*return as is*/
+            }
+        }
+    }
+    return result;
+
+}
+
+OPTIONHANDLER_RESULT OptionHandler_AddOption(OPTIONHANDLER_HANDLE handle, const char* name, const void* value)
+{
+    OPTIONHANDLER_RESULT result;
+    /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/
+    if (
+        (handle == NULL) ||
+        (name == NULL) ||
+        (value == NULL)
+        )
+    {
+        LogError("invalid arguments: OPTIONHANDLER_HANDLE handle=%p, const char* name=%p, void* value=%p", handle, name, value);
+        result= OPTIONHANDLER_INVALIDARG;
+    }
+    else
+    {
+        const char* cloneOfName;
+        if (mallocAndStrcpy_s((char**)&cloneOfName, name) != 0)
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
+            LogError("unable to clone name");
+            result = OPTIONHANDLER_ERROR;
+        }
+        else 
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_006: [ OptionHandler_AddProperty shall call pfCloneOption passing name and value. ]*/
+            void* cloneOfValue = handle->cloneOption(name, value);
+            if (cloneOfValue == NULL)
+            {
+                /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
+                LogError("unable to clone value");
+                free((void*)cloneOfName);
+                result = OPTIONHANDLER_ERROR;
+            }
+            else
+            {
+                OPTION temp;
+                temp.name = cloneOfName;
+                temp.storage = cloneOfValue;
+                /*Codes_SRS_OPTIONHANDLER_02_007: [ OptionHandler_AddProperty shall use VECTOR APIs to save the name and the newly created clone of value. ]*/
+                if (VECTOR_push_back(handle->storage, &temp, 1) != 0)
+                {
+                    /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
+                    LogError("unable to VECTOR_push_back");
+                    handle->destroyOption(name, cloneOfValue);
+                    free((void*)cloneOfName);
+                    result = OPTIONHANDLER_ERROR;
+                }
+                else
+                {
+                    /*Codes_SRS_OPTIONHANDLER_02_008: [ If all the operations succed then OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_OK. ]*/
+                    result = OPTIONHANDLER_OK;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+OPTIONHANDLER_RESULT OptionHandler_FeedOptions(OPTIONHANDLER_HANDLE handle, void* destinationHandle)
+{
+    OPTIONHANDLER_RESULT result;
+    /*Codes_SRS_OPTIONHANDLER_02_010: [ OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_INVALIDARG if any argument is NULL. ]*/
+    if (
+        (handle == NULL) ||
+        (destinationHandle == NULL)
+        )
+    {
+        LogError("invalid arguments OPTIONHANDLER_HANDLE handle=%p, void* destinationHandle=%p", handle, destinationHandle);
+        result = OPTIONHANDLER_INVALIDARG;
+    }
+    else
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_011: [ Otherwise, OptionHandler_FeedOptions shall use VECTOR's iteration mechanisms to retrieve pairs of name, value (const char* and void*). ]*/
+        size_t nOptions = VECTOR_size(handle->storage), i;
+        for (i = 0;i < nOptions;i++)
+        {
+            OPTION* option = (OPTION*)VECTOR_element(handle->storage, i);
+            /*Codes_SRS_OPTIONHANDLER_02_012: [ OptionHandler_FeedOptions shall call for every pair of name,value setOption passing destinationHandle, name and value. ]*/
+            if (handle->setOption(destinationHandle, option->name, option->storage) != 0)
+            {
+                LogError("failure while trying to _SetOption");
+                break;
+            }
+        }
+            
+        if (i == nOptions)
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_014: [ Otherwise, OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_ERROR. ]*/
+            result = OPTIONHANDLER_OK;
+        }
+        else
+        {
+            /*Codes_SRS_OPTIONHANDLER_02_013: [ If all the operations succeed then OptionHandler_FeedOptions shall succeed and return OPTIONHANDLER_OK. ]*/
+            result = OPTIONHANDLER_ERROR;
+        }
+    }
+    return result;
+}
+
+void OptionHandler_Destroy(OPTIONHANDLER_HANDLE handle)
+{   
+    /*Codes_SRS_OPTIONHANDLER_02_015: [ OptionHandler_Destroy shall do nothing if parameter handle is NULL. ]*/
+    if (handle == NULL)
+    {
+        LogError("invalid argument OPTIONHANDLER_HANDLE handle=%p", handle);
+    }
+    else
+    {
+        /*Codes_SRS_OPTIONHANDLER_02_016: [ Otherwise, OptionHandler_Destroy shall free all used resources. ]*/
+        size_t nOptions = VECTOR_size(handle->storage), i;
+        for (i = 0;i < nOptions;i++)
+        {
+            OPTION* option = (OPTION*)VECTOR_element(handle->storage, i);
+            handle->destroyOption(option->name, option->storage);
+            free((void*)option->name);
+        }
+
+        VECTOR_destroy(handle->storage);
+        free(handle);
+    }
+}