方法介绍

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

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