mirror of
https://github.com/fumiama/simple-protobuf.git
synced 2026-06-13 05:31:09 +08:00
修正align与items_len
This commit is contained in:
40
protobuf.c
40
protobuf.c
@@ -1,6 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include "simple_protobuf.h"
|
#include "simple_protobuf.h"
|
||||||
|
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
@@ -46,7 +47,7 @@ SIMPLE_PB* get_pb(FILE* fp) {
|
|||||||
char* end = p + struct_len;
|
char* end = p + struct_len;
|
||||||
memset(p, 0, struct_len);
|
memset(p, 0, struct_len);
|
||||||
while(p < end) {
|
while(p < end) {
|
||||||
uint64_t offset = 1u << fgetc(fp);
|
uint64_t offset = read_num(fp);
|
||||||
uint64_t data_len = read_num(fp);
|
uint64_t data_len = read_num(fp);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Offset: %llu, data_len: %llu.\n", offset, data_len);
|
printf("Offset: %llu, data_len: %llu.\n", offset, data_len);
|
||||||
@@ -60,7 +61,7 @@ SIMPLE_PB* get_pb(FILE* fp) {
|
|||||||
return NULL;
|
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;
|
uint64_t offset = 0;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
char* p = (char*)target;
|
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);
|
printf("struct_len: %llu bytes.\n", struct_len);
|
||||||
#endif
|
#endif
|
||||||
while(offset < struct_len) {
|
while(offset < struct_len) {
|
||||||
uint8_t type = items_type[i++];
|
uint64_t data_len = items_len[i++];
|
||||||
uint64_t data_len = 1u << type;
|
write_num(fp, data_len);
|
||||||
fputc(type, fp);
|
|
||||||
char* this = p + offset;
|
char* this = p + offset;
|
||||||
offset += data_len;
|
offset += data_len;
|
||||||
if(data_len > 1) while(!this[data_len - 1]) 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;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 sum = 0;
|
uint64_t* align_struct(uint64_t struct_size, uint32_t items_cnt, ...) {
|
||||||
uint8_t min = 255;
|
va_list list;
|
||||||
for(uint64_t i = 0; i < items_cnt; i++) {
|
va_start(list, items_cnt);
|
||||||
sum += 1u << items_type[i];
|
uint64_t* items_len = malloc(struct_size*sizeof(uint64_t));
|
||||||
if(min > items_type[i]) min = items_type[i];
|
if(items_len) {
|
||||||
}
|
void* this;
|
||||||
while(sum < struct_size) {
|
void* next = va_arg(list, void*);
|
||||||
uint8_t new_min = 255;
|
void* end = next + struct_size;
|
||||||
sum = 0;
|
for(uint32_t i = 0; i < items_cnt - 1; i++) {
|
||||||
for(uint64_t i = 0; i < items_cnt; i++) {
|
this = next;
|
||||||
if(items_type[i] == min) items_type[i]++;
|
next = va_arg(list, void*);
|
||||||
if(new_min > items_type[i]) new_min = items_type[i];
|
items_len[i] = next - this;
|
||||||
sum += 1u << items_type[i];
|
|
||||||
}
|
}
|
||||||
|
items_len[items_cnt-1] = end - next;
|
||||||
}
|
}
|
||||||
|
va_end(list);
|
||||||
|
return items_len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ struct SIMPLE_PB {
|
|||||||
typedef struct SIMPLE_PB SIMPLE_PB;
|
typedef struct SIMPLE_PB SIMPLE_PB;
|
||||||
|
|
||||||
SIMPLE_PB* get_pb(FILE* fp);
|
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);
|
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
|
#endif
|
||||||
18
test.c
18
test.c
@@ -11,26 +11,20 @@ struct TEST {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TEST t;
|
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() {
|
int main() {
|
||||||
t.a = 0xAB;
|
t.a = 0xAB;
|
||||||
t.b = 63345;
|
t.b = 0xCDEF;
|
||||||
t.c = 1234567890;
|
t.c = 0xCCDDEE;
|
||||||
t.d = 1234567898765435432ULL;
|
t.d = 0xABCDEF12345678;
|
||||||
strcpy(t.e, "Hello world! This is a message from simple protobuf.");
|
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++) {
|
for(int i = 0; i < 5; i++) {
|
||||||
types_len[i] = first_set(items_len[i]);
|
printf("Item %d has aligned size %llu\n", i, 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]);
|
|
||||||
}
|
}
|
||||||
FILE* fp = fopen("test.sp", "wb");
|
FILE* fp = fopen("test.sp", "wb");
|
||||||
if(fp) {
|
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));
|
memset(&t, 0, sizeof(struct TEST));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
puts("Write file succeed.");
|
puts("Write file succeed.");
|
||||||
|
|||||||
Reference in New Issue
Block a user