176 lines
3.9 KiB
C
176 lines
3.9 KiB
C
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include <unity/unity.h>
|
|
|
|
#include "rtti.h"
|
|
|
|
typedef struct {
|
|
int count;
|
|
int* data;
|
|
} myArray_t;
|
|
|
|
static size_t my_array_datasize(va_list ap) { return sizeof(myArray_t); }
|
|
|
|
static int my_array_init(meta_obj_t* obj, va_list ap)
|
|
{
|
|
myArray_t* a = RTTI_OBJ_TO_DATA(myArray_t, obj);
|
|
int count;
|
|
int i;
|
|
|
|
count = va_arg(ap, int);
|
|
if (count <= 0) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
a->data = (int*)calloc(count, sizeof(int));
|
|
if (a->data == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
a->count = count;
|
|
for (i = 0; i < count; i++) {
|
|
a->data[i] = va_arg(ap, int);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void my_array_destroy(meta_obj_t* obj)
|
|
{
|
|
myArray_t* a = RTTI_OBJ_TO_DATA(myArray_t, obj);
|
|
if (a->data != NULL) {
|
|
free(a->data);
|
|
a->data = NULL;
|
|
}
|
|
}
|
|
|
|
static int my_array_make_iter(iterator_t* iter, va_list ap)
|
|
{
|
|
iter->data = (void*)(long)0;
|
|
|
|
return RTTI_ITER_OK;
|
|
}
|
|
|
|
static int my_array_iter_next(iterator_t* iter, void** data)
|
|
{
|
|
myArray_t* a = RTTI_OBJ_TO_DATA(myArray_t, iter->obj);
|
|
int idx = (int)(long)iter->data;
|
|
|
|
if (idx >= a->count) {
|
|
/* no data */
|
|
return RTTI_ITER_NO_DATA;
|
|
}
|
|
|
|
*data = (void*)(long)a->data[idx];
|
|
iter->data = (void*)(long)(idx + 1);
|
|
|
|
return RTTI_ITER_OK;
|
|
}
|
|
|
|
static int my_array_iter_reset(iterator_t* iter)
|
|
{
|
|
iter->data = (void*)(long)0;
|
|
|
|
return RTTI_ITER_OK;
|
|
}
|
|
|
|
static void my_array_iter_destroy(iterator_t* iter) { return; }
|
|
|
|
static typeinfo_t myintArray
|
|
= { .name = "myintArray",
|
|
.privateSize = 0,
|
|
.dataSize = (datasize_fn_t)my_array_datasize,
|
|
.init = (obj_init_fn_t)my_array_init,
|
|
.destroy = (obj_destroy_fn_t)my_array_destroy,
|
|
.interfaces
|
|
= { .iter = &(intf_iterator_t) {
|
|
.make = (iter_make_fn_t)my_array_make_iter,
|
|
.next = (iter_next_fn_t)my_array_iter_next,
|
|
.reset = (iter_reset_fn_t)my_array_iter_reset,
|
|
.destroy = (iter_destroy_fn_t)my_array_iter_destroy } } };
|
|
|
|
static void test_typeof(void)
|
|
{
|
|
var array = makeInstance(&myintArray, 5, 0, 1, 2, 3, 4);
|
|
int rc;
|
|
typeinfo_t* t = NULL;
|
|
|
|
t = typeOf(array);
|
|
TEST_ASSERT_TRUE(t == &myintArray);
|
|
|
|
rc = instanceOf(array, &myintArray);
|
|
TEST_ASSERT_TRUE(rc == 1);
|
|
|
|
destroy(array);
|
|
}
|
|
|
|
static void test_array_iter(void)
|
|
{
|
|
var array = makeInstance(&myintArray, 5, 0, 1, 2, 3, 4);
|
|
iterator_t it;
|
|
int rc, sum;
|
|
void* data;
|
|
|
|
TEST_ASSERT_TRUE(array != NULL);
|
|
TEST_ASSERT_TRUE(is_rtti_obj(array) == 1);
|
|
rc = iter_make(&it, array);
|
|
TEST_ASSERT_TRUE(rc == 1);
|
|
|
|
rc = iter_next(&it, (void**)&data);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE((int)(long)data == 0);
|
|
|
|
rc = iter_next(&it, (void**)&data);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE((int)(long)data == 1);
|
|
|
|
rc = iter_next(&it, (void**)&data);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE((int)(long)data == 2);
|
|
|
|
rc = iter_next(&it, (void**)&data);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE((int)(long)data == 3);
|
|
|
|
rc = iter_next(&it, (void**)&data);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
TEST_ASSERT_TRUE((int)(long)data == 4);
|
|
|
|
rc = iter_next(&it, (void**)&data);
|
|
TEST_ASSERT_TRUE(rc == RTTI_ITER_NO_DATA);
|
|
|
|
sum = 0;
|
|
rc = iter_reset(&it);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
|
|
for (;;) {
|
|
rc = iter_next(&it, &data);
|
|
TEST_ASSERT_TRUE(rc >= 0);
|
|
if (rc == RTTI_ITER_NO_DATA) {
|
|
break;
|
|
}
|
|
|
|
sum += (int)(long)data;
|
|
}
|
|
|
|
TEST_ASSERT_TRUE(sum == 10);
|
|
|
|
iter_destroy(&it);
|
|
|
|
destroy(array);
|
|
|
|
return;
|
|
}
|
|
|
|
void test_type(void) {
|
|
printf("\n type info test\n\n");
|
|
|
|
RUN_TEST(test_typeof);
|
|
}
|
|
|
|
void test_iter(void)
|
|
{
|
|
printf("\n iterator test\n\n");
|
|
|
|
RUN_TEST(test_array_iter);
|
|
}
|