source: azure_iot_hub/trunk/azure_iothub/c-utility/src/vector.c@ 389

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

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 11.4 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/gballoc.h"
6#include "azure_c_shared_utility/vector.h"
7#include "azure_c_shared_utility/optimize_size.h"
8#include "azure_c_shared_utility/xlogging.h"
9
10#include "azure_c_shared_utility/vector_types_internal.h"
11
12VECTOR_HANDLE VECTOR_create(size_t elementSize)
13{
14 VECTOR_HANDLE result;
15
16 /* Codes_SRS_VECTOR_10_002: [VECTOR_create shall fail and return NULL if elementsize is 0.] */
17 if (elementSize == 0)
18 {
19 LogError("invalid elementSize(%zd).", elementSize);
20 result = NULL;
21 }
22 else
23 {
24 result = (VECTOR*)malloc(sizeof(VECTOR));
25 /* Codes_SRS_VECTOR_10_002 : [VECTOR_create shall fail and return NULL if malloc fails.] */
26 if (result == NULL)
27 {
28 LogError("malloc failed.");
29 }
30 else
31 {
32 /* Codes_SRS_VECTOR_10_001: [VECTOR_create shall allocate a VECTOR_HANDLE that will contain an empty vector.The size of each element is given with the parameter elementSize.] */
33 result->storage = NULL;
34 result->count = 0;
35 result->elementSize = elementSize;
36 }
37 }
38 return result;
39}
40
41void VECTOR_destroy(VECTOR_HANDLE handle)
42{
43 /* Codes_SRS_VECTOR_10_009: [VECTOR_destroy shall return if the given handle is NULL.] */
44 if (handle == NULL)
45 {
46 LogError("invalid argument handle(NULL).");
47 }
48 else
49 {
50 /* Codes_SRS_VECTOR_10_008: [VECTOR_destroy shall free the given handle and its internal storage.] */
51 free(handle->storage);
52 free(handle);
53 }
54}
55
56VECTOR_HANDLE VECTOR_move(VECTOR_HANDLE handle)
57{
58 VECTOR_HANDLE result;
59 if (handle == NULL)
60 {
61 /* Codes_SRS_VECTOR_10_005: [VECTOR_move shall fail and return NULL if the given handle is NULL.] */
62 LogError("invalid argument - handle(NULL).");
63 result = NULL;
64 }
65 else
66 {
67 result = (VECTOR*)malloc(sizeof(VECTOR));
68 if (result == NULL)
69 {
70 /* Codes_SRS_VECTOR_10_006: [VECTOR_move shall fail and return NULL if malloc fails.] */
71 LogError("malloc failed.");
72 }
73 else
74 {
75 /* Codes_SRS_VECTOR_10_004: [VECTOR_move shall allocate a VECTOR_HANDLE and move the data to it from the given handle.] */
76 result->count = handle->count;
77 result->elementSize = handle->elementSize;
78 result->storage = handle->storage;
79
80 handle->storage = NULL;
81 handle->count = 0;
82 }
83 }
84 return result;
85}
86
87/* insertion */
88
89int VECTOR_push_back(VECTOR_HANDLE handle, const void* elements, size_t numElements)
90{
91 int result;
92 if (handle == NULL || elements == NULL || numElements == 0)
93 {
94 /* Codes_SRS_VECTOR_10_011: [VECTOR_push_back shall fail and return non-zero if handle is NULL.] */
95 /* Codes_SRS_VECTOR_10_034: [VECTOR_push_back shall fail and return non-zero if elements is NULL.] */
96 /* Codes_SRS_VECTOR_10_035: [VECTOR_push_back shall fail and return non-zero if numElements is 0.] */
97 LogError("invalid argument - handle(%p), elements(%p), numElements(%zd).", handle, elements, numElements);
98 result = MU_FAILURE;
99 }
100 else
101 {
102 size_t curSize = handle->elementSize * handle->count;
103 size_t appendSize = handle->elementSize * numElements;
104
105 void* temp = realloc(handle->storage, curSize + appendSize);
106 if (temp == NULL)
107 {
108 /* Codes_SRS_VECTOR_10_012: [VECTOR_push_back shall fail and return non-zero if memory allocation fails.] */
109 LogError("realloc failed.");
110 result = MU_FAILURE;
111 }
112 else
113 {
114 /* Codes_SRS_VECTOR_10_013: [VECTOR_push_back shall append the given elements and return 0 indicating success.] */
115 (void)memcpy((unsigned char*)temp + curSize, elements, appendSize);
116 handle->storage = temp;
117 handle->count += numElements;
118 result = 0;
119 }
120 }
121 return result;
122}
123
124/* removal */
125
126void VECTOR_erase(VECTOR_HANDLE handle, void* elements, size_t numElements)
127{
128 if (handle == NULL || elements == NULL || numElements == 0)
129 {
130 /* Codes_SRS_VECTOR_10_015: [VECTOR_erase shall return if handle is NULL.] */
131 /* Codes_SRS_VECTOR_10_038: [VECTOR_erase shall return if elements is NULL.] */
132 /* Codes_SRS_VECTOR_10_039: [VECTOR_erase shall return if numElements is 0.] */
133 LogError("invalid argument - handle(%p), elements(%p), numElements(%zd).", handle, elements, numElements);
134 }
135 else
136 {
137 if (elements < handle->storage)
138 {
139 /* Codes_SRS_VECTOR_10_040: [VECTOR_erase shall return if elements is out of bound.] */
140 LogError("invalid argument elements(%p) is not a member of this object.", elements);
141 }
142 else
143 {
144 ptrdiff_t diff = ((unsigned char*)elements) - ((unsigned char*)handle->storage);
145 if ((diff % handle->elementSize) != 0)
146 {
147 /* Codes_SRS_VECTOR_10_041: [VECTOR_erase shall return if elements is misaligned.] */
148 LogError("invalid argument - elements(%p) is misaligned", elements);
149 }
150 else
151 {
152 /* Compute the arguments needed for memmove. */
153 unsigned char* src = (unsigned char*)elements + (handle->elementSize * numElements);
154 unsigned char* srcEnd = (unsigned char*)handle->storage + (handle->elementSize * handle->count);
155 if (src > srcEnd)
156 {
157 /* Codes_SRS_VECTOR_10_040: [VECTOR_erase shall return if elements is out of bound.] */
158 LogError("invalid argument - numElements(%zd) is out of bound.", numElements);
159 }
160 else
161 {
162 /* Codes_SRS_VECTOR_10_014: [VECTOR_erase shall remove the 'numElements' starting at 'elements' and reduce its internal storage.] */
163 handle->count -= numElements;
164 if (handle->count == 0)
165 {
166 free(handle->storage);
167 handle->storage = NULL;
168 }
169 else
170 {
171 void* tmp;
172 (void)memmove(elements, src, srcEnd - src);
173 tmp = realloc(handle->storage, (handle->elementSize * handle->count));
174 if (tmp == NULL)
175 {
176 LogInfo("realloc failed. Keeping original internal storage pointer.");
177 }
178 else
179 {
180 handle->storage = tmp;
181 }
182 }
183 }
184 }
185 }
186 }
187}
188
189void VECTOR_clear(VECTOR_HANDLE handle)
190{
191 /* Codes_SRS_VECTOR_10_017: [VECTOR_clear shall if the object is NULL or empty.] */
192 if (handle == NULL)
193 {
194 LogError("invalid argument handle(NULL).");
195 }
196 else
197 {
198 /* Codes_SRS_VECTOR_10_016: [VECTOR_clear shall remove all elements from the object and release internal storage.] */
199 free(handle->storage);
200 handle->storage = NULL;
201 handle->count = 0;
202 }
203}
204
205/* access */
206
207void* VECTOR_element(VECTOR_HANDLE handle, size_t index)
208{
209 void* result;
210 if (handle == NULL)
211 {
212 /* Codes_SRS_VECTOR_10_019: [VECTOR_element shall fail and return NULL if handle is NULL.] */
213 LogError("invalid argument handle(NULL).");
214 result = NULL;
215 }
216 else
217 {
218 if (index >= handle->count)
219 {
220 /* Codes_SRS_VECTOR_10_020: [VECTOR_element shall fail and return NULL if the given index is out of range.] */
221 LogError("invalid argument - index(%zd); should be >= 0 and < %zd.", index, handle->count);
222 result = NULL;
223 }
224 else
225 {
226 /* Codes_SRS_VECTOR_10_018: [VECTOR_element shall return the element at the given index.] */
227 result = (unsigned char*)handle->storage + (handle->elementSize * index);
228 }
229 }
230 return result;
231}
232
233void* VECTOR_front(VECTOR_HANDLE handle)
234{
235 void* result;
236 if (handle == NULL)
237 {
238 /* Codes_SRS_VECTOR_10_022: [VECTOR_front shall fail and return NULL if handle is NULL.] */
239 LogError("invalid argument handle (NULL).");
240 result = NULL;
241 }
242 else
243 {
244 if (handle->count == 0)
245 {
246 /* Codes_SRS_VECTOR_10_028: [VECTOR_front shall return NULL if the vector is empty.] */
247 LogError("vector is empty.");
248 result = NULL;
249 }
250 else
251 {
252 /* Codes_SRS_VECTOR_10_021: [VECTOR_front shall return a pointer to the element at index 0.] */
253 result = handle->storage;
254 }
255 }
256 return result;
257}
258
259void* VECTOR_back(VECTOR_HANDLE handle)
260{
261 void* result;
262 if (handle == NULL)
263 {
264 /* Codes_SRS_VECTOR_10_024: [VECTOR_back shall fail and return NULL if handle is NULL.] */
265 LogError("invalid argument handle (NULL).");
266 result = NULL;
267 }
268 else
269 {
270 if (handle->count == 0)
271 {
272 /* Codes_SRS_VECTOR_10_029: [VECTOR_back shall return NULL if the vector is empty.] */
273 LogError("vector is empty.");
274 result = NULL;
275 }
276 else
277 {
278 /* Codes_SRS_VECTOR_10_023: [VECTOR_front shall return the last element of the vector.] */
279 result = (unsigned char*)handle->storage + (handle->elementSize * (handle->count - 1));
280 }
281 }
282 return result;
283}
284
285void* VECTOR_find_if(VECTOR_HANDLE handle, PREDICATE_FUNCTION pred, const void* value)
286{
287 void* result;
288 if (handle == NULL || pred == NULL)
289 {
290 /* Codes_SRS_VECTOR_10_030: [VECTOR_find_if shall fail and return NULL if handle is NULL.] */
291 /* Codes_SRS_VECTOR_10_036: [VECTOR_find_if shall fail and return NULL if pred is NULL.] */
292 LogError("invalid argument - handle(%p), pred(%p)", handle, pred);
293 result = NULL;
294 }
295 else
296 {
297 size_t i;
298 for (i = 0; i < handle->count; ++i)
299 {
300 if (true == pred((unsigned char*)handle->storage + (handle->elementSize * i), value))
301 {
302 /* Codes_SRS_VECTOR_10_031: [VECTOR_find_if shall return the first element in the vector that matches pred.] */
303 break;
304 }
305 }
306
307 if (i == handle->count)
308 {
309 /* Codes_SRS_VECTOR_10_032: [VECTOR_find_if shall return NULL if no matching element is found.] */
310 result = NULL;
311 }
312 else
313 {
314 /* Codes_SRS_VECTOR_10_031: [VECTOR_find_if shall return the first element in the vector that matches pred.]*/
315 result = (unsigned char*)handle->storage + (handle->elementSize * i);
316 }
317 }
318 return result;
319}
320
321/* capacity */
322
323size_t VECTOR_size(VECTOR_HANDLE handle)
324{
325 size_t result;
326 if (handle == NULL)
327 {
328 /* Codes_SRS_VECTOR_10_026: [**VECTOR_size shall return 0 if the given handle is NULL.] */
329 LogError("invalid argument handle(NULL).");
330 result = 0;
331 }
332 else
333 {
334 /* Codes_SRS_VECTOR_10_025: [VECTOR_size shall return the number of elements stored with the given handle.] */
335 result = handle->count;
336 }
337 return result;
338}
Note: See TracBrowser for help on using the repository browser.