From d0c7f4712312f24a4b2e3919919dae1ebe7874c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Fri, 6 May 2022 11:15:13 +0800 Subject: [PATCH] add more api --- protobuf.c | 41 ++++++++++++++++++++++++++++++++++++++--- simple_protobuf.h | 6 ++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/protobuf.c b/protobuf.c index d0cb37e..d6f70b1 100644 --- a/protobuf.c +++ b/protobuf.c @@ -5,9 +5,8 @@ #include "simple_protobuf.h" static uint32_t read_num(FILE* fp) { - uint8_t c; - uint32_t n = 0; - uint8_t i = 0; + uint32_t c, n = 0; + long i = 0; do { c = fgetc(fp); if(feof(fp)) return n; @@ -16,6 +15,18 @@ static uint32_t read_num(FILE* fp) { return n; } +static uint32_t peek_num(FILE* fp) { + uint32_t c, n = 0; + long i = 0; + do { + c = fgetc(fp); + if(feof(fp)) return n; + else n |= (c & 0x7f) << (7 * i++); + } while((c & 0x80)); + fseek(fp, -i, SEEK_CUR); + return n; +} + static int write_num(FILE* fp, uint32_t n) { char* c = (char*)(&n); int i = 0; @@ -51,6 +62,30 @@ SIMPLE_PB* get_pb(FILE* fp) { return spb; } +uint32_t get_pb_len(FILE* fp) { + uint32_t init_pos = ftell(fp); + uint32_t struct_len = peek_num(fp); + if(struct_len <= 1 || struct_len >= 1u<<20) return 0; // 1B= 1u<<20) return NULL; // 1Bstruct_len = struct_len; + memset(spb->target, 0, struct_len); + uint32_t offset, data_len; + for(char* p = spb->target; p < spb->target+struct_len; p += offset) { + offset = read_num(fp); + data_len = read_num(fp); + if(data_len > 0 && data_len <= offset) fread(p, data_len, 1, fp); + } + spb->real_len = ftell(fp) - init_pos; + return spb; +} + int set_pb(FILE* fp, uint32_t* items_len, uint32_t struct_len, void* target) { uint32_t offset = 0; uint32_t i = 0; diff --git a/simple_protobuf.h b/simple_protobuf.h index 4c0adc1..b3151b3 100644 --- a/simple_protobuf.h +++ b/simple_protobuf.h @@ -11,7 +11,13 @@ struct SIMPLE_PB { typedef struct SIMPLE_PB SIMPLE_PB; SIMPLE_PB* get_pb(FILE* fp); + +uint32_t get_pb_len(FILE* fp); + +SIMPLE_PB* read_pb_into(FILE* fp, SIMPLE_PB* spb); + int set_pb(FILE* fp, uint32_t* items_len, uint32_t struct_len, void* target); + //uint32_t struct_size, uint32_t items_cnt, void* item_addr1, void* item_addr2... uint32_t* align_struct(uint32_t struct_size, uint32_t items_cnt, ...);