*
* Copyright (c) 2024 Brad House
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#ifndef __ARES__ARRAY_H
#define __ARES__ARRAY_H
#include "ares.h"
*
* This is an array with helpers. It is meant to have as little overhead
* as possible over direct array management by applications but to provide
* safety and some optimization features. It can also return the array in
* native form once all manipulation has been performed.
*
* @{
*/
struct ares_array;
typedef struct ares_array ares_array_t;
*
* \param[in] data pointer to member of array to be destroyed. The pointer
* itself must not be destroyed, just the data it contains.
*/
typedef void (*ares_array_destructor_t)(void *data);
*
* \param[in] data1 array member 1
* \param[in] data2 array member 2
* \return < 0 if data1 < data2, > 0 if data1 > data2, 0 if data1 == data2
*/
typedef int (*ares_array_cmp_t)(const void *data1, const void *data2);
*
* NOTE: members of the array are typically going to be an going to be a
* struct with compiler/ABI specific padding to ensure proper alignment.
* Care needs to be taken if using primitive types, especially floating
* point numbers which size may not indicate the required alignment.
* For example, a double may be 80 bits (10 bytes), but required
* alignment of 16 bytes. In such a case, a member_size of 16 would be
* required to be used.
*
* \param[in] destruct Optional. Destructor to call on a removed member
* \param[in] member_size Size of array member, usually determined using
* sizeof() for the member such as a struct.
*
* \return array object or NULL on out of memory
*/
CARES_EXTERN ares_array_t *ares_array_create(size_t member_size,
ares_array_destructor_t destruct);
* array size is known prior to populating the array to prevent reallocations.
*
* \param[in] arr Initialized array object.
* \param[in] size Minimum number of members
* \return ARES_SUCCESS on success, ARES_EFORMERR on misuse,
* ARES_ENOMEM on out of memory */
CARES_EXTERN ares_status_t ares_array_set_size(ares_array_t *arr, size_t size);
* persistent, any future elements inserted will not maintain this sort.
*
* \param[in] arr Initialized array object.
* \param[in] cb Sort callback
* \return ARES_SUCCESS on success
*/
CARES_EXTERN ares_status_t ares_array_sort(ares_array_t *arr,
ares_array_cmp_t cmp);
* member of the array.
*
* \param[in] arr Initialized array object.
*/
CARES_EXTERN void ares_array_destroy(ares_array_t *arr);
* container. It is the responsibility of the caller to free the returned
* pointer and also any data within each array element.
*
* \param[in] arr Initialized array object
* \param[out] num_members the number of members in the returned array
* \return pointer to native array on success, NULL on failure.
*/
CARES_EXTERN void *ares_array_finish(ares_array_t *arr, size_t *num_members);
*
* \param[in] arr Initialized array object.
* \return numbrer of members
*/
CARES_EXTERN size_t ares_array_len(const ares_array_t *arr);
*
* \param[out] elem_ptr Optional. Pointer to the returned array element.
* \param[in] arr Initialized array object.
* \param[in] idx Index in array to place new element, will shift any
* elements down that exist after this point.
* \return ARES_SUCCESS on success, ARES_EFORMERR on bad index,
* ARES_ENOMEM on out of memory.
*/
CARES_EXTERN ares_status_t ares_array_insert_at(void **elem_ptr,
ares_array_t *arr, size_t idx);
*
* \param[out] elem_ptr Optional. Pointer to the returned array element.
* \param[in] arr Initialized array object.
* \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory.
*/
CARES_EXTERN ares_status_t ares_array_insert_last(void **elem_ptr,
ares_array_t *arr);
*
* \param[out] elem_ptr Optional. Pointer to the returned array element.
* \param[in] arr Initialized array object.
* \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory.
*/
CARES_EXTERN ares_status_t ares_array_insert_first(void **elem_ptr,
ares_array_t *arr);
* to by the data pointer into the array. This will copy member_size bytes
* from the provided pointer, this may not be safe for some data types
* that may have a smaller size than the provided member_size which includes
* padding as discussed in ares_array_create().
*
* \param[in] arr Initialized array object.
* \param[in] idx Index in array to place new element, will shift any
* elements down that exist after this point.
* \param[in] data_ptr Pointer to data to copy into array.
* \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data
* ptr, ARES_ENOMEM on out of memory.
*/
CARES_EXTERN ares_status_t ares_array_insertdata_at(ares_array_t *arr,
size_t idx,
const void *data_ptr);
* to by the data pointer into the array. This will copy member_size bytes
* from the provided pointer, this may not be safe for some data types
* that may have a smaller size than the provided member_size which includes
* padding as discussed in ares_array_create().
*
* \param[in] arr Initialized array object.
* \param[in] data_ptr Pointer to data to copy into array.
* \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data
* ptr, ARES_ENOMEM on out of memory.
*/
CARES_EXTERN ares_status_t ares_array_insertdata_last(ares_array_t *arr,
const void *data_ptr);
* pointed to by the data pointer into the array. This will copy member_size
* bytes from the provided pointer, this may not be safe for some data types
* that may have a smaller size than the provided member_size which includes
* padding as discussed in ares_array_create().
*
* \param[in] arr Initialized array object.
* \param[in] data_ptr Pointer to data to copy into array.
* \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data
* ptr, ARES_ENOMEM on out of memory.
*/
CARES_EXTERN ares_status_t ares_array_insertdata_first(ares_array_t *arr,
const void *data_ptr);
* \param[in] array Initialized array object
* \param[in] idx Index to fetch
* \return pointer on success, NULL on failure */
CARES_EXTERN void *ares_array_at(ares_array_t *arr, size_t idx);
* \param[in] array Initialized array object
* \return pointer on success, NULL on failure */
CARES_EXTERN void *ares_array_first(ares_array_t *arr);
* \param[in] array Initialized array object
* \return pointer on success, NULL on failure */
CARES_EXTERN void *ares_array_last(ares_array_t *arr);
* \param[in] array Initialized array object
* \param[in] idx Index to fetch
* \return pointer on success, NULL on failure */
CARES_EXTERN const void *ares_array_at_const(const ares_array_t *arr,
size_t idx);
* \param[in] array Initialized array object
* \return pointer on success, NULL on failure */
CARES_EXTERN const void *ares_array_first_const(const ares_array_t *arr);
* \param[in] array Initialized array object
* \return pointer on success, NULL on failure */
CARES_EXTERN const void *ares_array_last_const(const ares_array_t *arr);
* provided by the caller. The index specified in the array will then be
* removed (without calling any possible destructor)
*
* \param[in,out] dest Optional. Buffer to hold array member. Pass NULL
* if not needed. This could leak memory if array
* member needs destructor if not provided.
* \param[in] dest_size Size of buffer provided, used as a sanity check.
* Must match member_size provided to
* ares_array_create() if dest_size specified.
* \param[in] arr Initialized array object
* \param[in] idx Index to claim
* \return ARES_SUCCESS on success, ARES_EFORMERR on usage failure.
*/
CARES_EXTERN ares_status_t ares_array_claim_at(void *dest, size_t dest_size,
ares_array_t *arr, size_t idx);
* called.
*
* \param[in] arr Initialized array object
* \param[in] idx Index to remove
* \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use
*/
CARES_EXTERN ares_status_t ares_array_remove_at(ares_array_t *arr, size_t idx);
*
* \param[in] arr Initialized array object
* \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use
*/
CARES_EXTERN ares_status_t ares_array_remove_first(ares_array_t *arr);
*
* \param[in] arr Initialized array object
* \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use
*/
CARES_EXTERN ares_status_t ares_array_remove_last(ares_array_t *arr);
#endif