aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--l4array2.c57
-rw-r--r--l4array2.h74
-rw-r--r--test-array2.c54
4 files changed, 145 insertions, 42 deletions
diff --git a/VERSION b/VERSION
index 8d39474..bf959fd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.91.1
+1.91.2
diff --git a/l4array2.c b/l4array2.c
index 24d6db0..e207e46 100644
--- a/l4array2.c
+++ b/l4array2.c
@@ -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);
+ }
}
diff --git a/l4array2.h b/l4array2.h
index e10fc0b..964f92c 100644
--- a/l4array2.h
+++ b/l4array2.h
@@ -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;
+}