方法介紹
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()可以通過使用“##”操作合並到一個函數中進行操作。
文中有不合理的地方希望各位批評指正。