From 6c5f133c330374dad402ec94074cc6a6cea15a17 Mon Sep 17 00:00:00 2001 From: fumiama Date: Tue, 18 May 2021 09:14:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3align=E4=B8=8Eitems=5Flen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protobuf.c | 40 +++++++++++++++++++++------------------- simple_protobuf.h | 5 +++-- test.c | 18 ++++++------------ 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/protobuf.c b/protobuf.c index 3610c9f..e96bc78 100644 --- a/protobuf.c +++ b/protobuf.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "simple_protobuf.h" //#define DEBUG @@ -46,7 +47,7 @@ SIMPLE_PB* get_pb(FILE* fp) { char* end = p + struct_len; memset(p, 0, struct_len); while(p < end) { - uint64_t offset = 1u << fgetc(fp); + uint64_t offset = read_num(fp); uint64_t data_len = read_num(fp); #ifdef DEBUG printf("Offset: %llu, data_len: %llu.\n", offset, data_len); @@ -60,7 +61,7 @@ SIMPLE_PB* get_pb(FILE* fp) { return NULL; } -int set_pb(FILE* fp, uint8_t* items_type, uint64_t struct_len, void* target) { +int set_pb(FILE* fp, uint64_t* items_len, uint64_t struct_len, void* target) { uint64_t offset = 0; uint32_t i = 0; char* p = (char*)target; @@ -69,9 +70,8 @@ int set_pb(FILE* fp, uint8_t* items_type, uint64_t struct_len, void* target) { printf("struct_len: %llu bytes.\n", struct_len); #endif while(offset < struct_len) { - uint8_t type = items_type[i++]; - uint64_t data_len = 1u << type; - fputc(type, fp); + uint64_t data_len = items_len[i++]; + write_num(fp, data_len); char* this = p + offset; offset += data_len; if(data_len > 1) while(!this[data_len - 1]) data_len--; @@ -90,20 +90,22 @@ uint8_t first_set(uint64_t n) { return i; } -void align_struct(uint8_t* items_type, uint64_t items_cnt, uint64_t struct_size) { - uint64_t sum = 0; - uint8_t min = 255; - for(uint64_t i = 0; i < items_cnt; i++) { - sum += 1u << items_type[i]; - if(min > items_type[i]) min = items_type[i]; - } - while(sum < struct_size) { - uint8_t new_min = 255; - sum = 0; - for(uint64_t i = 0; i < items_cnt; i++) { - if(items_type[i] == min) items_type[i]++; - if(new_min > items_type[i]) new_min = items_type[i]; - sum += 1u << items_type[i]; +//uint64_t struct_size, uint32_t items_cnt, void* item_addr1, void* item_addr2... +uint64_t* align_struct(uint64_t struct_size, uint32_t items_cnt, ...) { + va_list list; + va_start(list, items_cnt); + uint64_t* items_len = malloc(struct_size*sizeof(uint64_t)); + if(items_len) { + void* this; + void* next = va_arg(list, void*); + void* end = next + struct_size; + for(uint32_t i = 0; i < items_cnt - 1; i++) { + this = next; + next = va_arg(list, void*); + items_len[i] = next - this; } + items_len[items_cnt-1] = end - next; } + va_end(list); + return items_len; } diff --git a/simple_protobuf.h b/simple_protobuf.h index bdac106..15111e0 100644 --- a/simple_protobuf.h +++ b/simple_protobuf.h @@ -10,8 +10,9 @@ struct SIMPLE_PB { typedef struct SIMPLE_PB SIMPLE_PB; SIMPLE_PB* get_pb(FILE* fp); -int set_pb(FILE* fp, uint8_t* items_type, uint64_t struct_len, void* target); +int set_pb(FILE* fp, uint64_t* items_len, uint64_t struct_len, void* target); uint8_t first_set(uint64_t n); -void align_struct(uint8_t* items_type, uint64_t items_cnt, uint64_t struct_size); +//uint64_t struct_size, uint32_t items_cnt, void* item_addr1, void* item_addr2... +uint64_t* align_struct(uint64_t struct_size, uint32_t items_cnt, ...); #endif \ No newline at end of file diff --git a/test.c b/test.c index 1d65574..83ada7d 100644 --- a/test.c +++ b/test.c @@ -11,26 +11,20 @@ struct TEST { }; struct TEST t; -uint64_t items_len[5] = {sizeof(t.a), sizeof(t.b), sizeof(t.c), sizeof(t.d), sizeof(t.e)}; -uint8_t types_len[5]; int main() { t.a = 0xAB; - t.b = 63345; - t.c = 1234567890; - t.d = 1234567898765435432ULL; + t.b = 0xCDEF; + t.c = 0xCCDDEE; + t.d = 0xABCDEF12345678; strcpy(t.e, "Hello world! This is a message from simple protobuf."); + uint64_t* items_len = align_struct(sizeof(struct TEST), 5, &t.a, &t.b, &t.c, &t.d, &t.e); for(int i = 0; i < 5; i++) { - types_len[i] = first_set(items_len[i]); - printf("Item %d has type %d with size %llu\n", i, types_len[i], items_len[i]); - } - align_struct(types_len, 5, sizeof(struct TEST)); - for(int i = 0; i < 5; i++) { - printf("Item %d's type after align: %u\n", i, types_len[i]); + printf("Item %d has aligned size %llu\n", i, items_len[i]); } FILE* fp = fopen("test.sp", "wb"); if(fp) { - set_pb(fp, types_len, sizeof(struct TEST), &t); + set_pb(fp, items_len, sizeof(struct TEST), &t); memset(&t, 0, sizeof(struct TEST)); fclose(fp); puts("Write file succeed.");