之前浏览protobuf-c相关代码的时候,根据如下
protobuf_c_message_pack
protobuf_c_message_pack_to_buffer
protobuf_c_message_unpack
protobuf_c_message_free_unpacked
函数的实现,写了一个protobuf2xml、xml2protobuf 以及protobuf2json、json2protobuf的公共代码。
解决了 读取xml json到struct的问题。
目前go中有很多gorm解决了sql-db到struct映射的库以及struct到json的库。目前struct到xml的映射好像没有额!!!
pb2json 核心是:
- 遍历pb的每一个FieldDescriptor
- 如果是required 或者option 标签则调用cJSON_AddNumberToObject 添加json的k-v节点
cJSON_AddNumberToObject(parent, field->name, *(const int32_t*)(member));
对于message类型数据;
required_field_to_json(const ProtobufCFieldDescriptor *field,const void *member, cJSON *parent)
{
const ProtobufCMessage *sub_msg =*(ProtobufCMessage * const *)member;
cJSON *child = cJSON_CreateObject();
cJSON_AddItemToObject(parent, field->name, child);
message_to_json(sub_msg, child)
}
- 如果是repeated 标签;则类似于message 类型数据处理
array_child = cJSON_CreateArray();
cJSON_AddItemToObject(parent, field->name, array_child);
for (i = 0; i < count; i++) {
cJSON_AddNumberToObject(array_child, field->name, *(const int32_t*)(array));
array += siz;
}
json2pb核心是:
- scanjson;扫描json,解析每个k-v节点根据key 以及filed映射反射,member中去
- 为repeated数据给message分配一级arry也就是char**ptr,先分配一维数组内存prt = malloc(sizeof(void *) * n_mem) 大小内存
- 根据scan_member 结果组装message
cJSON *child =parent->child;
while (child!=NULL)
{
cJSON *child = cJSON_GetArrayItem(parent, i);
const char *name = child->string;
field = descriptor_get_field_by_name(desc, name);
scanned_member.field = field;
if (field->label != LABEL_REPEATED) {
scanned_member.node = child;
ret = add_member(result, &scanned_member, allocator);
} else {
n = message+field->quantifier_offset;
cJSON *child_child =child->child;
while (child_child!=NULL) {
scanned_member.node = child_child;
add_member(result, &scanned_member,allocator);
*n += 1;
child_child = child_child->next;
}
}
child =child->next;
}
后面直接使用c-go把
标签:const,cJSON,prb2xml,member,field,child,go,message From: https://www.cnblogs.com/codestack/p/17961872