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;
}
#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)
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)
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;
}
-
long size;
long offset;
long noffset;
+ long msize;
scf_pack_info_t* members;
long n_members;
};
#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[] = {
#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)); \
}