#include #include #include #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_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_iter(void) { printf("\n iterator test\n\n"); RUN_TEST(test_array_iter); }