当前位置: 首页 > news >正文

protobuf 未知字段的获取

未知字段就是服务器可能新增了一个字段,但是客服端的proto文件中并没有添加,那么服务器发来的序列化数据,在客服端进行反序列化之后,这个新增的字段在proto3.5之前是会被之久抛弃的,但是在proto3.5之后会被保存哎未知字段中。那么这里的未知字段就可以理解为解析结构良好的 protocol buffer 已序列化数据中的未识别字段的表示方式。例如,当旧程序解析带有新字段的数据时,这些新字段就会成为旧程序的未知字段。

那么未知字段要从哪里获取呢?
先了解一下protobuf的相关类的关系图
在这里插入图片描述
MessageLite类主要提供了序列化和反序列化的方法。
Message类主要提供了GetDescriptor/GetReflection,可以获取该类型对应的Descriptor对象指针 和 Reflection 对象指针。
Desriptor类主要提供了对Message类型定义的描述,包括Message的名字、所有字段的描述、原始的proto⽂件内容等。
Reflection类主要提供了动态读写消息字段的接口。并且还包含了对未知字段的读写方法。
UnknownFieldSet类就包含了分析消息时遇到但未由其类型定义的所有字段。通过Refiection中的GetUnknownFields方法就可以返回这样一个对象,参数为消息对象。
UnknownField类中就包含了未知消息的具体内容。并且这个类中存在Type枚举类型,其中就包含了很多的未知字段的可能类型,我们选哟根据类型调用不同的方法来拿到未知字段的内容。

有了上述的理解之后就可以尝试拿一下未知字段的内容了,假设我们现在有一个PeopleInfo消息在contacts命名空间中,现在有一个消息实例peo,那么可以通过下述代码来拿到未知消息字段的变好以及内容。

 // 获取到Reflection类对象const google::protobuf::Reflection* refiection = contacts::PeopleInfo::GetReflection();// 通过Reflection对象获取到未知字段的setconst google::protobuf::UnknownFieldSet& unknowSet = refiection->GetUnknownFields(peo); // 这里的消息可以替换成具体的消息,要和上面的PeopleInfo匹配for(int i = 0; i < unknowSet.field_count(); ++i){// 获取到set中的所有未知对象google::protobuf::UnknownField field = unknowSet.field(i);cout << "未知字段" << i + 1 << "字段编号为 :" << field.number() << " 值 :";// 根据类型进行打印switch (field.type()){case google::protobuf::UnknownField::Type::TYPE_VARINT:cout << field.varint() << endl;break;case google::protobuf::UnknownField::Type::TYPE_FIXED32:cout << field.fixed32() << endl;break;case google::protobuf::UnknownField::Type::TYPE_FIXED64:cout << field.fixed64() << endl;break;case google::protobuf::UnknownField::Type::TYPE_LENGTH_DELIMITED:cout << field.length_delimited() << endl;break;case google::protobuf::UnknownField::Type::TYPE_GROUP:const google::protobuf::UnknownFieldSet& set = field.group();// 这里会获得一个UnknownFieldSet 通过类似的方法进行打印break;default:break;}}

http://www.mrgr.cn/news/54757.html

相关文章:

  • Java 当中使用 “google.zxing ”开源项目 和 “github 的 qrcode-plugin” 开源项目 生成二维码
  • A Graph-Transformer for Whole SlideImage Classification文献笔记
  • 设计模式的六大原则
  • 【设计模式七大设计原则】
  • 【最新通知】2024年Cisco思科认证CCNA详解
  • 【Flutter】Dart:运算符
  • gc cr/current block 2-way
  • 【MySQL】内外连接
  • 2024年深圳福田区第十二届职工技能大比武职业技能竞赛圆满收官
  • Vue-router 路由守卫执行流程图
  • 光纤光学的基本方程
  • 【MySQL】:库的操作
  • 【力扣打卡系列】滑动窗口与双指针(接雨水)
  • 【Maven】一篇带你了解Maven项目管理工具
  • int argc, char *argv[]
  • 6.C++经典实例-计算给定范围内的素数(质数)
  • SLACC Simion-based Language Agnostic Code Clones
  • 基于STM32的超声波流量计设计
  • python编译问题 当你编译第一个python程序时可能出现如下错误
  • 【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,1-11
  • Tornado简单使用
  • JavaScript 新手必知的基本概念
  • 深入了解 Flannel(3):vxlan在flannel中的作用
  • 【Linux系统编程】冯诺依曼体系结构与操作系统
  • 操作系统之内存管理基本概念
  • SpringCloudAlibaba[Nacos]注册配置中心注册与发现服务