--- /dev/null
+CFILES += ../pack/scf_pack.c
+CFILES += ../pack/main.c
+
+CFLAGS += -g
+#CFLAGS += -Wall
+CFLAGS += -I../util
+
+LDFLAGS +=
+
+all:
+ gcc $(CFLAGS) $(CFILES) $(LDFLAGS)
--- /dev/null
+#include"scf_pack.h"
+
+typedef struct {
+ SCF_PACK_DEF_VAR(int, x); // int x;
+ SCF_PACK_DEF_VAR(int, y); // int y;
+} A;
+
+SCF_PACK_TYPE(A)
+SCF_PACK_INFO_VAR(A, x),
+SCF_PACK_INFO_VAR(A, y),
+SCF_PACK_END(A)
+
+
+int main()
+{
+ A a = {1, 2};
+ A* p = NULL;
+
+ uint8_t* buf = NULL;
+ int len = 0;
+
+ scf_A_pack(&a, &buf, &len);
+
+ int i;
+ 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_A_free(p);
+ free(buf);
+ return 0;
+}
--- /dev/null
+#include"scf_pack.h"
+
+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 (!buf)
+ len = 0;
+
+ 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;
+
+ memcpy(buf + len, pack, size);
+ len += size;
+ }
+ }
+
+ *pbuf = buf;
+ *plen = len;
+ return 0;
+}
+
+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 -EINVAL;
+
+ int size = infos[n_infos - 1].offset + infos[n_infos - 1].size;
+
+ void* p = calloc(1, size);
+ if (!p)
+ return -ENOMEM;
+
+ int i;
+ int j = 0;
+
+ for (i = 0; i < n_infos; i++) {
+
+ if (!infos[i].members) {
+
+ 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;
+ }
+ break;
+
+ case 8:
+ if (j + 8 <= len) {
+ *(uint64_t*)(p + infos[i].offset) = *(uint64_t*)(buf + j);
+ j += 8;
+ } else {
+ free(p);
+ return -EINVAL;
+ }
+ break;
+ default:
+ scf_loge("data type NOT support!\n");
+ return -EINVAL;
+ break;
+ };
+ }
+ }
+
+ *pp = p;
+ return 0;
+}
+
+int scf_unpack_free(void* p, scf_pack_info_t* infos, int n_infos)
+{
+ if (!p || !infos || n_infos < 1)
+ return -EINVAL;
+
+ int i;
+ for (i = 0; i < n_infos; i++) {
+
+ if (infos[i].members) {
+ int ret = scf_unpack_free(p + infos[i].offset, infos[i].members, infos[i].n_members);
+ }
+ }
+
+ free(p);
+ return 0;
+}
+
--- /dev/null
+#ifndef SCF_PACK_H
+#define SCF_PACK_H
+
+#include"scf_def.h"
+
+typedef struct scf_pack_info_s scf_pack_info_t;
+
+struct scf_pack_info_s
+{
+ const char* name;
+ long size;
+ long offset;
+ long noffset;
+ scf_pack_info_t* members;
+ long n_members;
+};
+
+int scf_pack (void* p, scf_pack_info_t* infos, int n_infos, uint8_t** pbuf, int* plen);
+int scf_unpack (void** pp, scf_pack_info_t* infos, int n_infos, const uint8_t* buf, int len);
+int scf_unpack_free(void* p, scf_pack_info_t* infos, int n_infos);
+
+#define SCF_PACK_DEF_VAR(type, var) type var
+#define SCF_PACK_DEF_VARS(type, vars) long n_##vars; type* vars
+
+#define SCF_PACK_DEF_OBJ(type, obj) type* obj
+#define SCF_PACK_DEF_OBJS(type, objs) long n_##objs; type** objs
+
+#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_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_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_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) \
+{ \
+ 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) \
+{ \
+ return scf_unpack((void**)pp, scf_pack_info_##type, SCF_PACK_N_INFOS(type), buf, len); \
+} \
+static int scf_##type##_free(A* p) \
+{ \
+ return scf_unpack_free(p, scf_pack_info_##type, SCF_PACK_N_INFOS(type)); \
+}
+
+#endif