Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more
optionhandler.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/optionhandler.h" 00006 #include "azure_c_shared_utility/xlogging.h" 00007 #include "azure_c_shared_utility/gballoc.h" 00008 #include "azure_c_shared_utility/vector.h" 00009 00010 typedef struct OPTION_TAG 00011 { 00012 const char* name; 00013 void* storage; 00014 }OPTION; 00015 00016 typedef struct OPTIONHANDLER_HANDLE_DATA_TAG 00017 { 00018 pfCloneOption cloneOption; 00019 pfDestroyOption destroyOption; 00020 pfSetOption setOption; 00021 VECTOR_HANDLE storage; 00022 }OPTIONHANDLER_HANDLE_DATA; 00023 00024 static OPTIONHANDLER_HANDLE CreateInternal(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption) 00025 { 00026 OPTIONHANDLER_HANDLE result; 00027 00028 result = (OPTIONHANDLER_HANDLE_DATA*)malloc(sizeof(OPTIONHANDLER_HANDLE_DATA)); 00029 if (result == NULL) 00030 { 00031 /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/ 00032 LogError("unable to malloc"); 00033 /*return as is*/ 00034 } 00035 else 00036 { 00037 /*Codes_SRS_OPTIONHANDLER_02_002: [ OptionHandler_Create shall create an empty VECTOR that will hold pairs of const char* and void*. ]*/ 00038 result->storage = VECTOR_create(sizeof(OPTION)); 00039 if (result->storage == NULL) 00040 { 00041 /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/ 00042 LogError("unable to VECTOR_create"); 00043 free(result); 00044 result = NULL; 00045 } 00046 else 00047 { 00048 /*Codes_SRS_OPTIONHANDLER_02_003: [ If all the operations succeed then OptionHandler_Create shall succeed and return a non-NULL handle. ]*/ 00049 result->cloneOption = cloneOption; 00050 result->destroyOption = destroyOption; 00051 result->setOption = setOption; 00052 /*return as is*/ 00053 } 00054 } 00055 00056 return result; 00057 } 00058 00059 static OPTIONHANDLER_RESULT AddOptionInternal(OPTIONHANDLER_HANDLE handle, const char* name, const void* value) 00060 { 00061 OPTIONHANDLER_RESULT result; 00062 const char* cloneOfName; 00063 if (mallocAndStrcpy_s((char**)&cloneOfName, name) != 0) 00064 { 00065 /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/ 00066 LogError("unable to clone name"); 00067 result = OPTIONHANDLER_ERROR; 00068 } 00069 else 00070 { 00071 /*Codes_SRS_OPTIONHANDLER_02_006: [ OptionHandler_AddProperty shall call pfCloneOption passing name and value. ]*/ 00072 void* cloneOfValue = handle->cloneOption(name, value); 00073 if (cloneOfValue == NULL) 00074 { 00075 /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/ 00076 LogError("unable to clone value"); 00077 free((void*)cloneOfName); 00078 result = OPTIONHANDLER_ERROR; 00079 } 00080 else 00081 { 00082 OPTION temp; 00083 temp.name = cloneOfName; 00084 temp.storage = cloneOfValue; 00085 /*Codes_SRS_OPTIONHANDLER_02_007: [ OptionHandler_AddProperty shall use VECTOR APIs to save the name and the newly created clone of value. ]*/ 00086 if (VECTOR_push_back(handle->storage, &temp, 1) != 0) 00087 { 00088 /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/ 00089 LogError("unable to VECTOR_push_back"); 00090 handle->destroyOption(name, cloneOfValue); 00091 free((void*)cloneOfName); 00092 result = OPTIONHANDLER_ERROR; 00093 } 00094 else 00095 { 00096 /*Codes_SRS_OPTIONHANDLER_02_008: [ If all the operations succed then OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_OK. ]*/ 00097 result = OPTIONHANDLER_OK; 00098 } 00099 } 00100 } 00101 00102 return result; 00103 } 00104 00105 static void DestroyInternal(OPTIONHANDLER_HANDLE handle) 00106 { 00107 /*Codes_SRS_OPTIONHANDLER_02_016: [ Otherwise, OptionHandler_Destroy shall free all used resources. ]*/ 00108 size_t nOptions = VECTOR_size(handle->storage), i; 00109 for (i = 0; i < nOptions; i++) 00110 { 00111 OPTION* option = (OPTION*)VECTOR_element(handle->storage, i); 00112 handle->destroyOption(option->name, option->storage); 00113 free((void*)option->name); 00114 } 00115 00116 VECTOR_destroy(handle->storage); 00117 free(handle); 00118 } 00119 00120 OPTIONHANDLER_HANDLE OptionHandler_Create(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption) 00121 { 00122 /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/ 00123 OPTIONHANDLER_HANDLE_DATA* result; 00124 if ( 00125 (cloneOption == NULL) || 00126 (destroyOption == NULL) || 00127 (setOption == NULL) 00128 ) 00129 { 00130 LogError("invalid parameter = pfCloneOption cloneOption=%p, pfDestroyOption destroyOption=%p, pfSetOption setOption=%p", cloneOption, destroyOption, setOption); 00131 result = NULL; 00132 } 00133 else 00134 { 00135 result = CreateInternal(cloneOption, destroyOption, setOption); 00136 } 00137 00138 return result; 00139 00140 } 00141 00142 OPTIONHANDLER_HANDLE OptionHandler_Clone(OPTIONHANDLER_HANDLE handler) 00143 { 00144 OPTIONHANDLER_HANDLE_DATA* result; 00145 00146 if (handler == NULL) 00147 { 00148 /* Codes_SRS_OPTIONHANDLER_01_010: [ If `handler` is NULL, OptionHandler_Clone shall fail and return NULL. ]*/ 00149 LogError("NULL argument: handler"); 00150 result = NULL; 00151 } 00152 else 00153 { 00154 /* Codes_SRS_OPTIONHANDLER_01_001: [ `OptionHandler_Clone` shall clone an existing option handler instance. ]*/ 00155 /* Codes_SRS_OPTIONHANDLER_01_002: [ On success it shall return a non-NULL handle. ]*/ 00156 /* Codes_SRS_OPTIONHANDLER_01_003: [ `OptionHandler_Clone` shall allocate memory for the new option handler instance. ]*/ 00157 result = CreateInternal(handler->cloneOption, handler->destroyOption, handler->setOption); 00158 if (result == NULL) 00159 { 00160 /* Codes_SRS_OPTIONHANDLER_01_004: [ If allocating memory fails, `OptionHandler_Clone` shall return NULL. ]*/ 00161 LogError("unable to create option handler"); 00162 } 00163 else 00164 { 00165 /* Codes_SRS_OPTIONHANDLER_01_005: [ `OptionHandler_Clone` shall iterate through all the options stored by the option handler to be cloned by using VECTOR's iteration mechanism. ]*/ 00166 size_t option_count = VECTOR_size(handler->storage); 00167 size_t i; 00168 00169 for (i = 0; i < option_count; i++) 00170 { 00171 OPTION* option = (OPTION*)VECTOR_element(handler->storage, i); 00172 00173 /* Codes_SRS_OPTIONHANDLER_01_006: [ For each option the option name shall be cloned by calling `mallocAndStrcpy_s`. ]*/ 00174 /* Codes_SRS_OPTIONHANDLER_01_007: [ For each option the value shall be cloned by using the cloning function associated with the source option handler `handler`. ]*/ 00175 if (AddOptionInternal(result, option->name, option->storage) != OPTIONHANDLER_OK) 00176 { 00177 /* Codes_SRS_OPTIONHANDLER_01_008: [ If cloning one of the option names fails, `OptionHandler_Clone` shall return NULL. ]*/ 00178 /* Codes_SRS_OPTIONHANDLER_01_009: [ If cloning one of the option values fails, `OptionHandler_Clone` shall return NULL. ]*/ 00179 LogError("Error cloning option %s", option->name); 00180 break; 00181 } 00182 } 00183 00184 if (i < option_count) 00185 { 00186 DestroyInternal(result); 00187 result = NULL; 00188 } 00189 } 00190 } 00191 00192 return result; 00193 } 00194 00195 OPTIONHANDLER_RESULT OptionHandler_AddOption(OPTIONHANDLER_HANDLE handle, const char* name, const void* value) 00196 { 00197 OPTIONHANDLER_RESULT result; 00198 /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/ 00199 if ( 00200 (handle == NULL) || 00201 (name == NULL) || 00202 (value == NULL) 00203 ) 00204 { 00205 LogError("invalid arguments: OPTIONHANDLER_HANDLE handle=%p, const char* name=%p, void* value=%p", handle, name, value); 00206 result= OPTIONHANDLER_INVALIDARG; 00207 } 00208 else 00209 { 00210 result = AddOptionInternal(handle, name, value); 00211 } 00212 00213 return result; 00214 } 00215 00216 OPTIONHANDLER_RESULT OptionHandler_FeedOptions(OPTIONHANDLER_HANDLE handle, void* destinationHandle) 00217 { 00218 OPTIONHANDLER_RESULT result; 00219 /*Codes_SRS_OPTIONHANDLER_02_010: [ OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_INVALIDARG if any argument is NULL. ]*/ 00220 if ( 00221 (handle == NULL) || 00222 (destinationHandle == NULL) 00223 ) 00224 { 00225 LogError("invalid arguments OPTIONHANDLER_HANDLE handle=%p, void* destinationHandle=%p", handle, destinationHandle); 00226 result = OPTIONHANDLER_INVALIDARG; 00227 } 00228 else 00229 { 00230 /*Codes_SRS_OPTIONHANDLER_02_011: [ Otherwise, OptionHandler_FeedOptions shall use VECTOR's iteration mechanisms to retrieve pairs of name, value (const char* and void*). ]*/ 00231 size_t nOptions = VECTOR_size(handle->storage), i; 00232 for (i = 0;i < nOptions;i++) 00233 { 00234 OPTION* option = (OPTION*)VECTOR_element(handle->storage, i); 00235 /*Codes_SRS_OPTIONHANDLER_02_012: [ OptionHandler_FeedOptions shall call for every pair of name,value setOption passing destinationHandle, name and value. ]*/ 00236 if (handle->setOption(destinationHandle, option->name, option->storage) != 0) 00237 { 00238 LogError("failure while trying to _SetOption"); 00239 break; 00240 } 00241 } 00242 00243 if (i == nOptions) 00244 { 00245 /*Codes_SRS_OPTIONHANDLER_02_014: [ Otherwise, OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_ERROR. ]*/ 00246 result = OPTIONHANDLER_OK; 00247 } 00248 else 00249 { 00250 /*Codes_SRS_OPTIONHANDLER_02_013: [ If all the operations succeed then OptionHandler_FeedOptions shall succeed and return OPTIONHANDLER_OK. ]*/ 00251 result = OPTIONHANDLER_ERROR; 00252 } 00253 } 00254 return result; 00255 } 00256 00257 void OptionHandler_Destroy(OPTIONHANDLER_HANDLE handle) 00258 { 00259 /*Codes_SRS_OPTIONHANDLER_02_015: [ OptionHandler_Destroy shall do nothing if parameter handle is NULL. ]*/ 00260 if (handle == NULL) 00261 { 00262 LogError("invalid argument OPTIONHANDLER_HANDLE handle=%p", handle); 00263 } 00264 else 00265 { 00266 DestroyInternal(handle); 00267 } 00268 }
Generated on Wed Jul 13 2022 23:38:02 by
1.7.2
