scf/pack: support var array and object array
authoryu.dongliang <18588496441@163.com>
Mon, 4 Mar 2024 11:17:38 +0000 (19:17 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 4 Mar 2024 11:17:38 +0000 (19:17 +0800)
pack/main.c
pack/scf_pack.c
pack/scf_pack.h

index 1e7e30b58f97dfa30841fb90834a96774d8bd061..64f1e6f2218f7044c68dfbbd6f5ae183478f929e 100644 (file)
@@ -3,32 +3,66 @@
 typedef struct {
        SCF_PACK_DEF_VAR(int, x); // int x;
        SCF_PACK_DEF_VAR(int, y); // int y;
+       SCF_PACK_DEF_VARS(int, z);
 } A;
 
 SCF_PACK_TYPE(A)
 SCF_PACK_INFO_VAR(A, x),
 SCF_PACK_INFO_VAR(A, y),
+SCF_PACK_INFO_VARS(A, z, int),
 SCF_PACK_END(A)
 
+typedef struct {
+       SCF_PACK_DEF_VAR(double, d);
+       SCF_PACK_DEF_OBJS(A, as);
+} B;
+
+SCF_PACK_TYPE(B)
+SCF_PACK_INFO_VAR(B, d),
+SCF_PACK_INFO_OBJS(B, as, A),
+SCF_PACK_END(B)
 
 int main()
 {
-       A  a = {1, 2};
-       A* p = NULL;
+       int z0[] = {1, 2, 3, 4};
+       int z1[] = {5, 6};
+       A  a0 = {7, 8, sizeof(z0) / sizeof(z0[0]), z0};
+       A  a1 = {9, 10, sizeof(z1) / sizeof(z1[0]), z1};
+       A* as[] = {&a0, &a1};
+
+       B  b = {3.14, sizeof(as) / sizeof(as[0]), as};
+       B* p = NULL;
+
+       printf("b: %p, b->as: %p, b->as[0]: %p, b->as[1]: %p\n", &b, b.as, b.as[0], b.as[1]);
+       printf("a0: %p, a1: %p\n", &a0, &a1);
+       printf("z0: %p, z1: %p\n", z0, z1);
 
        uint8_t* buf = NULL;
        int      len = 0;
 
-       scf_A_pack(&a, &buf, &len);
+       scf_B_pack(&b, &buf, &len);
 
        int i;
+       int j;
        for (i = 0; i < len; i++)
                printf("i: %d, %#x\n", i, buf[i]);
 
-       scf_A_unpack(&p, buf, len);
-       printf("p->x: %d, p->y: %d\n", p->x, p->y);
+       scf_B_unpack(&p, buf, len);
+       printf("p: %p, p->as: %p\n", p, p->as);
+       printf("p->d: %lg, p->n_as: %ld, p->as: %p\n", p->d, p->n_as, p->as);
+
+       for (i = 0; i < p->n_as; i++) {
+               printf("p->as[%d]: %p\n", i, p->as[i]);
+
+               A* a = p->as[i];
+               printf("a->x: %d, a->y: %d, a->n_z: %ld,a->z: %p\n", a->x,a->y, a->n_z, a->z);
+
+               for (j = 0; j < a->n_z; j++)
+                       printf("a->z[%d]: %d\n", j, a->z[j]);
+               printf("\n");
+       }
 
-       scf_A_free(p);
+       scf_B_free(p);
        free(buf);
        return 0;
 }
index db35901e3fc1bfa63748ab3ab51b3162753c627e..4ece50d9ca8a541721ee0948259fe53043f06a93 100644 (file)
 #include"scf_pack.h"
 
+int __scf_pack(void* p, int size, uint8_t** pbuf, int* plen)
+{
+       uint8_t pack[8];
+       int     len = 0;
+
+       switch (size) {
+               case 1:
+                       pack[0] = *(uint8_t*)p;
+                       len = 1;
+                       break;
+               case 2:
+                       *(uint16_t*)pack = *(uint16_t*)p;
+                       len = 2;
+                       break;
+               case 4:
+                       scf_logi("p: %p, %d\n", p, *(uint32_t*)p);
+                       *(uint32_t*)pack = *(uint32_t*)p;
+                       len = 4;
+                       break;
+               case 8:
+                       scf_logi("p: %p, %ld, %#lx, %lg\n", p, *(uint64_t*)p, *(uint64_t*)p, *(double*)p);
+                       *(uint64_t*)pack = *(uint64_t*)p;
+                       len = 8;
+                       break;
+               default:
+                       scf_loge("data size '%d' NOT support!\n", size);
+                       return -EINVAL;
+                       break;
+       };
+
+       void* b = realloc(*pbuf, *plen + len);
+       if (!b)
+               return -ENOMEM;
+       *pbuf = b;
+
+       memcpy(*pbuf + *plen, pack, len);
+       *plen += len;
+       return 0;
+}
+
 int scf_pack(void* p, scf_pack_info_t* infos, int n_infos, uint8_t** pbuf, int* plen)
 {
        if (!p || !infos || n_infos < 1 || !pbuf || !plen)
                return -EINVAL;
 
-       uint8_t* buf = *pbuf;
-       int      len = *plen;
-       int      i;
+       if (!*pbuf)
+               *plen = 0;
 
-       if (!buf)
-               len = 0;
+       printf("\n");
+       scf_logw("p: %p\n", p);
 
+       int i;
        for (i = 0; i < n_infos; i++) {
-               printf("name: %s, size: %ld, offset: %ld, noffset: %ld, members: %p, n_members: %ld\n",
-                               infos[i].name, infos[i].size, infos[i].offset, infos[i].noffset, infos[i].members, infos[i].n_members);
-
-               if (!infos[i].members) {
-
-                       uint8_t pack[8];
-                       int     size = 0;
-
-                       switch (infos[i].size) {
-                               case 1:
-                                       pack[0] = *(uint8_t*)(p + infos[i].offset);
-                                       size = 1;
-                                       break;
-                               case 2:
-                                       *(uint16_t*)pack = *(uint16_t*)(p + infos[i].offset);
-                                       size = 2;
-                                       break;
-                               case 4:
-                                       *(uint32_t*)pack = *(uint32_t*)(p + infos[i].offset);
-                                       size = 4;
-                                       break;
-                               case 8:
-                                       *(uint64_t*)pack = *(uint64_t*)(p + infos[i].offset);
-                                       size = 8;
-                                       break;
-                               default:
-                                       scf_loge("data type NOT support!\n");
-                                       return -EINVAL;
-                                       break;
-                       };
-
-                       void* b = realloc(buf, len + size);
-                       if (!b)
-                               return -ENOMEM;
-                       buf = b;
+               printf("name: %s, size: %ld, offset: %ld, noffset: %ld, msize: %ld, members: %p, n_members: %ld\n",
+                               infos[i].name, infos[i].size, infos[i].offset, infos[i].noffset, infos[i].msize, infos[i].members, infos[i].n_members);
+
+               if (infos[i].noffset >= 0) {
+
+                       void* a = *(void**)(p + infos[i].offset);
+                       long  n = *(long* )(p + infos[i].noffset);
+                       int   j;
 
-                       memcpy(buf + len, pack, size);
-                       len += size;
+                       scf_loge("a: %p, n: %ld, infos[i].msize: %ld, infos[i].noffset: %ld\n", a, n, infos[i].msize, infos[i].noffset);
+
+                       for (j = 0; j < n; j++) {
+
+                               if (infos[i].members) {
+                                       int ret = scf_pack(*(void**)(a + j * infos[i].msize), infos[i].members, infos[i].n_members, pbuf, plen);
+                                       if (ret < 0) {
+                                               scf_loge("ret: %d\n", ret);
+                                               return ret;
+                                       }
+                               } else {
+                                       int ret = __scf_pack(a + j * infos[i].msize, infos[i].msize, pbuf, plen);
+                                       if (ret < 0) {
+                                               scf_loge("ret: %d\n", ret);
+                                               return ret;
+                                       }
+                               }
+                       }
+
+                       continue;
+               }
+
+               if (infos[i].members) {
+
+                       int ret = scf_pack(*(void**)(p + infos[i].offset), infos[i].members, infos[i].n_members, pbuf, plen);
+                       if (ret < 0) {
+                               scf_loge("ret: %d\n", ret);
+                               return ret;
+                       }
+                       continue;
+               }
+
+               int ret = __scf_pack(p + infos[i].offset, infos[i].size, pbuf, plen);
+               if (ret < 0) {
+                       scf_loge("ret: %d\n", ret);
+                       return ret;
                }
+
+               scf_loge("size: %ld\n\n", infos[i].size);
        }
 
-       *pbuf = buf;
-       *plen = len;
        return 0;
 }
 
+int __scf_unpack(void* p, int size, const uint8_t* buf, int len)
+{
+       switch (size) {
+               case 1:
+                       if (1 <= len) {
+                               *(uint8_t*)p = buf[0];
+                               return 1;
+                       }
+                       break;
+
+               case 2:
+                       if (2 <= len) {
+                               *(uint16_t*)p = *(uint16_t*)buf;
+                               return 2;
+                       }
+                       break;
+
+               case 4:
+                       if (4 <= len) {
+                               *(uint32_t*)p = *(uint32_t*)buf;
+                               return 4;
+                       }
+                       break;
+
+               case 8:
+                       if (8 <= len) {
+                               *(uint64_t*)p = *(uint64_t*)buf;
+                               return 8;
+                       }
+                       break;
+               default:
+                       scf_loge("data type NOT support!\n");
+                       break;
+       };
+
+       return -EINVAL;
+}
+
 int scf_unpack(void** pp, scf_pack_info_t* infos, int n_infos, const uint8_t* buf, int len)
 {
        if (!pp || !infos || n_infos < 1 || !buf || len < 1)
@@ -71,61 +156,69 @@ int scf_unpack(void** pp, scf_pack_info_t* infos, int n_infos, const uint8_t* bu
                return -ENOMEM;
 
        int i;
-       int j = 0;
+       int j;
+       int k = 0;
 
        for (i = 0; i < n_infos; i++) {
 
-               if (!infos[i].members) {
+               if (infos[i].noffset >= 0) {
 
-                       switch (infos[i].size) {
-                               case 1:
-                                       if (j + 1 <= len)
-                                               *(uint8_t*)(p + infos[i].offset) = buf[j++];
-                                       else {
-                                               free(p);
-                                               return -EINVAL;
-                                       }
-                                       break;
-
-                               case 2:
-                                       if (j + 2 <= len) {
-                                               *(uint16_t*)(p + infos[i].offset) = *(uint16_t*)(buf + j);
-                                               j += 2;
-                                       } else {
-                                               free(p);
-                                               return -EINVAL;
-                                       }
-                                       break;
-
-                               case 4:
-                                       if (j + 4 <= len) {
-                                               *(uint32_t*)(p + infos[i].offset) = *(uint32_t*)(buf + j);
-                                               j += 4;
-                                       } else {
-                                               free(p);
-                                               return -EINVAL;
+                       long  n = *(long*)(p + infos[i].noffset);
+                       void* a = calloc(n, infos[i].msize);
+                       if (!a)
+                               return -ENOMEM;
+                       *(void**)(p + infos[i].offset) = a;
+
+                       scf_loge("a: %p, n: %ld, infos[i].msize: %ld\n", a, n, infos[i].msize);
+
+                       for (j = 0; j < n; j++) {
+
+                               if (infos[i].members) {
+                                       int ret = scf_unpack((void**)(a + j * infos[i].msize), infos[i].members, infos[i].n_members, buf + k, len - k);
+                                       if (ret < 0) {
+                                               scf_loge("ret: %d\n", ret);
+                                               return ret;
                                        }
-                                       break;
-
-                               case 8:
-                                       if (j + 8 <= len) {
-                                               *(uint64_t*)(p + infos[i].offset) = *(uint64_t*)(buf + j);
-                                               j += 8;
-                                       } else {
-                                               free(p);
-                                               return -EINVAL;
+
+                                       k += ret;
+
+                               } else {
+                                       int ret = __scf_unpack(a + j * infos[i].msize, infos[i].msize, buf + k, len - k);
+                                       if (ret < 0) {
+                                               scf_loge("ret: %d\n", ret);
+                                               return ret;
                                        }
-                                       break;
-                               default:
-                                       scf_loge("data type NOT support!\n");
-                                       return -EINVAL;
-                                       break;
-                       };
+
+                                       k += ret;
+                               }
+                       }
+
+                       continue;
                }
+
+               if (infos[i].members) {
+
+                       int ret = scf_unpack((void**)(p + infos[i].offset), infos[i].members, infos[i].n_members, buf + k, len - k);
+                       if (ret < 0) {
+                               scf_loge("ret: %d\n", ret);
+                               return ret;
+                       }
+
+                       k += ret;
+                       continue;
+               }
+
+               int ret = __scf_unpack(p + infos[i].offset, infos[i].size, buf + k, len - k);
+               if (ret < 0) {
+                       scf_loge("ret: %d\n", ret);
+                       return ret;
+               }
+
+               k += ret;
        }
 
        *pp = p;
-       return 0;
+       return k;
 }
 
 int scf_unpack_free(void* p, scf_pack_info_t* infos, int n_infos)
@@ -134,14 +227,41 @@ int scf_unpack_free(void* p, scf_pack_info_t* infos, int n_infos)
                return -EINVAL;
 
        int i;
+       int j;
        for (i = 0; i < n_infos; i++) {
 
+               if (infos[i].noffset >= 0) {
+                       long  n = *(long* )(p + infos[i].noffset);
+                       void* a = *(void**)(p + infos[i].offset);
+
+                       scf_loge("a: %p, n: %ld, infos[i].msize: %ld\n", a, n, infos[i].msize);
+
+                       if (infos[i].members) {
+
+                               for (j = 0; j < n; j++) {
+                                       int ret = scf_unpack_free(*(void**)(a + j * infos[i].msize), infos[i].members, infos[i].n_members);
+                                       if (ret < 0) {
+                                               scf_loge("ret: %d\n", ret);
+                                               return ret;
+                                       }
+                               }
+                       }
+
+                       scf_logi("a: %p\n", a);
+                       free(a);
+                       continue;
+               }
+
                if (infos[i].members) {
-                       int ret = scf_unpack_free(p + infos[i].offset, infos[i].members, infos[i].n_members);
+                       int ret = scf_unpack_free(*(void**)(p + infos[i].offset), infos[i].members, infos[i].n_members);
+                       if (ret < 0) {
+                               scf_loge("ret: %d\n", ret);
+                               return ret;
+                       }
                }
        }
 
+       scf_logi("p: %p\n", p);
        free(p);
        return 0;
 }
-
index 0594d16c21c0ed7bcc68e7f408791dad1db834dc..1235e80e25c5e6363d99d13e03af72c65aa1adeb 100644 (file)
@@ -11,6 +11,7 @@ struct scf_pack_info_s
        long             size;
        long             offset;
        long             noffset;
+       long             msize;
        scf_pack_info_t* members;
        long             n_members;
 };
@@ -27,16 +28,16 @@ int scf_unpack_free(void*  p,  scf_pack_info_t* infos, int n_infos);
 
 #define SCF_PACK_N_INFOS(type)         (sizeof(scf_pack_info_##type) / sizeof(scf_pack_info_##type[0]))
 
-#define SCF_PACK_INFO_VAR(type, var)   {#var,  sizeof(((type*)0)->var),   offsetof(type, var), -1, NULL, 0}
-#define SCF_PACK_INFO_OBJ(type, obj)   {#obj,  sizeof(((type*)0)->obj),   offsetof(type, obj), -1, scf_pack_info_##type, SCF_PACK_N_INFOS(type)}
+#define SCF_PACK_INFO_VAR(type, var)            {#var,  sizeof(((type*)0)->var),   offsetof(type, var), -1, -1, NULL, 0}
+#define SCF_PACK_INFO_OBJ(type, obj, objtype)   {#obj,  sizeof(((type*)0)->obj),   offsetof(type, obj), -1, -1, scf_pack_info_##objtype, SCF_PACK_N_INFOS(objtype)}
 
-#define SCF_PACK_INFO_VARS(type, vars) \
-       {"n_"#vars, sizeof(((type* )0)->n_##vars), offsetof(type, n_##vars), -1, NULL, 0}, \
-       {#vars,     sizeof(((type* )0)->vars),     offsetof(type, vars),     offsetof(type, n_##vars), NULL, 0}
+#define SCF_PACK_INFO_VARS(type, vars, vtype) \
+       {"n_"#vars, sizeof(((type*)0)->n_##vars), offsetof(type, n_##vars), -1, -1, NULL, 0}, \
+       {#vars,     sizeof(((type*)0)->vars),     offsetof(type, vars),     offsetof(type, n_##vars), sizeof(vtype), NULL, 0}
 
-#define SCF_PACK_INFO_OBJS(type, objs) \
-       {"n_"#objs, sizeof(((type* )0)->n_##objs), offsetof(type, n_##objs), -1, NULL, 0}, \
-       {#objs,     sizeof(((type**)0)->objs),     offsetof(type, objs),     offsetof(type, n_##objs), scf_pack_info_##type, SCF_PACK_N_INFOS(type)}
+#define SCF_PACK_INFO_OBJS(type, objs, objtype) \
+       {"n_"#objs, sizeof(((type*)0)->n_##objs), offsetof(type, n_##objs), -1, -1, NULL, 0}, \
+       {#objs,     sizeof(((type*)0)->objs),     offsetof(type, objs),     offsetof(type, n_##objs), sizeof(objtype*), scf_pack_info_##objtype, SCF_PACK_N_INFOS(objtype)}
 
 #define SCF_PACK_TYPE(type) \
 static scf_pack_info_t scf_pack_info_##type[] = {
@@ -44,15 +45,15 @@ static scf_pack_info_t scf_pack_info_##type[] = {
 
 #define SCF_PACK_END(type) \
 }; \
-static int scf_##type##_pack(A* p, uint8_t** pbuf, int* plen) \
+static int scf_##type##_pack(type* p, uint8_t** pbuf, int* plen) \
 { \
        return scf_pack(p, scf_pack_info_##type, SCF_PACK_N_INFOS(type), pbuf, plen); \
 } \
-static int scf_##type##_unpack(A** pp, uint8_t* buf, int len) \
+static int scf_##type##_unpack(type** pp, uint8_t* buf, int len) \
 { \
        return scf_unpack((void**)pp, scf_pack_info_##type, SCF_PACK_N_INFOS(type), buf, len); \
 } \
-static int scf_##type##_free(A* p) \
+static int scf_##type##_free(type* p) \
 { \
        return scf_unpack_free(p, scf_pack_info_##type, SCF_PACK_N_INFOS(type)); \
 }