source: azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/optionhandler.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.2 KB
Line 
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#include <stdlib.h>
5#include "azure_c_shared_utility/optionhandler.h"
6#include "azure_c_shared_utility/xlogging.h"
7#include "azure_c_shared_utility/gballoc.h"
8#include "azure_c_shared_utility/vector.h"
9
10typedef struct OPTION_TAG
11{
12 const char* name;
13 void* storage;
14}OPTION;
15
16typedef struct OPTIONHANDLER_HANDLE_DATA_TAG
17{
18 pfCloneOption cloneOption;
19 pfDestroyOption destroyOption;
20 pfSetOption setOption;
21 VECTOR_HANDLE storage;
22}OPTIONHANDLER_HANDLE_DATA;
23
24static OPTIONHANDLER_HANDLE CreateInternal(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption)
25{
26 OPTIONHANDLER_HANDLE result;
27
28 result = (OPTIONHANDLER_HANDLE_DATA*)malloc(sizeof(OPTIONHANDLER_HANDLE_DATA));
29 if (result == NULL)
30 {
31 /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/
32 LogError("unable to malloc");
33 /*return as is*/
34 }
35 else
36 {
37 /*Codes_SRS_OPTIONHANDLER_02_002: [ OptionHandler_Create shall create an empty VECTOR that will hold pairs of const char* and void*. ]*/
38 result->storage = VECTOR_create(sizeof(OPTION));
39 if (result->storage == NULL)
40 {
41 /*Codes_SRS_OPTIONHANDLER_02_004: [ Otherwise, OptionHandler_Create shall fail and return NULL. ]*/
42 LogError("unable to VECTOR_create");
43 free(result);
44 result = NULL;
45 }
46 else
47 {
48 /*Codes_SRS_OPTIONHANDLER_02_003: [ If all the operations succeed then OptionHandler_Create shall succeed and return a non-NULL handle. ]*/
49 result->cloneOption = cloneOption;
50 result->destroyOption = destroyOption;
51 result->setOption = setOption;
52 /*return as is*/
53 }
54 }
55
56 return result;
57}
58
59static OPTIONHANDLER_RESULT AddOptionInternal(OPTIONHANDLER_HANDLE handle, const char* name, const void* value)
60{
61 OPTIONHANDLER_RESULT result;
62 const char* cloneOfName;
63 if (mallocAndStrcpy_s((char**)&cloneOfName, name) != 0)
64 {
65 /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
66 LogError("unable to clone name");
67 result = OPTIONHANDLER_ERROR;
68 }
69 else
70 {
71 /*Codes_SRS_OPTIONHANDLER_02_006: [ OptionHandler_AddProperty shall call pfCloneOption passing name and value. ]*/
72 void* cloneOfValue = handle->cloneOption(name, value);
73 if (cloneOfValue == NULL)
74 {
75 /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
76 LogError("unable to clone value");
77 free((void*)cloneOfName);
78 result = OPTIONHANDLER_ERROR;
79 }
80 else
81 {
82 OPTION temp;
83 temp.name = cloneOfName;
84 temp.storage = cloneOfValue;
85 /*Codes_SRS_OPTIONHANDLER_02_007: [ OptionHandler_AddProperty shall use VECTOR APIs to save the name and the newly created clone of value. ]*/
86 if (VECTOR_push_back(handle->storage, &temp, 1) != 0)
87 {
88 /*Codes_SRS_OPTIONHANDLER_02_009: [ Otherwise, OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_ERROR. ]*/
89 LogError("unable to VECTOR_push_back");
90 handle->destroyOption(name, cloneOfValue);
91 free((void*)cloneOfName);
92 result = OPTIONHANDLER_ERROR;
93 }
94 else
95 {
96 /*Codes_SRS_OPTIONHANDLER_02_008: [ If all the operations succed then OptionHandler_AddProperty shall succeed and return OPTIONHANDLER_OK. ]*/
97 result = OPTIONHANDLER_OK;
98 }
99 }
100 }
101
102 return result;
103}
104
105static void DestroyInternal(OPTIONHANDLER_HANDLE handle)
106{
107 /*Codes_SRS_OPTIONHANDLER_02_016: [ Otherwise, OptionHandler_Destroy shall free all used resources. ]*/
108 size_t nOptions = VECTOR_size(handle->storage), i;
109 for (i = 0; i < nOptions; i++)
110 {
111 OPTION* option = (OPTION*)VECTOR_element(handle->storage, i);
112 handle->destroyOption(option->name, option->storage);
113 free((void*)option->name);
114 }
115
116 VECTOR_destroy(handle->storage);
117 free(handle);
118}
119
120OPTIONHANDLER_HANDLE OptionHandler_Create(pfCloneOption cloneOption, pfDestroyOption destroyOption, pfSetOption setOption)
121{
122 /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/
123 OPTIONHANDLER_HANDLE_DATA* result;
124 if (
125 (cloneOption == NULL) ||
126 (destroyOption == NULL) ||
127 (setOption == NULL)
128 )
129 {
130 LogError("invalid parameter = pfCloneOption cloneOption=%p, pfDestroyOption destroyOption=%p, pfSetOption setOption=%p", cloneOption, destroyOption, setOption);
131 result = NULL;
132 }
133 else
134 {
135 result = CreateInternal(cloneOption, destroyOption, setOption);
136 }
137
138 return result;
139
140}
141
142OPTIONHANDLER_HANDLE OptionHandler_Clone(OPTIONHANDLER_HANDLE handler)
143{
144 OPTIONHANDLER_HANDLE_DATA* result;
145
146 if (handler == NULL)
147 {
148 /* Codes_SRS_OPTIONHANDLER_01_010: [ If handler is NULL, OptionHandler_Clone shall fail and return NULL. ]*/
149 LogError("NULL argument: handler");
150 result = NULL;
151 }
152 else
153 {
154 /* Codes_SRS_OPTIONHANDLER_01_001: [ OptionHandler_Clone shall clone an existing option handler instance. ]*/
155 /* Codes_SRS_OPTIONHANDLER_01_002: [ On success it shall return a non-NULL handle. ]*/
156 /* Codes_SRS_OPTIONHANDLER_01_003: [ OptionHandler_Clone shall allocate memory for the new option handler instance. ]*/
157 result = CreateInternal(handler->cloneOption, handler->destroyOption, handler->setOption);
158 if (result == NULL)
159 {
160 /* Codes_SRS_OPTIONHANDLER_01_004: [ If allocating memory fails, OptionHandler_Clone shall return NULL. ]*/
161 LogError("unable to create option handler");
162 }
163 else
164 {
165 /* 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. ]*/
166 size_t option_count = VECTOR_size(handler->storage);
167 size_t i;
168
169 for (i = 0; i < option_count; i++)
170 {
171 OPTION* option = (OPTION*)VECTOR_element(handler->storage, i);
172
173 /* Codes_SRS_OPTIONHANDLER_01_006: [ For each option the option name shall be cloned by calling mallocAndStrcpy_s. ]*/
174 /* 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. ]*/
175 if (AddOptionInternal(result, option->name, option->storage) != OPTIONHANDLER_OK)
176 {
177 /* Codes_SRS_OPTIONHANDLER_01_008: [ If cloning one of the option names fails, OptionHandler_Clone shall return NULL. ]*/
178 /* Codes_SRS_OPTIONHANDLER_01_009: [ If cloning one of the option values fails, OptionHandler_Clone shall return NULL. ]*/
179 LogError("Error cloning option %s", option->name);
180 break;
181 }
182 }
183
184 if (i < option_count)
185 {
186 DestroyInternal(result);
187 result = NULL;
188 }
189 }
190 }
191
192 return result;
193}
194
195OPTIONHANDLER_RESULT OptionHandler_AddOption(OPTIONHANDLER_HANDLE handle, const char* name, const void* value)
196{
197 OPTIONHANDLER_RESULT result;
198 /*Codes_SRS_OPTIONHANDLER_02_001: [ OptionHandler_Create shall fail and retun NULL if any parameters are NULL. ]*/
199 if (
200 (handle == NULL) ||
201 (name == NULL) ||
202 (value == NULL)
203 )
204 {
205 LogError("invalid arguments: OPTIONHANDLER_HANDLE handle=%p, const char* name=%p, void* value=%p", handle, name, value);
206 result= OPTIONHANDLER_INVALIDARG;
207 }
208 else
209 {
210 result = AddOptionInternal(handle, name, value);
211 }
212
213 return result;
214}
215
216OPTIONHANDLER_RESULT OptionHandler_FeedOptions(OPTIONHANDLER_HANDLE handle, void* destinationHandle)
217{
218 OPTIONHANDLER_RESULT result;
219 /*Codes_SRS_OPTIONHANDLER_02_010: [ OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_INVALIDARG if any argument is NULL. ]*/
220 if (
221 (handle == NULL) ||
222 (destinationHandle == NULL)
223 )
224 {
225 LogError("invalid arguments OPTIONHANDLER_HANDLE handle=%p, void* destinationHandle=%p", handle, destinationHandle);
226 result = OPTIONHANDLER_INVALIDARG;
227 }
228 else
229 {
230 /*Codes_SRS_OPTIONHANDLER_02_011: [ Otherwise, OptionHandler_FeedOptions shall use VECTOR's iteration mechanisms to retrieve pairs of name, value (const char* and void*). ]*/
231 size_t nOptions = VECTOR_size(handle->storage), i;
232 for (i = 0;i < nOptions;i++)
233 {
234 OPTION* option = (OPTION*)VECTOR_element(handle->storage, i);
235 /*Codes_SRS_OPTIONHANDLER_02_012: [ OptionHandler_FeedOptions shall call for every pair of name,value setOption passing destinationHandle, name and value. ]*/
236 if (handle->setOption(destinationHandle, option->name, option->storage) != 0)
237 {
238 LogError("failure while trying to SetOption with option %s", option->name);
239 break;
240 }
241 }
242
243 if (i == nOptions)
244 {
245 /*Codes_SRS_OPTIONHANDLER_02_014: [ Otherwise, OptionHandler_FeedOptions shall fail and return OPTIONHANDLER_ERROR. ]*/
246 result = OPTIONHANDLER_OK;
247 }
248 else
249 {
250 /*Codes_SRS_OPTIONHANDLER_02_013: [ If all the operations succeed then OptionHandler_FeedOptions shall succeed and return OPTIONHANDLER_OK. ]*/
251 result = OPTIONHANDLER_ERROR;
252 }
253 }
254 return result;
255}
256
257void OptionHandler_Destroy(OPTIONHANDLER_HANDLE handle)
258{
259 /*Codes_SRS_OPTIONHANDLER_02_015: [ OptionHandler_Destroy shall do nothing if parameter handle is NULL. ]*/
260 if (handle == NULL)
261 {
262 LogError("invalid argument OPTIONHANDLER_HANDLE handle=%p", handle);
263 }
264 else
265 {
266 DestroyInternal(handle);
267 }
268}
Note: See TracBrowser for help on using the repository browser.