Azure IoT common library
Fork of azure_c_shared_utility by
Diff: xio.c
- Revision:
- 7:1af47e3a19b6
- Parent:
- 6:c55b013dfc2a
- Child:
- 19:2e0811512ceb
diff -r c55b013dfc2a -r 1af47e3a19b6 xio.c --- a/xio.c Fri Jul 01 10:43:23 2016 -0700 +++ b/xio.c Fri Jul 29 16:01:07 2016 -0700 @@ -9,6 +9,8 @@ #include "azure_c_shared_utility/gballoc.h" #include "azure_c_shared_utility/xio.h" +static const char* CONCRETE_OPTIONS = "concreteOptions"; + typedef struct XIO_INSTANCE_TAG { const IO_INTERFACE_DESCRIPTION* io_interface_description; @@ -21,6 +23,7 @@ /* Codes_SRS_XIO_01_003: [If the argument io_interface_description is NULL, xio_create shall return NULL.] */ if ((io_interface_description == NULL) || /* Codes_SRS_XIO_01_004: [If any io_interface_description member is NULL, xio_create shall return NULL.] */ + (io_interface_description->concrete_io_retrieveoptions == NULL) || (io_interface_description->concrete_io_create == NULL) || (io_interface_description->concrete_io_destroy == NULL) || (io_interface_description->concrete_io_open == NULL) || @@ -168,7 +171,7 @@ { int result; - /* Codes_SRS_XIO_03_030: [If the xio argumnent or the optionName argument is NULL, xio_setoption shall return a non-zero value.] */ + /* Codes_SRS_XIO_03_030: [If the xio argument or the optionName argument is NULL, xio_setoption shall return a non-zero value.] */ if (xio == NULL || optionName == NULL) { result = __LINE__; @@ -177,11 +180,125 @@ { XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; - /* Codes_SRS_XIO_003_028: [xio_setoption shall pass the optionName and value to the concrete IO implementation specified in xio_create by invoking the concrete_xio_setoption function.] */ - /* Codes_SRS_XIO_03_029: [xio_setoption shall return 0 upon success.] */ - /* Codes_SRS_XIO_03_031: [If the underlying concrete_xio_setoption fails, xio_setOption shall return a non-zero value.] */ - result = xio_instance->io_interface_description->concrete_io_setoption(xio_instance->concrete_xio_handle, optionName, value); + if (strcmp(CONCRETE_OPTIONS, optionName) == 0) + { + /*then value is a pointer to OPTIONHANDLER_HANDLE*/ + if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, xio_instance->concrete_xio_handle) != OPTIONHANDLER_OK) + { + LogError("unable to OptionHandler_FeedOptions"); + result = __LINE__; + } + else + { + result = 0; + } + } + else /*passthrough*/ + { + /* Codes_SRS_XIO_003_028: [xio_setoption shall pass the optionName and value to the concrete IO implementation specified in xio_create by invoking the concrete_xio_setoption function.] */ + /* Codes_SRS_XIO_03_029: [xio_setoption shall return 0 upon success.] */ + /* Codes_SRS_XIO_03_031: [If the underlying concrete_xio_setoption fails, xio_setOption shall return a non-zero value.] */ + result = xio_instance->io_interface_description->concrete_io_setoption(xio_instance->concrete_xio_handle, optionName, value); + } } return result; } + +static void* xio_CloneOption(const char* name, const void* value) +{ + void *result; + if ( + (name == NULL) || + (value == NULL) + ) + { + LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value); + result = NULL; + } + else + { + if (strcmp(name, CONCRETE_OPTIONS) == 0) + { + result = (void*)value; + } + else + { + LogError("unknown option: %s", name); + result = NULL; + } + } + return result; +} + + +static void xio_DestroyOption(const char* name, const void* value) +{ + if ( + (name == NULL) || + (value == NULL) + ) + { + LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value); + } + else + { + if (strcmp(name, CONCRETE_OPTIONS) == 0) + { + OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value); + } + else + { + LogError("unknown option: %s", name); + } + } +} + +OPTIONHANDLER_HANDLE xio_retrieveoptions(XIO_HANDLE xio) +{ + OPTIONHANDLER_HANDLE result; + + if (xio == NULL) + { + LogError("invalid argument detected: XIO_HANDLE xio=%p", xio); + result = NULL; + } + else + { + XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; + /*xio_retrieveoptions shall return a OPTIONHANDLER_HANDLE that has 1 option called "underlyingOptions" which is of type OPTIONHANDLER_HANDLE*/ + result = OptionHandler_Create(xio_CloneOption, xio_DestroyOption, (pfSetOption)xio_setoption); + if (result == NULL) + { + LogError("unable to OptionHandler_Create"); + /*return as is*/ + } + else + { + OPTIONHANDLER_HANDLE concreteOptions = xio_instance->io_interface_description->concrete_io_retrieveoptions(xio_instance->concrete_xio_handle); + if (concreteOptions == NULL) + { + LogError("unable to concrete_io_retrieveoptions"); + OptionHandler_Destroy(result); + result = NULL; + } + else + { + if (OptionHandler_AddOption(result, CONCRETE_OPTIONS, concreteOptions) != OPTIONHANDLER_OK) + { + LogError("unable to OptionHandler_AddOption"); + OptionHandler_Destroy(concreteOptions); + OptionHandler_Destroy(result); + result = NULL; + } + else + { + /*all is fine*/ + } + } + } + } + + return result; +} +