方法介绍
protobuf的介绍在这里就不详细介绍了,主要是俺也是刚接触,感兴趣的同学可以去搜索相关博客或者直接去看源码以及google的官方文档(官方文档表示很吃力)或者去这个网站:https://developers.google.com/protocol-buffers/docs/overview查看相应内容,这里面内容很全面,可以很方面的查询各个函数的使用方法以及功能。本篇文章主要介绍一下本人最近做的一个protobuf转json的小工具,下面进行拆分讲解,完整的代码在:git@github.com:chengfeiGitHub/P-bToJson.git。
protobuf自带一个MessageToJson()的函数可以将对应的消息转换成json,一般情况下该函数可以满足转换需求。但是,最近项目的要求使用MessageToJson()无法实现,主要要求是:
- 选择特定的messge进行转换(主要是提供包含需求字段号的set或者vector,根据提供的字段号进行转换);
- 对于Enum类型的消息,可以选择显示枚举名或者枚举值;
- 对于字段值为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()可以通过使用“##”操作合并到一个函数中进行操作。
文中有不合理的地方希望各位批评指正。