diff options
author | LAN-TW <lantw44@gmail.com> | 2013-12-07 20:30:26 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-12-07 20:31:18 +0800 |
commit | bdf3ed07dca38a5cd01ef908a4d7c9b7855257b5 (patch) | |
tree | 8909240b5caf21e551ee4d7e682b8bece2111be7 | |
parent | 39b80dfe6ff2f8c9e6615dd095e26c093ae34856 (diff) | |
download | l4basic-bdf3ed07dca38a5cd01ef908a4d7c9b7855257b5.tar.gz l4basic-bdf3ed07dca38a5cd01ef908a4d7c9b7855257b5.tar.zst l4basic-bdf3ed07dca38a5cd01ef908a4d7c9b7855257b5.zip |
Rewrite two-dimension array (LbsArray2) and add test suitel4basic-unstable-1.91.2
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | l4array2.c | 57 | ||||
-rw-r--r-- | l4array2.h | 74 | ||||
-rw-r--r-- | test-array2.c | 54 |
4 files changed, 145 insertions, 42 deletions
@@ -1 +1 @@ -1.91.1 +1.91.2 @@ -1,26 +1,51 @@ +/* vim: set sw=4 ts=4 sts=4 et: */ #include "l4array2.h" + #include <stdlib.h> +#include <string.h> -L4DA2* l4da2_create(int itemsize, int lenx, int leny){ - if(lenx <= 0 || leny <= 0 || itemsize <= 0){ - return NULL; - } - L4DA2* arr = (L4DA2*)malloc(sizeof(L4DA2)); - if(arr == NULL){ +LbsArray2* lbs_array2_new (size_t size, int lenx, int leny) { + if(size <= 0 || lenx <= 0 || leny <= 0){ return NULL; } - arr->arr_itemsize = itemsize; - arr->arr_lenx = lenx; - arr->arr_leny = leny; - arr->arr_data = malloc(itemsize*lenx*leny); - if(arr->arr_data == NULL){ - free(arr); + + LbsArray2* array2 = malloc ( + sizeof (LbsArray2) + size * lenx * leny); + if(array2 == NULL){ return NULL; } - return arr; + + array2->size = size; + array2->lenx = lenx; + array2->leny = leny; + array2->ref_count = 1; + return array2; +} + +void lbs_array2_copy_in (LbsArray2* array2, const void* copy_in) { + memcpy (array2->data, copy_in, array2->size * array2->lenx * array2->leny); +} + +void lbs_array2_copy_out (LbsArray2* array2, void* copy_out) { + memcpy (copy_out, array2->data, array2->size * array2->lenx * array2->leny); +} + +void* lbs_array2_ref_generic (void* array2_generic) { + LbsArray2* array2 = LBS_ARRAY2 (array2_generic); + int oldref = array2->ref_count; + int newref = oldref + 1; + if (newref <= oldref) { + return NULL; + } + + array2->ref_count = newref; + return array2; } -void l4da2_free(L4DA2* arr){ - free(arr->arr_data); - free(arr); +void lbs_array2_unref_generic (void* array2_generic) { + LbsArray2* array2 = LBS_ARRAY2 (array2_generic); + array2->ref_count--; + if (array2->ref_count <= 0) { + free (array2_generic); + } } @@ -1,25 +1,49 @@ -#ifndef L4LIB_DYNAMIC_ARRAY_D2 -#define L4LIB_DYNAMIC_ARRAY_D2 - -/*********** 二維陣列 (其實是用一維陣列來模擬,功能有限) ***********/ - -typedef struct l4lib_dyn_2darr{ - int arr_itemsize; /* 每個項目的大小 */ - int arr_lenx; /* 陣列 x 方向長度 */ - int arr_leny; /* 陣列 y 方向長度 */ - void* arr_data; /* 資料區 */ -} L4DA2 ; - -L4DA2* l4da2_create(int, int, int); -void l4da2_free(L4DA2*); -#define l4da2_getlenx(arr) ((arr)->arr_lenx) -#define l4da2_getleny(arr) ((arr)->arr_leny) -#define l4da2_itemsize(arr) ((arr)->arr_itemsize) -#define l4da2_data(arr) ((arr)->arr_data) -#define l4da2_v(arr, type, numx, numy) \ - (*(((type*)((arr)->arr_data))+((numx)*(l4da2_getleny(arr)))+(numy))) -#define l4da2_vp(arr, numx, numy) \ - ((void*)(((char*)((arr)->arr_data))+ \ - ((arr)->arr_itemsize)*((numx)*(l4da2_getleny(arr))+(numy)))) - -#endif +/* vim: set sw=4 ts=4 sts=4 et: */ +#ifndef LBS_ARRAY2_H +#define LBS_ARRAY2_H + +#include <l4common.h> + +typedef struct LbsArray2Struct { + /*< private >*/ + size_t size; /* element size */ + size_t lenx; /* x length */ + size_t leny; /* y length */ + unsigned ref_count; /* reference count */ + + /*< public >*/ + char data[]; /* data */ +} LbsArray2; + +#define LBS_ARRAY2(x) ((LbsArray2*)(x)) + +LbsArray2* lbs_array2_new (size_t size, int lenx, int leny); +void lbs_array2_copy_in (LbsArray2* array2, const void* copy_in); +void lbs_array2_copy_out (LbsArray2* array2, void* copy_out); + +#define lbs_array2_ref(array2) \ + (lbs_array2_ref_generic (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*))) +#define lbs_array2_unref(array2) \ + (lbs_array2_unref_generic (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*))) +void* lbs_array2_ref_generic (void* array2); +void lbs_array2_unref_generic (void* array2); + +#define lbs_array2_get_data(array2) \ + (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*)->data) +#define lbs_array2_get_size(array2) \ + (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*)->size) +#define lbs_array2_get_lenx(array2) \ + (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*)->lenx) +#define lbs_array2_get_leny(array2) \ + (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*)->leny) +#define lbs_array2_get_ref_count(array2) \ + (LBS_COMMON_CHECK_TYPE ((array2), LbsArray2*)->ref_count) + +#define lbs_array2_v(array2,type,x,y) \ + (*(((type*)((array2)->data)) + \ + ((x)*((array2)->leny))+(y))) +#define lbs_array2_vp(array2,x,y) \ + ((void*)(((char*)((array2)->data)) + \ + ((array2)->size)*((x)*((array2)->leny)+(y)))) + +#endif /* LBS_ARRAY2_H */ diff --git a/test-array2.c b/test-array2.c new file mode 100644 index 0000000..98b0ef0 --- /dev/null +++ b/test-array2.c @@ -0,0 +1,54 @@ +/* vim: set sw=4 ts=4 sts=4 et: */ +#undef NDEBUG +#define _POSIX_C_SOURCE 200809L +#include <l4array2.h> + +#include <assert.h> +#include <stdio.h> +#include <string.h> + +void test_array2_op (void) { + LbsArray2* array2 = lbs_array2_new (sizeof (int), 5, 8); + int tc[5][8] = { + { 1, 2, 3, 4, 5, 6, 7, 8 }, + { 9, 8, 7, 6, 5, 4, 3, 2 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 5, 5, 5, 5, 5, 5, 5, 5 }, + { 1, 5, 7, 2, 8, 3, 9, 4 } + }; + int tc_flat[5 * 8] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 8, 7, 6, 5, 4, 3, 2, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, + 1, 5, 7, 2, 8, 3, 9, 4 + }; + int tc_buf[5 * 8]; + const ssize_t tc_len = sizeof (int) * 5 * 8; + + lbs_array2_ref (array2); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 8; j++) { + lbs_array2_v (array2, int, i, j) = tc[i][j]; + } + } + + lbs_array2_copy_out (array2, tc_buf); + assert (memcmp (tc_buf, tc_flat, tc_len) == 0); + lbs_array2_v (array2, int, 4, 7) = 80; + lbs_array2_v (array2, int, 0, 0) = 90; + lbs_array2_copy_in (array2, tc_flat); + assert (memcmp (tc_buf, lbs_array2_get_data (array2), tc_len) == 0); + + assert (lbs_array2_get_ref_count (array2) == 2); + lbs_array2_unref (array2); + assert (lbs_array2_get_ref_count (array2) == 1); + lbs_array2_unref (array2); + + printf ("%s => PASS!\n", __func__); +} + +int main () { + test_array2_op (); + return 0; +} |