Azure IoT common library
Fork of azure_c_shared_utility by
optionhandler.c@7:1af47e3a19b6, 2016-07-29 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Fri Jul 29 16:01:07 2016 -0700
- Revision:
- 7:1af47e3a19b6
- Child:
- 19:2e0811512ceb
1.0.10
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AzureIoTClient | 7:1af47e3a19b6 | 1 | // Copyright (c) Microsoft. All rights reserved. |
AzureIoTClient | 7:1af47e3a19b6 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
AzureIoTClient | 7:1af47e3a19b6 | 3 | |
AzureIoTClient | 7:1af47e3a19b6 | 4 | #include "azure_c_shared_utility/optionhandler.h" |
AzureIoTClient | 7:1af47e3a19b6 | 5 | #include "azure_c_shared_utility/xlogging.h" |
AzureIoTClient | 7:1af47e3a19b6 | 6 | #include "azure_c_shared_utility/gballoc.h" |
AzureIoTClient | 7:1af47e3a19b6 | 7 | #include "azure_c_shared_utility/vector.h" |
AzureIoTClient | 7:1af47e3a19b6 | 8 | |
AzureIoTClient | 7:1af47e3a19b6 | 9 | typedef struct OPTION_TAG |
AzureIoTClient | 7:1af47e3a19b6 | 10 | { |
AzureIoTClient | 7:1af47e3a19b6 | 11 | const char* name; |
AzureIoTClient | 7:1af47e3a19b6 | 12 | void* storage; |
AzureIoTClient | 7:1af47e3a19b6 | 13 | }OPTION; |
AzureIoTClient | 7:1af47e3a19b6 | 14 | |
AzureIoTClient | 7:1af47e3a19b6 | 15 | typedef struct OPTIONHANDLER_HANDLE_DATA_TAG |
AzureIoTClient | 7:1af47e3a19b6 | 16 | { |
AzureIoTClient | 7:1af47e3a19b6 | 17 | pfCloneOption cloneOption; |
AzureIoTClient | 7:1af47e3a19b6 | 18 | pfDestroyOption destroyOption; |
AzureIoTClient | 7:1af47e3a19b6 | 19 | pfSetOption setOption; |
AzureIoTClient | 7:1af47e3a19b6 | 20 | VECTOR_HANDLE storage; |
AzureIoTClient | 7:1af47e3a19b6 | 21 | }OPTIONHANDLER_HANDLE_DATA; |
AzureIoTClient | 7:1af47e3a19b6 | 22 | |
AzureIoTClient | 7:1af47e3a19b6 | 23 | OPTIONHANDLER_HANDLE OptionHandler_Create(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption) |
AzureIoTClient | 7:1af47e3a19b6 | 24 | { |
AzureIoTClient | 7:1af47e3a19b6 | 25 | /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 26 | OPTIONHANDLER_HANDLE_DATA* result; |
AzureIoTClient | 7:1af47e3a19b6 | 27 | if ( |
AzureIoTClient | 7:1af47e3a19b6 | 28 | (cloneOption == NULL) || |
AzureIoTClient | 7:1af47e3a19b6 | 29 | (destroyOption == NULL) || |
AzureIoTClient | 7:1af47e3a19b6 | 30 | (setOption == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 31 | ) |
AzureIoTClient | 7:1af47e3a19b6 | 32 | { |
AzureIoTClient | 7:1af47e3a19b6 | 33 | LogError("invalid parameter = pfCloneOption cloneOption=%p, pfDestroyOption destroyOption=%p, pfSetOption setOption=%p", cloneOption, destroyOption, setOption); |
AzureIoTClient | 7:1af47e3a19b6 | 34 | result = NULL; |
AzureIoTClient | 7:1af47e3a19b6 | 35 | } |
AzureIoTClient | 7:1af47e3a19b6 | 36 | else |
AzureIoTClient | 7:1af47e3a19b6 | 37 | { |
AzureIoTClient | 7:1af47e3a19b6 | 38 | result = (OPTIONHANDLER_HANDLE_DATA*)malloc(sizeof(OPTIONHANDLER_HANDLE_DATA)); |
AzureIoTClient | 7:1af47e3a19b6 | 39 | if (result == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 40 | { |
AzureIoTClient | 7:1af47e3a19b6 | 41 | /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 42 | LogError("unable to malloc"); |
AzureIoTClient | 7:1af47e3a19b6 | 43 | /*return as is*/ |
AzureIoTClient | 7:1af47e3a19b6 | 44 | } |
AzureIoTClient | 7:1af47e3a19b6 | 45 | else |
AzureIoTClient | 7:1af47e3a19b6 | 46 | { |
AzureIoTClient | 7:1af47e3a19b6 | 47 | /*Codes_SRS_OPTIONHANDLER_02_002: [ OptionHandler_Create shall create an empty VECTOR that will hold pairs of const char* and void*. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 48 | result->storage = VECTOR_create(sizeof(OPTION)); |
AzureIoTClient | 7:1af47e3a19b6 | 49 | if (result->storage == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 50 | { |
AzureIoTClient | 7:1af47e3a19b6 | 51 | /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 52 | LogError("unable to VECTOR_create"); |
AzureIoTClient | 7:1af47e3a19b6 | 53 | free(result); |
AzureIoTClient | 7:1af47e3a19b6 | 54 | result= NULL; |
AzureIoTClient | 7:1af47e3a19b6 | 55 | } |
AzureIoTClient | 7:1af47e3a19b6 | 56 | else |
AzureIoTClient | 7:1af47e3a19b6 | 57 | { |
AzureIoTClient | 7:1af47e3a19b6 | 58 | /*Codes_SRS_OPTIONHANDLER_02_003: [ If all the operations succeed then OptionHandler_Create shall succeed and return a non-NULL handle. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 59 | result->cloneOption = cloneOption; |
AzureIoTClient | 7:1af47e3a19b6 | 60 | result->destroyOption = destroyOption; |
AzureIoTClient | 7:1af47e3a19b6 | 61 | result->setOption = setOption; |
AzureIoTClient | 7:1af47e3a19b6 | 62 | /*return as is*/ |
AzureIoTClient | 7:1af47e3a19b6 | 63 | } |
AzureIoTClient | 7:1af47e3a19b6 | 64 | } |
AzureIoTClient | 7:1af47e3a19b6 | 65 | } |
AzureIoTClient | 7:1af47e3a19b6 | 66 | return result; |
AzureIoTClient | 7:1af47e3a19b6 | 67 | |
AzureIoTClient | 7:1af47e3a19b6 | 68 | } |
AzureIoTClient | 7:1af47e3a19b6 | 69 | |
AzureIoTClient | 7:1af47e3a19b6 | 70 | OPTIONHANDLER_RESULT OptionHandler_AddOption(OPTIONHANDLER_HANDLE handle, const char* name, const void* value) |
AzureIoTClient | 7:1af47e3a19b6 | 71 | { |
AzureIoTClient | 7:1af47e3a19b6 | 72 | OPTIONHANDLER_RESULT result; |
AzureIoTClient | 7:1af47e3a19b6 | 73 | /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 74 | if ( |
AzureIoTClient | 7:1af47e3a19b6 | 75 | (handle == NULL) || |
AzureIoTClient | 7:1af47e3a19b6 | 76 | (name == NULL) || |
AzureIoTClient | 7:1af47e3a19b6 | 77 | (value == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 78 | ) |
AzureIoTClient | 7:1af47e3a19b6 | 79 | { |
AzureIoTClient | 7:1af47e3a19b6 | 80 | LogError("invalid arguments: OPTIONHANDLER_HANDLE handle=%p, const char* name=%p, void* value=%p", handle, name, value); |
AzureIoTClient | 7:1af47e3a19b6 | 81 | result= OPTIONHANDLER_INVALIDARG; |
AzureIoTClient | 7:1af47e3a19b6 | 82 | } |
AzureIoTClient | 7:1af47e3a19b6 | 83 | else |
AzureIoTClient | 7:1af47e3a19b6 | 84 | { |
AzureIoTClient | 7:1af47e3a19b6 | 85 | const char* cloneOfName; |
AzureIoTClient | 7:1af47e3a19b6 | 86 | if (mallocAndStrcpy_s((char**)&cloneOfName, name) != 0) |
AzureIoTClient | 7:1af47e3a19b6 | 87 | { |
AzureIoTClient | 7:1af47e3a19b6 | 88 | /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 89 | LogError("unable to clone name"); |
AzureIoTClient | 7:1af47e3a19b6 | 90 | result = OPTIONHANDLER_ERROR; |
AzureIoTClient | 7:1af47e3a19b6 | 91 | } |
AzureIoTClient | 7:1af47e3a19b6 | 92 | else |
AzureIoTClient | 7:1af47e3a19b6 | 93 | { |
AzureIoTClient | 7:1af47e3a19b6 | 94 | /*Codes_SRS_OPTIONHANDLER_02_006: [ OptionHandler_AddProperty shall call pfCloneOption passing name and value. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 95 | void* cloneOfValue = handle->cloneOption(name, value); |
AzureIoTClient | 7:1af47e3a19b6 | 96 | if (cloneOfValue == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 97 | { |
AzureIoTClient | 7:1af47e3a19b6 | 98 | /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 99 | LogError("unable to clone value"); |
AzureIoTClient | 7:1af47e3a19b6 | 100 | free((void*)cloneOfName); |
AzureIoTClient | 7:1af47e3a19b6 | 101 | result = OPTIONHANDLER_ERROR; |
AzureIoTClient | 7:1af47e3a19b6 | 102 | } |
AzureIoTClient | 7:1af47e3a19b6 | 103 | else |
AzureIoTClient | 7:1af47e3a19b6 | 104 | { |
AzureIoTClient | 7:1af47e3a19b6 | 105 | OPTION temp; |
AzureIoTClient | 7:1af47e3a19b6 | 106 | temp.name = cloneOfName; |
AzureIoTClient | 7:1af47e3a19b6 | 107 | temp.storage = cloneOfValue; |
AzureIoTClient | 7:1af47e3a19b6 | 108 | /*Codes_SRS_OPTIONHANDLER_02_007: [ OptionHandler_AddProperty shall use VECTOR APIs to save the name and the newly created clone of value. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 109 | if (VECTOR_push_back(handle->storage, &temp, 1) != 0) |
AzureIoTClient | 7:1af47e3a19b6 | 110 | { |
AzureIoTClient | 7:1af47e3a19b6 | 111 | /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 112 | LogError("unable to VECTOR_push_back"); |
AzureIoTClient | 7:1af47e3a19b6 | 113 | handle->destroyOption(name, cloneOfValue); |
AzureIoTClient | 7:1af47e3a19b6 | 114 | free((void*)cloneOfName); |
AzureIoTClient | 7:1af47e3a19b6 | 115 | result = OPTIONHANDLER_ERROR; |
AzureIoTClient | 7:1af47e3a19b6 | 116 | } |
AzureIoTClient | 7:1af47e3a19b6 | 117 | else |
AzureIoTClient | 7:1af47e3a19b6 | 118 | { |
AzureIoTClient | 7:1af47e3a19b6 | 119 | /*Codes_SRS_OPTIONHANDLER_02_008: [ If all the operations succed then OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_OK. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 120 | result = OPTIONHANDLER_OK; |
AzureIoTClient | 7:1af47e3a19b6 | 121 | } |
AzureIoTClient | 7:1af47e3a19b6 | 122 | } |
AzureIoTClient | 7:1af47e3a19b6 | 123 | } |
AzureIoTClient | 7:1af47e3a19b6 | 124 | } |
AzureIoTClient | 7:1af47e3a19b6 | 125 | return result; |
AzureIoTClient | 7:1af47e3a19b6 | 126 | } |
AzureIoTClient | 7:1af47e3a19b6 | 127 | |
AzureIoTClient | 7:1af47e3a19b6 | 128 | OPTIONHANDLER_RESULT OptionHandler_FeedOptions(OPTIONHANDLER_HANDLE handle, void* destinationHandle) |
AzureIoTClient | 7:1af47e3a19b6 | 129 | { |
AzureIoTClient | 7:1af47e3a19b6 | 130 | OPTIONHANDLER_RESULT result; |
AzureIoTClient | 7:1af47e3a19b6 | 131 | /*Codes_SRS_OPTIONHANDLER_02_010: [ OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_INVALIDARG if any argument is NULL. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 132 | if ( |
AzureIoTClient | 7:1af47e3a19b6 | 133 | (handle == NULL) || |
AzureIoTClient | 7:1af47e3a19b6 | 134 | (destinationHandle == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 135 | ) |
AzureIoTClient | 7:1af47e3a19b6 | 136 | { |
AzureIoTClient | 7:1af47e3a19b6 | 137 | LogError("invalid arguments OPTIONHANDLER_HANDLE handle=%p, void* destinationHandle=%p", handle, destinationHandle); |
AzureIoTClient | 7:1af47e3a19b6 | 138 | result = OPTIONHANDLER_INVALIDARG; |
AzureIoTClient | 7:1af47e3a19b6 | 139 | } |
AzureIoTClient | 7:1af47e3a19b6 | 140 | else |
AzureIoTClient | 7:1af47e3a19b6 | 141 | { |
AzureIoTClient | 7:1af47e3a19b6 | 142 | /*Codes_SRS_OPTIONHANDLER_02_011: [ Otherwise, OptionHandler_FeedOptions shall use VECTOR's iteration mechanisms to retrieve pairs of name, value (const char* and void*). ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 143 | size_t nOptions = VECTOR_size(handle->storage), i; |
AzureIoTClient | 7:1af47e3a19b6 | 144 | for (i = 0;i < nOptions;i++) |
AzureIoTClient | 7:1af47e3a19b6 | 145 | { |
AzureIoTClient | 7:1af47e3a19b6 | 146 | OPTION* option = (OPTION*)VECTOR_element(handle->storage, i); |
AzureIoTClient | 7:1af47e3a19b6 | 147 | /*Codes_SRS_OPTIONHANDLER_02_012: [ OptionHandler_FeedOptions shall call for every pair of name,value setOption passing destinationHandle, name and value. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 148 | if (handle->setOption(destinationHandle, option->name, option->storage) != 0) |
AzureIoTClient | 7:1af47e3a19b6 | 149 | { |
AzureIoTClient | 7:1af47e3a19b6 | 150 | LogError("failure while trying to _SetOption"); |
AzureIoTClient | 7:1af47e3a19b6 | 151 | break; |
AzureIoTClient | 7:1af47e3a19b6 | 152 | } |
AzureIoTClient | 7:1af47e3a19b6 | 153 | } |
AzureIoTClient | 7:1af47e3a19b6 | 154 | |
AzureIoTClient | 7:1af47e3a19b6 | 155 | if (i == nOptions) |
AzureIoTClient | 7:1af47e3a19b6 | 156 | { |
AzureIoTClient | 7:1af47e3a19b6 | 157 | /*Codes_SRS_OPTIONHANDLER_02_014: [ Otherwise, OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_ERROR. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 158 | result = OPTIONHANDLER_OK; |
AzureIoTClient | 7:1af47e3a19b6 | 159 | } |
AzureIoTClient | 7:1af47e3a19b6 | 160 | else |
AzureIoTClient | 7:1af47e3a19b6 | 161 | { |
AzureIoTClient | 7:1af47e3a19b6 | 162 | /*Codes_SRS_OPTIONHANDLER_02_013: [ If all the operations succeed then OptionHandler_FeedOptions shall succeed and return OPTIONHANDLER_OK. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 163 | result = OPTIONHANDLER_ERROR; |
AzureIoTClient | 7:1af47e3a19b6 | 164 | } |
AzureIoTClient | 7:1af47e3a19b6 | 165 | } |
AzureIoTClient | 7:1af47e3a19b6 | 166 | return result; |
AzureIoTClient | 7:1af47e3a19b6 | 167 | } |
AzureIoTClient | 7:1af47e3a19b6 | 168 | |
AzureIoTClient | 7:1af47e3a19b6 | 169 | void OptionHandler_Destroy(OPTIONHANDLER_HANDLE handle) |
AzureIoTClient | 7:1af47e3a19b6 | 170 | { |
AzureIoTClient | 7:1af47e3a19b6 | 171 | /*Codes_SRS_OPTIONHANDLER_02_015: [ OptionHandler_Destroy shall do nothing if parameter handle is NULL. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 172 | if (handle == NULL) |
AzureIoTClient | 7:1af47e3a19b6 | 173 | { |
AzureIoTClient | 7:1af47e3a19b6 | 174 | LogError("invalid argument OPTIONHANDLER_HANDLE handle=%p", handle); |
AzureIoTClient | 7:1af47e3a19b6 | 175 | } |
AzureIoTClient | 7:1af47e3a19b6 | 176 | else |
AzureIoTClient | 7:1af47e3a19b6 | 177 | { |
AzureIoTClient | 7:1af47e3a19b6 | 178 | /*Codes_SRS_OPTIONHANDLER_02_016: [ Otherwise, OptionHandler_Destroy shall free all used resources. ]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 179 | size_t nOptions = VECTOR_size(handle->storage), i; |
AzureIoTClient | 7:1af47e3a19b6 | 180 | for (i = 0;i < nOptions;i++) |
AzureIoTClient | 7:1af47e3a19b6 | 181 | { |
AzureIoTClient | 7:1af47e3a19b6 | 182 | OPTION* option = (OPTION*)VECTOR_element(handle->storage, i); |
AzureIoTClient | 7:1af47e3a19b6 | 183 | handle->destroyOption(option->name, option->storage); |
AzureIoTClient | 7:1af47e3a19b6 | 184 | free((void*)option->name); |
AzureIoTClient | 7:1af47e3a19b6 | 185 | } |
AzureIoTClient | 7:1af47e3a19b6 | 186 | |
AzureIoTClient | 7:1af47e3a19b6 | 187 | VECTOR_destroy(handle->storage); |
AzureIoTClient | 7:1af47e3a19b6 | 188 | free(handle); |
AzureIoTClient | 7:1af47e3a19b6 | 189 | } |
AzureIoTClient | 7:1af47e3a19b6 | 190 | } |