From 72df914b470a37d2e152d49a5ced8ff39d424e65 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Mon, 4 Mar 2024 19:17:38 +0800 Subject: [PATCH] scf/pack: support var array and object array --- pack/main.c | 46 +++++++- pack/scf_pack.c | 302 +++++++++++++++++++++++++++++++++--------------- pack/scf_pack.h | 23 ++-- 3 files changed, 263 insertions(+), 108 deletions(-) diff --git a/pack/main.c b/pack/main.c index 1e7e30b..64f1e6f 100644 --- a/pack/main.c +++ b/pack/main.c @@ -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; } diff --git a/pack/scf_pack.c b/pack/scf_pack.c index db35901..4ece50d 100644 --- a/pack/scf_pack.c +++ b/pack/scf_pack.c @@ -1,64 +1,149 @@ #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; } - diff --git a/pack/scf_pack.h b/pack/scf_pack.h index 0594d16..1235e80 100644 --- a/pack/scf_pack.h +++ b/pack/scf_pack.h @@ -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)); \ } -- 2.25.1