inc/c_util/thandle_tuple_array.h (97 lines of code) (raw):
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#ifndef THANDLE_TUPLE_ARRAY_H
#define THANDLE_TUPLE_ARRAY_H
#ifdef __cplusplus
#include <cinttypes>
#else
#include <inttypes.h>
#endif
#include "macro_utils/macro_utils.h"
#include "c_pal/thandle.h"
#include "umock_c/umock_c_prod.h"
#ifdef __cplusplus
extern "C" {
#endif
#define THANDLE_TUPLE_ARRAY_STRUCT_MEMBER(type, name) THANDLE(type) name;
#define DECLARE_THANDLE_TUPLE_TYPE(name, ...) \
typedef struct MU_C2(name, _TAG) \
{ \
MU_FOR_EACH_2(THANDLE_TUPLE_ARRAY_STRUCT_MEMBER, __VA_ARGS__) \
} name;
#define THANDLE_TUPLE_ARRAY_TYPE(name) MU_C2A(name, _ARRAY)
#define DECLARE_THANDLE_TUPLE_ARRAY_TYPE(name) \
typedef struct MU_C2B(THANDLE_TUPLE_ARRAY_TYPE(name), _TAG) \
{ \
const uint32_t count; \
name tuple_array[]; \
} THANDLE_TUPLE_ARRAY_TYPE(name);
#define THANDLE_TUPLE_ARRAY_CREATE(name) MU_C2A(name, _array_create)
#define THANDLE_TUPLE_ARRAY_DESTROY(name) MU_C2A(name, _array_destroy)
#define DECLARE_THANDLE_TUPLE_ARRAY(name, ...) \
DECLARE_THANDLE_TUPLE_TYPE(name, __VA_ARGS__) \
DECLARE_THANDLE_TUPLE_ARRAY_TYPE(name) \
MOCKABLE_FUNCTION(, THANDLE_TUPLE_ARRAY_TYPE(name)*, THANDLE_TUPLE_ARRAY_CREATE(name), uint32_t, count); \
MOCKABLE_FUNCTION(, void, THANDLE_TUPLE_ARRAY_DESTROY(name), THANDLE_TUPLE_ARRAY_TYPE(name)*, tuple_array);
#define THANDLE_TUPLE_ARRAY_INIT_MEMBER(type, name) THANDLE_INITIALIZE(type)(&result->tuple_array[i].name, NULL);
#define IMPLEMENT_THANDLE_TUPLE_ARRAY_CREATE(name, ...) \
IMPLEMENT_MOCKABLE_FUNCTION(, THANDLE_TUPLE_ARRAY_TYPE(name)*, THANDLE_TUPLE_ARRAY_CREATE(name), uint32_t, count) \
{ \
THANDLE_TUPLE_ARRAY_TYPE(name)* result; \
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_001: [ THANDLE_TUPLE_ARRAY_CREATE(name) shall allocate memory for the array. ]*/ \
result = malloc_flex(sizeof(THANDLE_TUPLE_ARRAY_TYPE(name)), count, sizeof(name)); \
\
if (result == NULL) \
{ \
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_004: [ If there are any errors then THANDLE_TUPLE_ARRAY_CREATE(name) shall fail and return NULL. ]*/ \
LogError("failure in malloc_flex((sizeof(THANDLE_TUPLE_ARRAY_TYPE(name))=%zu, count=%" PRIu32 ", sizeof(name)=%zu)) failed", sizeof(THANDLE_TUPLE_ARRAY_TYPE(name)), count, sizeof(name)); \
} \
else \
{ \
/* Need to cast to assign to the const member */ \
*(uint32_t*)&result->count = count; \
\
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_003: [ THANDLE_TUPLE_ARRAY_CREATE(name) shall initialize the members of the tuples in the array to NULL. ]*/ \
for (uint32_t i = 0; i < count; ++i) \
{ \
MU_FOR_EACH_2(THANDLE_TUPLE_ARRAY_INIT_MEMBER, __VA_ARGS__) \
} \
\
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_005: [ THANDLE_TUPLE_ARRAY_CREATE(name) shall succeed and return the allocated array. ]*/ \
goto all_ok; \
} \
free(result); \
result = NULL; \
all_ok: \
return result; \
}
#define THANDLE_TUPLE_ARRAY_FREE_MEMBER(type, name) \
if (tuple_array->tuple_array[i].name != NULL) \
{ \
THANDLE_ASSIGN(type)(&tuple_array->tuple_array[i].name, NULL); \
}
#define IMPLEMENT_THANDLE_TUPLE_ARRAY_DESTROY(name, ...) \
IMPLEMENT_MOCKABLE_FUNCTION(, void, THANDLE_TUPLE_ARRAY_DESTROY(name), THANDLE_TUPLE_ARRAY_TYPE(name)*, tuple_array) \
{ \
if (tuple_array == NULL) \
{ \
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_006: [ If tuple_array is NULL then THANDLE_TUPLE_ARRAY_DESTROY(name) shall fail and return. ]*/ \
LogError("Invalid args: " MU_TOSTRING(THANDLE_TUPLE_ARRAY_TYPE(name)) "* tuple_array=%p", \
tuple_array); \
} \
else \
{ \
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_007: [ THANDLE_TUPLE_ARRAY_DESTROY(name) shall iterate over all of the elements in tuple_array and call THANDLE_ASSIGN(type) with NULL for each field. ]*/ \
for (uint32_t i = 0; i < tuple_array->count; ++i) \
{ \
MU_FOR_EACH_2(THANDLE_TUPLE_ARRAY_FREE_MEMBER, __VA_ARGS__) \
} \
/*Codes_SRS_THANDLE_TUPLE_ARRAY_42_008: [ THANDLE_TUPLE_ARRAY_DESTROY(name) shall free the memory allocated in tuple_array. ]*/ \
free(tuple_array); \
} \
}
#define DEFINE_THANDLE_TUPLE_ARRAY(name, ...) \
IMPLEMENT_THANDLE_TUPLE_ARRAY_CREATE(name, __VA_ARGS__) \
IMPLEMENT_THANDLE_TUPLE_ARRAY_DESTROY(name, __VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif // THANDLE_TUPLE_ARRAY_H