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.
Fork of azure_c_shared_utility by
vector.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/gballoc.h" 00006 #include "azure_c_shared_utility/vector.h" 00007 #include "azure_c_shared_utility/optimize_size.h" 00008 #include "azure_c_shared_utility/xlogging.h" 00009 00010 #include "azure_c_shared_utility/vector_types_internal.h" 00011 00012 VECTOR_HANDLE VECTOR_create(size_t elementSize) 00013 { 00014 VECTOR_HANDLE result; 00015 00016 /* Codes_SRS_VECTOR_10_002: [VECTOR_create shall fail and return NULL if elementsize is 0.] */ 00017 if (elementSize == 0) 00018 { 00019 LogError("invalid elementSize(%zd).", elementSize); 00020 result = NULL; 00021 } 00022 else 00023 { 00024 result = (VECTOR*)malloc(sizeof(VECTOR)); 00025 /* Codes_SRS_VECTOR_10_002 : [VECTOR_create shall fail and return NULL if malloc fails.] */ 00026 if (result == NULL) 00027 { 00028 LogError("malloc failed."); 00029 } 00030 else 00031 { 00032 /* 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.] */ 00033 result->storage = NULL; 00034 result->count = 0; 00035 result->elementSize = elementSize; 00036 } 00037 } 00038 return result; 00039 } 00040 00041 void VECTOR_destroy(VECTOR_HANDLE handle) 00042 { 00043 /* Codes_SRS_VECTOR_10_009: [VECTOR_destroy shall return if the given handle is NULL.] */ 00044 if (handle == NULL) 00045 { 00046 LogError("invalid argument handle(NULL)."); 00047 } 00048 else 00049 { 00050 /* Codes_SRS_VECTOR_10_008: [VECTOR_destroy shall free the given handle and its internal storage.] */ 00051 free(handle->storage); 00052 free(handle); 00053 } 00054 } 00055 00056 VECTOR_HANDLE VECTOR_move(VECTOR_HANDLE handle) 00057 { 00058 VECTOR_HANDLE result; 00059 if (handle == NULL) 00060 { 00061 /* Codes_SRS_VECTOR_10_005: [VECTOR_move shall fail and return NULL if the given handle is NULL.] */ 00062 LogError("invalid argument - handle(NULL)."); 00063 result = NULL; 00064 } 00065 else 00066 { 00067 result = (VECTOR*)malloc(sizeof(VECTOR)); 00068 if (result == NULL) 00069 { 00070 /* Codes_SRS_VECTOR_10_006: [VECTOR_move shall fail and return NULL if malloc fails.] */ 00071 LogError("malloc failed."); 00072 } 00073 else 00074 { 00075 /* Codes_SRS_VECTOR_10_004: [VECTOR_move shall allocate a VECTOR_HANDLE and move the data to it from the given handle.] */ 00076 result->count = handle->count; 00077 result->elementSize = handle->elementSize; 00078 result->storage = handle->storage; 00079 00080 handle->storage = NULL; 00081 handle->count = 0; 00082 } 00083 } 00084 return result; 00085 } 00086 00087 /* insertion */ 00088 00089 int VECTOR_push_back(VECTOR_HANDLE handle, const void* elements, size_t numElements) 00090 { 00091 int result; 00092 if (handle == NULL || elements == NULL || numElements == 0) 00093 { 00094 /* Codes_SRS_VECTOR_10_011: [VECTOR_push_back shall fail and return non-zero if `handle` is NULL.] */ 00095 /* Codes_SRS_VECTOR_10_034: [VECTOR_push_back shall fail and return non-zero if `elements` is NULL.] */ 00096 /* Codes_SRS_VECTOR_10_035: [VECTOR_push_back shall fail and return non-zero if `numElements` is 0.] */ 00097 LogError("invalid argument - handle(%p), elements(%p), numElements(%zd).", handle, elements, numElements); 00098 result = __FAILURE__; 00099 } 00100 else 00101 { 00102 size_t curSize = handle->elementSize * handle->count; 00103 size_t appendSize = handle->elementSize * numElements; 00104 00105 void* temp = realloc(handle->storage, curSize + appendSize); 00106 if (temp == NULL) 00107 { 00108 /* Codes_SRS_VECTOR_10_012: [VECTOR_push_back shall fail and return non-zero if memory allocation fails.] */ 00109 LogError("realloc failed."); 00110 result = __FAILURE__; 00111 } 00112 else 00113 { 00114 /* Codes_SRS_VECTOR_10_013: [VECTOR_push_back shall append the given elements and return 0 indicating success.] */ 00115 (void)memcpy((unsigned char*)temp + curSize, elements, appendSize); 00116 handle->storage = temp; 00117 handle->count += numElements; 00118 result = 0; 00119 } 00120 } 00121 return result; 00122 } 00123 00124 /* removal */ 00125 00126 void VECTOR_erase(VECTOR_HANDLE handle, void* elements, size_t numElements) 00127 { 00128 if (handle == NULL || elements == NULL || numElements == 0) 00129 { 00130 /* Codes_SRS_VECTOR_10_015: [VECTOR_erase shall return if `handle` is NULL.] */ 00131 /* Codes_SRS_VECTOR_10_038: [VECTOR_erase shall return if `elements` is NULL.] */ 00132 /* Codes_SRS_VECTOR_10_039: [VECTOR_erase shall return if `numElements` is 0.] */ 00133 LogError("invalid argument - handle(%p), elements(%p), numElements(%zd).", handle, elements, numElements); 00134 } 00135 else 00136 { 00137 if (elements < handle->storage) 00138 { 00139 /* Codes_SRS_VECTOR_10_040: [VECTOR_erase shall return if `elements` is out of bound.] */ 00140 LogError("invalid argument elements(%p) is not a member of this object.", elements); 00141 } 00142 else 00143 { 00144 ptrdiff_t diff = ((unsigned char*)elements) - ((unsigned char*)handle->storage); 00145 if ((diff % handle->elementSize) != 0) 00146 { 00147 /* Codes_SRS_VECTOR_10_041: [VECTOR_erase shall return if elements is misaligned.] */ 00148 LogError("invalid argument - elements(%p) is misaligned", elements); 00149 } 00150 else 00151 { 00152 /* Compute the arguments needed for memmove. */ 00153 unsigned char* src = (unsigned char*)elements + (handle->elementSize * numElements); 00154 unsigned char* srcEnd = (unsigned char*)handle->storage + (handle->elementSize * handle->count); 00155 if (src > srcEnd) 00156 { 00157 /* Codes_SRS_VECTOR_10_040: [VECTOR_erase shall return if `elements` is out of bound.] */ 00158 LogError("invalid argument - numElements(%zd) is out of bound.", numElements); 00159 } 00160 else 00161 { 00162 /* Codes_SRS_VECTOR_10_014: [VECTOR_erase shall remove the 'numElements' starting at 'elements' and reduce its internal storage.] */ 00163 handle->count -= numElements; 00164 if (handle->count == 0) 00165 { 00166 free(handle->storage); 00167 handle->storage = NULL; 00168 } 00169 else 00170 { 00171 void* tmp; 00172 (void)memmove(elements, src, srcEnd - src); 00173 tmp = realloc(handle->storage, (handle->elementSize * handle->count)); 00174 if (tmp == NULL) 00175 { 00176 LogInfo("realloc failed. Keeping original internal storage pointer."); 00177 } 00178 else 00179 { 00180 handle->storage = tmp; 00181 } 00182 } 00183 } 00184 } 00185 } 00186 } 00187 } 00188 00189 void VECTOR_clear(VECTOR_HANDLE handle) 00190 { 00191 /* Codes_SRS_VECTOR_10_017: [VECTOR_clear shall if the object is NULL or empty.] */ 00192 if (handle == NULL) 00193 { 00194 LogError("invalid argument handle(NULL)."); 00195 } 00196 else 00197 { 00198 /* Codes_SRS_VECTOR_10_016: [VECTOR_clear shall remove all elements from the object and release internal storage.] */ 00199 free(handle->storage); 00200 handle->storage = NULL; 00201 handle->count = 0; 00202 } 00203 } 00204 00205 /* access */ 00206 00207 void* VECTOR_element(VECTOR_HANDLE handle, size_t index) 00208 { 00209 void* result; 00210 if (handle == NULL) 00211 { 00212 /* Codes_SRS_VECTOR_10_019: [VECTOR_element shall fail and return NULL if handle is NULL.] */ 00213 LogError("invalid argument handle(NULL)."); 00214 result = NULL; 00215 } 00216 else 00217 { 00218 if (index >= handle->count) 00219 { 00220 /* Codes_SRS_VECTOR_10_020: [VECTOR_element shall fail and return NULL if the given index is out of range.] */ 00221 LogError("invalid argument - index(%zd); should be >= 0 and < %zd.", index, handle->count); 00222 result = NULL; 00223 } 00224 else 00225 { 00226 /* Codes_SRS_VECTOR_10_018: [VECTOR_element shall return the element at the given index.] */ 00227 result = (unsigned char*)handle->storage + (handle->elementSize * index); 00228 } 00229 } 00230 return result; 00231 } 00232 00233 void* VECTOR_front(VECTOR_HANDLE handle) 00234 { 00235 void* result; 00236 if (handle == NULL) 00237 { 00238 /* Codes_SRS_VECTOR_10_022: [VECTOR_front shall fail and return NULL if handle is NULL.] */ 00239 LogError("invalid argument handle (NULL)."); 00240 result = NULL; 00241 } 00242 else 00243 { 00244 if (handle->count == 0) 00245 { 00246 /* Codes_SRS_VECTOR_10_028: [VECTOR_front shall return NULL if the vector is empty.] */ 00247 LogError("vector is empty."); 00248 result = NULL; 00249 } 00250 else 00251 { 00252 /* Codes_SRS_VECTOR_10_021: [VECTOR_front shall return a pointer to the element at index 0.] */ 00253 result = handle->storage; 00254 } 00255 } 00256 return result; 00257 } 00258 00259 void* VECTOR_back(VECTOR_HANDLE handle) 00260 { 00261 void* result; 00262 if (handle == NULL) 00263 { 00264 /* Codes_SRS_VECTOR_10_024: [VECTOR_back shall fail and return NULL if handle is NULL.] */ 00265 LogError("invalid argument handle (NULL)."); 00266 result = NULL; 00267 } 00268 else 00269 { 00270 if (handle->count == 0) 00271 { 00272 /* Codes_SRS_VECTOR_10_029: [VECTOR_back shall return NULL if the vector is empty.] */ 00273 LogError("vector is empty."); 00274 result = NULL; 00275 } 00276 else 00277 { 00278 /* Codes_SRS_VECTOR_10_023: [VECTOR_front shall return the last element of the vector.] */ 00279 result = (unsigned char*)handle->storage + (handle->elementSize * (handle->count - 1)); 00280 } 00281 } 00282 return result; 00283 } 00284 00285 void* VECTOR_find_if(VECTOR_HANDLE handle, PREDICATE_FUNCTION pred, const void* value) 00286 { 00287 void* result; 00288 if (handle == NULL || pred == NULL) 00289 { 00290 /* Codes_SRS_VECTOR_10_030: [VECTOR_find_if shall fail and return NULL if `handle` is NULL.] */ 00291 /* Codes_SRS_VECTOR_10_036: [VECTOR_find_if shall fail and return NULL if `pred` is NULL.] */ 00292 LogError("invalid argument - handle(%p), pred(%p)", handle, pred); 00293 result = NULL; 00294 } 00295 else 00296 { 00297 size_t i; 00298 for (i = 0; i < handle->count; ++i) 00299 { 00300 if (true == pred((unsigned char*)handle->storage + (handle->elementSize * i), value)) 00301 { 00302 /* Codes_SRS_VECTOR_10_031: [VECTOR_find_if shall return the first element in the vector that matches `pred`.] */ 00303 break; 00304 } 00305 } 00306 00307 if (i == handle->count) 00308 { 00309 /* Codes_SRS_VECTOR_10_032: [VECTOR_find_if shall return NULL if no matching element is found.] */ 00310 result = NULL; 00311 } 00312 else 00313 { 00314 /* Codes_SRS_VECTOR_10_031: [VECTOR_find_if shall return the first element in the vector that matches `pred`.]*/ 00315 result = (unsigned char*)handle->storage + (handle->elementSize * i); 00316 } 00317 } 00318 return result; 00319 } 00320 00321 /* capacity */ 00322 00323 size_t VECTOR_size(VECTOR_HANDLE handle) 00324 { 00325 size_t result; 00326 if (handle == NULL) 00327 { 00328 /* Codes_SRS_VECTOR_10_026: [**VECTOR_size shall return 0 if the given handle is NULL.] */ 00329 LogError("invalid argument handle(NULL)."); 00330 result = 0; 00331 } 00332 else 00333 { 00334 /* Codes_SRS_VECTOR_10_025: [VECTOR_size shall return the number of elements stored with the given handle.] */ 00335 result = handle->count; 00336 } 00337 return result; 00338 }
Generated on Tue Jul 12 2022 19:14:38 by
