protobuf转json

他山之石,可以攻玉      2022-02-11     206

关键词:

方法介绍

    protobuf的介绍在这里就不详细介绍了,主要是俺也是刚接触,感兴趣的同学可以去搜索相关博客或者直接去看源码以及google的官方文档(官方文档表示很吃力)或者去这个网站:https://developers.google.com/protocol-buffers/docs/overview查看相应内容,这里面内容很全面,可以很方面的查询各个函数的使用方法以及功能。本篇文章主要介绍一下本人最近做的一个protobuf转json的小工具,下面进行拆分讲解,完整的代码在:[email protected]:chengfeiGitHub/P-bToJson.git。

    protobuf自带一个MessageToJson()的函数可以将对应的消息转换成json,一般情况下该函数可以满足转换需求。但是,最近项目的要求使用MessageToJson()无法实现,主要要求是:

  1. 选择特定的messge进行转换(主要是提供包含需求字段号的set或者vector,根据提供的字段号进行转换);
  2. 对于Enum类型的消息,可以选择显示枚举名或者枚举值;
  3. 对于字段值为0的字段,可以选择显示或者不显示.

    主要有这三个要求,对于功能2、3现在最新的protobuf应该是支持的,但是没有功能1的实现方式,所以只好自己写一个小工具。

    说明:本工具由C++编写完成

    首先是函数的声明:

 1 #pragma once
 2 #include <iostream>
 3 #include <google/protobuf/message.h>
 4 #include <google/protobuf/descriptor.h>
 5 
 6 void ChooseSomeFieldsToJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, std::vector<uint>& needs, bool Enum_2_Str, bool Showzero);
 7 //Enum_2_Str: ture显示枚举名,false:显示枚举值; Showzero: ture显示值为0的fields,false,不显示值为0的fields。
 8 void GetRepeatedJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, const google::protobuf::FieldDescriptor *field, const ::google::protobuf::Reflection *reflection, bool Enum_2_Str,bool Showzero);
 9 void NeedEmptyToJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, bool Enum_2_Str, bool Showzero);
10 void NeedNotEmptyToJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, std::vector<uint>& needs, bool Enum_2_Str, bool Showzero);
11 int AppendTmpString1(std::string& pb2jsonstring,std::string& tmp_string, int judge);
12 int AppendTmpString2(std::string& pb2jsonstring,std::string& tmp_string, int judge);

 

    pb2jsonstring是存储转换结果的字符串,msg是需要转换的消息,needs是需要转换的字段号;函数GetRepeatedJson()是对重复的字段进行操作;NeedEmptyToJson()是当needs为空时对应的操作(needs为空表示需要转换所有的字段);NeedNotEmptyToJson()是当needs不为空时对应的操作;AppendTmpStrign1()以及AppendTmpStrign2()是将临时字符串添加到pb2jsonstring后的操作。

    上面的代码保存到一个头文件当中,就叫pbjsontest3.h吧,然后是pbjsontest3.cpp

    

 1 #include <iostream>
 2 #include <google/protobuf/descriptor.h>  
 3 #include <google/protobuf/message.h>  
 4 #include <set>
 5 #include <string>
 6 #include "pbjsontest3.h"
 7   
 8 using namespace ::google::protobuf; 
 9 
10 void ChooseSomeFieldsToJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, std::vector<uint>& need, bool Enum_2_Str, bool Showzero)  
11 {
12 
13     const Descriptor* descriptor = msg.GetDescriptor();  
14     const Reflection* reflection = msg.GetReflection(); 
15     if (need.empty())  //如果needs为空,表示需要将所有的字段转换为json
16     {    
17         NeedEmptyToJson(pb2jsonstring, msg, Enum_2_Str, Showzero);
18     }
19     else 
20     {
21         NeedNotEmptyToJson(pb2jsonstring, msg, need, Enum_2_Str, Showzero);
22     }
23 }

    这一部分主要就是判断need是否为空,然后选择相应的函数进行操作,不在做详细的叙述,下面是NeedEmptyToJson()的介绍。由于这一部分代码太长,所以相应的介绍在代码中进行注释说明。

  1 void NeedEmptyToJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, bool Enum_2_Str, bool Showzero)
  2 {
  3     const Descriptor* descriptor = msg.GetDescriptor();  
  4     const Reflection* reflection = msg.GetReflection(); 
  5     const uint count = descriptor->field_count();  //count为当前消息中所有的字段总数
  6     uint judge = 0;//judge用来判断是否在当前json元素前加“,”用来分隔前后元素,如果judge==0,则不加,如果jugdge==1,则加“,”
  7     std::string tmp_string;  //临时变量
  8     std::int32_t v32=0;
  9     std::uint32_t vu32=0;
 10     std::int64_t v64=0;
 11     std::uint64_t vu64=0;
 12     double vd=0;
 13     std::string str;
 14     pb2jsonstring.append("{");  //添加第一个"{"
 15     for (int it = 0; it <count; ++it) 
 16     {         
 17         const FieldDescriptor* goal_field=descriptor->field(it);  
 18         /*这里要用field()来取字段,因为field()是按字段的实际标号来取字段,而不是根据字段号来进行取字段,这样就避免的字段号不连续造成的某些字段取不到的问题。 */   
 19         if(nullptr==goal_field)  //不存在字段
 20         {
 21             continue;
 22         } 
 23 
 24         if (goal_field->is_repeated())  //判断字段是否为repeated
 25         {  
 26             if (reflection->FieldSize(msg, goal_field) > 0)  
 27             { 
 28                 tmp_string="";
 29                 tmp_string.append(""").append(goal_field->name()).append("":");
 30                 tmp_string .append("[");  //重复的字段用[]包围
 31                 GetRepeatedJson(tmp_string, msg, goal_field, reflection, Enum_2_Str,Showzero); 
 32                 tmp_string.append("]"); 
 33                 judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);  
 34             }
 35             continue;  
 36         }
 37         switch (goal_field->type())  
 38         {  
 39         case FieldDescriptor::TYPE_MESSAGE:  
 40             {  
 41                 const Message& tmp_msg = reflection->GetMessage(msg, goal_field);  
 42                 if (0 != tmp_msg.ByteSize())  
 43                 { 
 44                     tmp_string="";
 45                     tmp_string.append(""").append(goal_field->name()).append("":");
 46                     NeedEmptyToJson(tmp_string,tmp_msg, Enum_2_Str, Showzero);
 47                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
 48                 }  
 49             }  
 50             break;  
 51             
 52         case FieldDescriptor::TYPE_INT32: 
 53             {
 54                 v32=reflection->GetInt32(msg, goal_field);
 55                 if(v32==0)
 56                 {
 57                     if(Showzero)   //字段值为0,也需要进行打印
 58                     {                        
 59                         tmp_string="";
 60                         tmp_string.append(""").append(goal_field->name()).append("":");
 61                         tmp_string.append(std::to_string(v32)); //需要抓换成字符型
 62                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 63                     }
 64                 }
 65                 else
 66                 {
 67                     tmp_string="";
 68                     tmp_string.append(""").append(goal_field->name()).append("":");
 69                     tmp_string.append(std::to_string(v32));                     
 70                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 71                 } 
 72             }
 73             break;  
 74 
 75         case FieldDescriptor::TYPE_UINT32:
 76             {  
 77                 vu32=reflection->GetUInt32(msg, goal_field);
 78                 if(vu32==0)
 79                 {
 80                     if(Showzero)
 81                     {
 82                         tmp_string="";
 83                         tmp_string.append(""").append(goal_field->name()).append("":");
 84                         tmp_string.append(std::to_string(vu32));  
 85                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 86                     }
 87                 }
 88                 else
 89                 {
 90                     tmp_string="";
 91                     tmp_string.append(""").append(goal_field->name()).append("":");
 92                     tmp_string.append(std::to_string(vu32));
 93                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 94                 }       
 95              }
 96             break;  
 97 
 98         case FieldDescriptor::TYPE_INT64:  
 99             {  
100                 v64=reflection->GetInt64(msg, goal_field);
101                 if(v64==0)
102                 {
103                     if(Showzero)
104                     {
105                         tmp_string="";
106                         tmp_string.append(""").append(goal_field->name()).append("":");         
107                         tmp_string.append(std::to_string(v64));
108                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
109                     }
110                 }
111                 else
112                 {
113                     tmp_string="";
114                     tmp_string.append(""").append(goal_field->name()).append("":");
115                     tmp_string.append(std::to_string(v64));         
116                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);  
117                 } 
118             } 
119             break;  
120         case FieldDescriptor::TYPE_UINT64:  
121              {  
122                 vu64=reflection->GetUInt64(msg, goal_field);
123                 if(vu64==0)
124                 {
125                     if(Showzero)
126                     {
127                         tmp_string="";                
128                         tmp_string.append(""").append(goal_field->name()).append("":");      
129                         tmp_string.append(std::to_string(vu64));
130                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
131                     }
132                 }
133                 else
134                 {
135                     tmp_string="";                
136                     tmp_string.append(""").append(goal_field->name()).append("":");      
137                     tmp_string.append(std::to_string(vu64));
138                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
139                 }
140              } 
141             break;  
142         case FieldDescriptor::TYPE_STRING:  
143         case FieldDescriptor::TYPE_BYTES:  
144             {  
145                 
146                 str=reflection->GetString(msg, goal_field);
147                 if(str.empty())
148                 {
149                     if(Showzero)
150                     {
151                         tmp_string="";
152                         tmp_string.append(""").append(goal_field->name()).append("":");
153                         tmp_string.append(""").append(str).append(""");
154                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
155                     }
156                 }
157                 else
158                 {
159                     tmp_string="";
160                     tmp_string.append(""").append(goal_field->name()).append("":");
161                     tmp_string.append(""").append(str).append(""");
162                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
163 
164                 }
165             }  
166             break; 
167         case FieldDescriptor::TYPE_DOUBLE:
168             {
169                 vd=reflection->GetDouble(msg, goal_field);
170                 if(vd==0)
171                 {
172                     if(Showzero)
173                     {
174                         tmp_string="";
175                         tmp_string.append(""").append(goal_field->name()).append("":");
176                         tmp_string.append(std::to_string(vd));
177                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
178                     }
179                 }
180                 else 
181                 {
182                     tmp_string="";
183                     tmp_string.append(""").append(goal_field->name()).append("":");
184                     tmp_string.append(std::to_string(vd));
185                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
186                 }          
187             } 
188             break;
189         case FieldDescriptor::TYPE_BOOL:
190             {
191                 tmp_string="";
192                 tmp_string.append(""").append(goal_field->name()).append("":");
193                 if (reflection->GetBool(msg, goal_field))
194                     tmp_string.append("true");
195                 else 
196                     tmp_string.append("false");
197                 judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
198               
199             } 
200             break;
201         case FieldDescriptor::TYPE_ENUM:
202             {
203                 tmp_string="";
204                 tmp_string.append(""").append(goal_field->name()).append("":");
205                 if (Enum_2_Str) //判断显示枚举名还是枚举值
206                 {       
207                     tmp_string.append(""").append(reflection->GetEnum(msg,goal_field)->name()).append(""");
208                 }
209                 else 
210                 {
211                     static char enumstr[8];
212                     memset(enumstr, 0, sizeof(enumstr)); 
213                     snprintf(enumstr, sizeof(enumstr), "%d", reflection->GetEnum(msg,goal_field)->number());
214                     tmp_string.append(enumstr);                    
215                 }
216                 judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
217             }
218             break;
219         default:  
220             break;  
221         }
222     }
223     pb2jsonstring.append("}");
224 }
225 
226 int AppendTmpString1(std::string &pb2jsonstring,std::string &tmp_string, int judge)
227 {
228     if ( judge!=0 && tmp_string.length()!=0)
229     {
230         pb2jsonstring.append(",").append(tmp_string);
231         return judge;
232     }
233     else if(judge==0 && tmp_string.length()!=0)
234     {
235         pb2jsonstring.append(tmp_string);
236         return 1;
237     }
238     return judge;
239 }

 

    下面need不为空时候的转换:

    

  1 void NeedNotEmptyToJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, std::vector<uint>& needs, bool Enum_2_Str, bool Showzero)
  2 {
  3     const Descriptor* descriptor = msg.GetDescriptor();  
  4     const Reflection* reflection = msg.GetReflection(); 
  5    
  6     uint judge = 0;
  7     std::string tmp_string;
  8     std::int32_t v32=0;
  9     std::uint32_t vu32=0;
 10     std::int64_t v64=0;
 11     std::uint64_t vu64=0;
 12     double vd=0;
 13     std::string str;
 14 
 15     pb2jsonstring.append("{");
 16    
 17     for (auto it=needs.begin(); it != needs.end(); ++it) 
 18     {         
 19         const FieldDescriptor* goal_field=descriptor->FindFieldByNumber(*it); 
 20         //need为空的转换和不为空的几乎一样,主要差别是对字段的提取,不为空时需要使用FindFieldByNumber()来进行操作,这样可以取任意字段号对应的字段。将need为空和不为空分开写主要是测试中这样可以节省时间,其实是可以写到一块的,有兴趣的同学可以进行修改。
 21 
 22         if(nullptr==goal_field)  //不存在字段
 23         {
 24             continue;
 25         } 
 26 
 27         if (goal_field->is_repeated())  
 28         {  
 29             if (reflection->FieldSize(msg, goal_field) > 0)  
 30             { 
 31                 tmp_string="";
 32                 tmp_string.append(""").append(goal_field->name()).append("":");
 33                 tmp_string .append("[");
 34                 GetRepeatedJson(tmp_string, msg, goal_field, reflection, Enum_2_Str,Showzero); 
 35                 tmp_string.append("]"); 
 36                 judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);  
 37             }
 38             continue;  
 39         }
 40         switch (goal_field->type())  
 41         {  
 42         case FieldDescriptor::TYPE_MESSAGE:  
 43             {  
 44                 const Message& tmp_msg = reflection->GetMessage(msg, goal_field);  
 45                 if (0 != tmp_msg.ByteSize())  
 46                 { 
 47                     tmp_string="";
 48                     tmp_string.append(""").append(goal_field->name()).append("":");
 49                     NeedEmptyToJson(tmp_string,tmp_msg, Enum_2_Str, Showzero);
 50                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
 51                 }  
 52             }  
 53             break;  
 54             
 55         case FieldDescriptor::TYPE_INT32: 
 56             {
 57                 v32=reflection->GetInt32(msg, goal_field);
 58                 if(v32==0)
 59                 {
 60                     if(Showzero)   //字段值为0,也需要进行打印
 61                     {                        
 62                         tmp_string="";
 63                         tmp_string.append(""").append(goal_field->name()).append("":");
 64                         tmp_string.append(std::to_string(v32)); 
 65                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 66                     }
 67                 }
 68                 else
 69                 {
 70                     tmp_string="";
 71                     tmp_string.append(""").append(goal_field->name()).append("":");
 72                     tmp_string.append(std::to_string(v32));                     
 73                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 74                 } 
 75             }
 76             break;  
 77 
 78         case FieldDescriptor::TYPE_UINT32:
 79             {  
 80                 vu32=reflection->GetUInt32(msg, goal_field);
 81                 if(vu32==0)
 82                 {
 83                     if(Showzero)
 84                     {
 85                         tmp_string="";
 86                         tmp_string.append(""").append(goal_field->name()).append("":");
 87                         tmp_string.append(std::to_string(vu32));  
 88                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 89                     }
 90                 }
 91                 else
 92                 {
 93                     tmp_string="";
 94                     tmp_string.append(""").append(goal_field->name()).append("":");
 95                     tmp_string.append(std::to_string(vu32));
 96                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 97                 }       
 98              }
 99             break;  
100 
101         case FieldDescriptor::TYPE_INT64:  
102             {  
103                 v64=reflection->GetInt64(msg, goal_field);
104                 if(v64==0)
105                 {
106                     if(Showzero)
107                     {
108                         tmp_string="";
109                         tmp_string.append(""").append(goal_field->name()).append("":");         
110                         tmp_string.append(std::to_string(v64));
111                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
112                     }
113                 }
114                 else
115                 {
116                     tmp_string="";
117                     tmp_string.append(""").append(goal_field->name()).append("":");
118                     tmp_string.append(std::to_string(v64));         
119                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);  
120                 } 
121             } 
122             break;  
123         case FieldDescriptor::TYPE_UINT64:  
124              {  
125                 vu64=reflection->GetUInt64(msg, goal_field);
126                 if(vu64==0)
127                 {
128                     if(Showzero)
129                     {
130                         tmp_string="";                
131                         tmp_string.append(""").append(goal_field->name()).append("":");      
132                         tmp_string.append(std::to_string(vu64));
133                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
134                     }
135                 }
136                 else
137                 {
138                     tmp_string="";                
139                     tmp_string.append(""").append(goal_field->name()).append("":");      
140                     tmp_string.append(std::to_string(vu64));
141                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
142                 }
143              } 
144             break;  
145         case FieldDescriptor::TYPE_STRING:  
146         case FieldDescriptor::TYPE_BYTES:  
147             {  
148                 
149                 str=reflection->GetString(msg, goal_field);
150                 if(str.empty())
151                 {
152                     if(Showzero)
153                     {
154                         tmp_string="";
155                         tmp_string.append(""").append(goal_field->name()).append("":");
156                         tmp_string.append(""").append(str).append(""");
157                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
158                     }
159                 }
160                 else
161                 {
162                     tmp_string="";
163                     tmp_string.append(""").append(goal_field->name()).append("":");
164                     tmp_string.append(""").append(str).append(""");
165                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
166 
167                 }
168             }  
169             break; 
170         case FieldDescriptor::TYPE_DOUBLE:
171             {
172                 vd=reflection->GetDouble(msg, goal_field);
173                 if(vd==0)
174                 {
175                     if(Showzero)
176                     {
177                         tmp_string="";
178                         tmp_string.append(""").append(goal_field->name()).append("":");
179                         tmp_string.append(std::to_string(vd));
180                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
181                     }
182                 }
183                 else 
184                 {
185                     tmp_string="";
186                     tmp_string.append(""").append(goal_field->name()).append("":");
187                     tmp_string.append(std::to_string(vd));
188                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
189                 }          
190             } 
191             break;
192         case FieldDescriptor::TYPE_BOOL:
193             {
194                 tmp_string="";
195                 tmp_string.append(""").append(goal_field->name()).append("":");
196                 if (reflection->GetBool(msg, goal_field))
197                     tmp_string.append("true");
198                 else 
199                     tmp_string.append("false");
200                 judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
201               
202             } 
203             break;
204         case FieldDescriptor::TYPE_ENUM:
205             {
206                 tmp_string="";
207                 tmp_string.append(""").append(goal_field->name()).append("":");
208                 if (Enum_2_Str)
209                 {       
210                     tmp_string.append(""").append(reflection->GetEnum(msg,goal_field)->name()).append(""");
211                 }
212                 else 
213                 {
214                     static char enumstr[8];
215                     memset(enumstr, 0, sizeof(enumstr)); 
216                     snprintf(enumstr, sizeof(enumstr), "%d", reflection->GetEnum(msg,goal_field)->number());
217                     tmp_string.append(enumstr);                    
218                 }
219                 judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
220             }
221             break;
222         default:  
223             break;  
224         }
225     }
226     pb2jsonstring.append("}");
227 }

    然后就是需要对repeated的字段进行相应的转换,

  1 void GetRepeatedJson(std::string& pb2jsonstring, const ::google::protobuf::Message& msg, const google::protobuf::FieldDescriptor *goal_field, const ::google::protobuf::Reflection *reflection, bool Enum_2_Str,bool Showzero)  
  2 {     
  3     std::string tmp_string;
  4     int judge=0;
  5     std::int32_t v32=0;
  6     std::uint32_t vu32=0;
  7     std::int64_t v64=0;
  8     std::uint64_t vu64=0;
  9     double vd=0;
 10     std::string str;
 11     for (int i = 0; i < reflection->FieldSize(msg, goal_field); ++i)  
 12     {      
 13         switch (goal_field->type())                 
 14         {  
 15         case FieldDescriptor::TYPE_MESSAGE:  
 16             {  
 17                 const Message& tmp_msg = reflection->GetRepeatedMessage(msg, goal_field, i);
 18                 if (0 != tmp_msg.ByteSize())  
 19                 {                    
 20                     tmp_string="";
 21                     //当重复的是message时,需要全部进行转换,不需要选择特定的字段进行转换,当然有这个需求的也可以进行相应的改进,不过会麻烦一些。重复字段的提取主要就是Get方式的不同,这个可以查阅文章开头中提到的文档,里面有详细说明
 22                     NeedEmptyToJson(tmp_string, tmp_msg, Enum_2_Str,Showzero); 
 23                     judge = AppendTmpString2(pb2jsonstring,tmp_string,judge);
 24                 }
 25             }  
 26             break;  
 27         case FieldDescriptor::TYPE_INT32: 
 28             {               
 29                 v32=reflection->GetRepeatedInt32(msg, goal_field,i);
 30                 if(v32==0)
 31                 {
 32                     if(Showzero)
 33                     {                        
 34                         tmp_string="";
 35                         tmp_string.append(std::to_string(v32)); 
 36                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 37                     }
 38                 }
 39                 else
 40                 {
 41                     tmp_string="";
 42                     tmp_string.append(std::to_string(v32));            
 43                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 44                 } 
 45             } 
 46             
 47             break;  
 48         case FieldDescriptor::TYPE_UINT32:
 49             {               
 50                 vu32=reflection->GetRepeatedUInt32(msg, goal_field,i);
 51                 if(vu32==0)
 52                 {
 53                     if(Showzero)
 54                     {
 55                         tmp_string="";
 56                         tmp_string.append(std::to_string(vu32));  
 57                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 58                     }
 59                 }
 60                 else
 61                 {
 62                     tmp_string="";
 63                     tmp_string.append(std::to_string(vu32)); 
 64                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 65                 }       
 66              }          
 67             break;  
 68         case FieldDescriptor::TYPE_INT64:  
 69             {  
 70                 v64=reflection->GetRepeatedInt64(msg, goal_field,i);
 71                 if(v64==0)
 72                 {
 73                     if(Showzero)
 74                     {
 75                         tmp_string="";      
 76                         tmp_string.append(std::to_string(v64));
 77                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 78                     }
 79                 }
 80                 else
 81                 {
 82                     tmp_string="";
 83                     tmp_string.append(std::to_string(v64));         
 84                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);  
 85                 }
 86             }  
 87             break;  
 88         case FieldDescriptor::TYPE_UINT64:  
 89             {  
 90                 vu64=reflection->GetRepeatedUInt64(msg, goal_field,i);
 91                 if(vu64==0)
 92                 {
 93                     if(Showzero)
 94                     {
 95                         tmp_string="";                      
 96                         tmp_string.append(std::to_string(vu64));
 97                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
 98                     }
 99                 }
100                 else
101                 {
102                     tmp_string="";                    
103                     tmp_string.append(std::to_string(vu64));
104                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge); 
105                 }
106 
107             }  
108             break;  
109         case FieldDescriptor::TYPE_STRING:  
110         case FieldDescriptor::TYPE_BYTES: 
111             {
112                 str="";
113                 str=reflection->GetRepeatedString(msg, goal_field,i);
114                 if(str.empty())
115                 {
116                     if(Showzero)
117                     {
118                         tmp_string="";
119                         tmp_string.append(""").append(str).append(""");
120                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
121                     }
122                 }
123                 else
124                 {
125                     tmp_string="";
126                     tmp_string.append(""").append(str).append(""");
127                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
128 
129                 }
130             }
131             break; 
132         case FieldDescriptor::TYPE_DOUBLE:  
133             {
134                 vd=reflection->GetRepeatedDouble(msg, goal_field,i);
135                 if(vd==0)
136                 {
137                     if(Showzero)
138                     {
139                         tmp_string="";
140                         tmp_string.append(std::to_string(vd));
141                         judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
142                     }
143                 }
144                 else 
145                 {
146                     tmp_string="";
147                     tmp_string.append(std::to_string(vd));
148                     judge = AppendTmpString1(pb2jsonstring,tmp_string,judge);
149                 }
150 
151             }           
152             break; 
153          case FieldDescriptor::TYPE_BOOL:  
154         {
155             tmp_string="";
156             if(reflection->GetRepeatedBool(msg, goal_field,i))
157                 tmp_string.append("true");
158             else
159                 tmp_string.append("false");
160             judge = AppendTmpString2(pb2jsonstring,tmp_string,judge);
161 
162         }           
163         break; 
164         case FieldDescriptor::TYPE_ENUM:
165             {
166                tmp_string="";
167                if (Enum_2_Str)
168                     {                       
169                         tmp_string.append(""").append(reflection->GetRepeatedEnum(msg,goal_field,i)->name()).append(""");                
170                     }
171                 else 
172                     {
173                         static char enumstr[8];
174                         memset(enumstr, 0, sizeof(enumstr)); 
175                         snprintf(enumstr, sizeof(enumstr), "%d", reflection->GetRepeatedEnum(msg,goal_field,i)->number());
176                         tmp_string.append(enumstr);
177                     }
178                 judge = AppendTmpString2(pb2jsonstring,tmp_string,judge);
179             }       
180             break;  
181         default:  
182             break;  
183         }        
184     }    
185 }  
186 int AppendTmpString2(std::string &pb2jsonstring,std::string &tmp_string, int judge)
187 {
188     if( judge!=0 && tmp_string.length()!=0)
189     {
190         pb2jsonstring.append(",").append(tmp_string);
191         return judge;
192     }
193     else if( judge==0 && tmp_string.length()!=0)
194     {
195         pb2jsonstring.append(tmp_string);
196         return 1;
197     }
198     return judge;
199 }

总结说明

    本文中介绍的方法从逻辑上来说没有什么特别的地方,就是读取字段名,字段值然后添加到对应的字符串当中,代码比较繁琐,还有很大的改进空间,后来使用宏定义的##操作减少了很多代码量,比如GetInt()与GetRepeatedInt()可以通过使用“##”操作合并到一个函数中进行操作。

    文中有不合理的地方希望各位批评指正。

 

protobuf.js–protocolbuffers的javascript实现(转)

原文链接:ProtoBuf.js–ProtocolBuffers的Javascript实现推荐前端网址:http://keenwon.com/在Javascript里比较常见的数据格式就是json,xml,但是这两种格式在数据传输方面有明显不足。而ProtocolBuffers可以很好的解决这个问题,下面引用百科的... 查看详情

C ++ Protobuf到/从JSON转换[关闭]

】C++Protobuf到/从JSON转换[关闭]【英文标题】:C++Protobufto/fromJSONconversion[closed]【发布时间】:2011-10-2321:16:15【问题描述】:是否有人熟悉将protobuf消息与JSON相互转换的稳定C++解决方案(库、代码sn-p等)?【问题讨论】:protobuf消... 查看详情

使用 Jackson 将 protobuf 转换为 JSON?

】使用Jackson将protobuf转换为JSON?【英文标题】:ConvertaprotobuftoJSONusingJackson?【发布时间】:2019-01-0609:32:56【问题描述】:使用Jackson的ObjectMapper将protobuf转换为JSON时出现以下错误:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:Dir... 查看详情

Java:JSON -> Protobuf & 反向转换

】Java:JSON->Protobuf&反向转换【英文标题】:Java:JSON->Protobuf&backconversion【发布时间】:2015-04-1704:45:53【问题描述】:我有一个现有系统,它在GUI和服务器之间使用基于protobuf的通信协议。现在我想添加一些持久性,但目... 查看详情

C ++在json中转换protobuf

】C++在json中转换protobuf【英文标题】:C++Convertingprotobufinjson【发布时间】:2018-03-0516:47:14【问题描述】:我正在尝试将一些数据从protobuf连接到json。这是我的代码的相关部分:Message*m;std::stringjson;std::stringbinary_s;...fillthemessage...m-&... 查看详情

使用 ProtoBuf 序列化动态 JSON - Java

】使用ProtoBuf序列化动态JSON-Java【英文标题】:SerializationofDynamicJSONusingProtoBuf-Java【发布时间】:2021-05-0810:51:56【问题描述】:需要一些见解:如何使用Protobuf序列化编写用于序列化包含JSONObject作为属性的javaPOJO类的proto文件。我... 查看详情

如何从二进制 protobuf 中提取 JSON?

】如何从二进制protobuf中提取JSON?【英文标题】:HowtoextractJSONfromabinaryprotobuf?【发布时间】:2018-03-0515:22:13【问题描述】:将ApacheSpark2.2.0结构化流视为:jsonStream.printSchema()root|--body:binary(nullable=true)body内的数据类型为ProtocolBuffersv... 查看详情

在 spring-boot 中将 protobuf 作为 JSON 发送

】在spring-boot中将protobuf作为JSON发送【英文标题】:SendingprotobufasJSONinspring-boot【发布时间】:2019-02-0207:27:34【问题描述】:我正在使用带有这个具体定义的protobufs。messageHashstringcategory=1;repeatedKVPaircontent=2;messageKVPairstringkey=1;stringv... 查看详情

protobuf的简单介绍使用和分析

  Protobuf的简单介绍、使用和分析 一、protobuf是什么?    protobuf(GoogleProtocolBuffers)是Google提供一个具有高效的协议数据交换格式工具库(类似Json),但相比于Json,Protobuf有更高的转化效率,时间效率和空间... 查看详情

golang中使用消息名称创建protobuf消息

golang中根据protobufmessagename动态实例化protobuf消息,消息内容通过输入json文件指定 背景:  项目中使用protobuf作为rpc调用协议,计划用golang实现一个压测工具,希望能够指定messagename和json动态的构建protobuf消息;从json解... 查看详情

[转]序列化悍将protobuf-net,入门动手实录

...篇文章,讲解如何提升性能的,在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打算了解下这个利器 1:安装篇谷歌官方没有提供.net的实现,所以在nuget上找了一个移植的Nuget里搜索Protobuf-net... 查看详情

protobuf详解(代码片段)

protobufprotobuf概述protobuf简介Protobuf是ProtocolBuffers的简称,它是Google公司开发的一种数据描述语言,是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或RPC数据交换格式。可... 查看详情

(转)protobuf-----mac机器安装

...blog.csdn.net/u014534808/article/details/80203018 安装之旅1.下载protobufprotobuf下载页面在此页面选择合适的版本,我选择的是最新的3.5.0,需要注意的mac下是不要下载protoc-3.5.1-xxx的包,因为这些包缺少相关命令,会导致后面安装失败。... 查看详情

protobuf简介

参考技术AProtoBuf是一种无关语言,无关平台的序列化结构数据的方法,可用于通信协议、数据存储等XML:数据较为冗余,需要成对的闭合标签JSON:使用键值对方式,压缩了一定的数据空间并且具有可读性ProtoBuf:适合高性能,对... 查看详情

如何从 protobuf (.proto) 文件中生成 (.json/.yaml) 中的 swagger3 (OpenAPI3) 规范?

】如何从protobuf(.proto)文件中生成(.json/.yaml)中的swagger3(OpenAPI3)规范?【英文标题】:Howtogenerateswagger3(OpenAPI3)specin(.json/.yaml)fromprotobuf(.proto)files?【发布时间】:2020-04-2118:03:08【问题描述】:我原来的用例:我正在使用gRPC服务器(... 查看详情

java序列化:protobuf与json的比较(代码片段)

1.概述转载:序列化:ProtoBuf与JSON的比较!介绍ProtoBuf是google团队开发的用于高效存储和读取结构化数据的工具。什么是结构化数据呢,正如字面上表达的,就是带有一定结构的数据。比如电话簿上有很多记录... 查看详情

使用 zap logger 将 protobuf 消息正确记录为未转义的 JSON

】使用zaplogger将protobuf消息正确记录为未转义的JSON【英文标题】:CorrectlylogprotobufmessagesasunescapedJSONwithzaplogger【发布时间】:2021-09-2510:11:35【问题描述】:我有一个Go项目,我在其中使用Zap结构化日志记录来记录结构的内容。这... 查看详情

netty使用protobuf序列化,太强大了!(代码片段)

...rickiyang出处:www.cnblogs.com/rickiyang/p/11074232.html我们来使用Protobuf进行序列化,它和XML,json一样都有自己的语法,xml的后缀是.xml,json文件的后缀是.json,自然Protobuf文件的后缀就是.proto(哈哈,当然不是全称)。下面我们使用Protobu... 查看详情