brpc_protobuf_json_unittest.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. #include <sys/time.h>
  18. #include <gtest/gtest.h>
  19. #include <iostream>
  20. #include <fstream>
  21. #include <string>
  22. #include <google/protobuf/text_format.h>
  23. #include "butil/iobuf.h"
  24. #include "butil/third_party/rapidjson/rapidjson.h"
  25. #include "butil/time.h"
  26. #include "butil/gperftools_profiler.h"
  27. #include "json2pb/pb_to_json.h"
  28. #include "json2pb/json_to_pb.h"
  29. #include "json2pb/encode_decode.h"
  30. #include "message.pb.h"
  31. #include "addressbook1.pb.h"
  32. #include "addressbook.pb.h"
  33. #include "addressbook_encode_decode.pb.h"
  34. #include "addressbook_map.pb.h"
  35. namespace { // just for coding-style check
  36. using addressbook::AddressBook;
  37. using addressbook::Person;
  38. class ProtobufJsonTest : public testing::Test {
  39. protected:
  40. void SetUp() {}
  41. void TearDown() {}
  42. };
  43. inline int64_t gettimeofday_us() {
  44. timeval now;
  45. gettimeofday(&now, NULL);
  46. return now.tv_sec * 1000000L + now.tv_usec;
  47. }
  48. TEST_F(ProtobufJsonTest, json_to_pb_normal_case) {
  49. const int N = 1000;
  50. int64_t total_tm = 0;
  51. int64_t total_tm2 = 0;
  52. for (int i = 0; i < N; ++i) {
  53. std::string info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\"ext\":"
  54. "{\"age\":1666666666, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":1},"
  55. "\"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,"
  56. "\"ext\":{\"age\":1666666660, \"databyte\":\"d2VsY29tZQ==\","
  57. "\"enumtype\":2},\"uid\":\"someone0\"}], \"judge\":false,"
  58. "\"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  59. std::string error;
  60. JsonContextBody data;
  61. const int64_t tm1 = gettimeofday_us();
  62. const bool ret = json2pb::JsonToProtoMessage(info3, &data, &error);
  63. const int64_t tm2 = gettimeofday_us();
  64. total_tm += tm2 - tm1;
  65. ASSERT_TRUE(ret);
  66. std::string info4;
  67. std::string error1;
  68. const int64_t tm3 = gettimeofday_us();
  69. bool ret2 = json2pb::ProtoMessageToJson(data, &info4, &error1);
  70. const int64_t tm4 = gettimeofday_us();
  71. ASSERT_TRUE(ret2);
  72. total_tm2 += tm4 - tm3;
  73. #ifndef RAPIDJSON_VERSION_0_1
  74. ASSERT_STREQ("{\"data\":[1,2,3,4,5,6,7,8,9,10],"
  75. "\"judge\":false,\"spur\":2.0,\"content\":[{\"uid\":\"someone\","
  76. "\"distance\":1.0,\"ext\":{\"age\":1666666666,\"databyte\":\"d2VsY29tZQ==\","
  77. "\"enumtype\":\"HOME\"}},\{\"uid\":\"someone0\",\"distance\":10.0,\"ext\":"
  78. "{\"age\":1666666660,\"databyte\":\"d2VsY29tZQ==\",\"enumtype\":\"WORK\"}}]}",
  79. info4.data());
  80. #else
  81. ASSERT_STREQ("{\"data\":[1,2,3,4,5,6,7,8,9,10],"
  82. "\"judge\":false,\"spur\":2,\"content\":[{\"uid\":\"someone\","
  83. "\"distance\":1,\"ext\":{\"age\":1666666666,\"databyte\":\"d2VsY29tZQ==\","
  84. "\"enumtype\":\"HOME\"}},\{\"uid\":\"someone0\",\"distance\":10,\"ext\":"
  85. "{\"age\":1666666660,\"databyte\":\"d2VsY29tZQ==\",\"enumtype\":\"WORK\"}}]}",
  86. info4.data());
  87. #endif
  88. }
  89. std::cout << "json2pb=" << total_tm / N
  90. << "us pb2json=" << total_tm2 / N << "us"
  91. << std::endl;
  92. }
  93. TEST_F(ProtobufJsonTest, json_base64_string_to_pb_types_case) {
  94. std::string info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\"ext\":"
  95. "{\"age\":1666666666, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":1},"
  96. "\"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,"
  97. "\"ext\":{\"age\":1666666660, \"databyte\":\"d2VsY29tZTA=\","
  98. "\"enumtype\":2},\"uid\":\"someone0\"}], \"judge\":false,"
  99. "\"spur\":2}";
  100. std::string error;
  101. JsonContextBody data;
  102. json2pb::Json2PbOptions options_j2pb;
  103. options_j2pb.base64_to_bytes = true;
  104. const bool ret = json2pb::JsonToProtoMessage(info3, &data, options_j2pb, &error);
  105. ASSERT_TRUE(ret);
  106. ASSERT_TRUE(data.content_size() == 2);
  107. ASSERT_EQ(data.content(0).ext().databyte(), "welcome");
  108. ASSERT_EQ(data.content(1).ext().databyte(), "welcome0");
  109. std::string info4;
  110. std::string error1;
  111. json2pb::Pb2JsonOptions options_pb2j;
  112. options_pb2j.bytes_to_base64 = true;
  113. bool ret2 = json2pb::ProtoMessageToJson(data, &info4, options_pb2j, &error1);
  114. ASSERT_TRUE(ret2);
  115. #ifndef RAPIDJSON_VERSION_0_1
  116. ASSERT_STREQ("{\"judge\":false,\"spur\":2.0,\"content\":[{\"uid\":\"someone\","
  117. "\"distance\":1.0,\"ext\":{\"age\":1666666666,\"databyte\":\"d2VsY29tZQ==\","
  118. "\"enumtype\":\"HOME\"}},\{\"uid\":\"someone0\",\"distance\":10.0,\"ext\":"
  119. "{\"age\":1666666660,\"databyte\":\"d2VsY29tZTA=\",\"enumtype\":\"WORK\"}}]}",
  120. info4.data());
  121. #else
  122. ASSERT_STREQ("{\"judge\":false,\"spur\":2,\"content\":[{\"uid\":\"someone\","
  123. "\"distance\":1,\"ext\":{\"age\":1666666666,\"databyte\":\"d2VsY29tZQ==\","
  124. "\"enumtype\":\"HOME\"}},\{\"uid\":\"someone0\",\"distance\":10,\"ext\":"
  125. "{\"age\":1666666660,\"databyte\":\"d2VsY29tZTA=\",\"enumtype\":\"WORK\"}}]}",
  126. info4.data());
  127. #endif
  128. }
  129. TEST_F(ProtobufJsonTest, json_to_pb_map_case) {
  130. std::string json = "{\"addr\":\"baidu.com\","
  131. "\"numbers\":{\"tel\":123456,\"cell\":654321},"
  132. "\"contacts\":{\"email\":\"frank@baidu.com\","
  133. " \"office\":\"Shanghai\"},"
  134. "\"friends\":{\"John\":[{\"school\":\"SJTU\",\"year\":2007}]}}";
  135. std::string error;
  136. AddressNoMap ab1;
  137. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab1, &error));
  138. ASSERT_EQ("baidu.com", ab1.addr());
  139. AddressIntMap ab2;
  140. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab2, &error));
  141. ASSERT_EQ("baidu.com", ab2.addr());
  142. ASSERT_EQ("tel", ab2.numbers(0).key());
  143. ASSERT_EQ(123456, ab2.numbers(0).value());
  144. ASSERT_EQ("cell", ab2.numbers(1).key());
  145. ASSERT_EQ(654321, ab2.numbers(1).value());
  146. AddressStringMap ab3;
  147. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab3, &error));
  148. ASSERT_EQ("baidu.com", ab3.addr());
  149. ASSERT_EQ("email", ab3.contacts(0).key());
  150. ASSERT_EQ("frank@baidu.com", ab3.contacts(0).value());
  151. ASSERT_EQ("office", ab3.contacts(1).key());
  152. ASSERT_EQ("Shanghai", ab3.contacts(1).value());
  153. AddressComplex ab4;
  154. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab4, &error)) << error;
  155. ASSERT_EQ("baidu.com", ab4.addr());
  156. ASSERT_EQ("John", ab4.friends(0).key());
  157. ASSERT_EQ("SJTU", ab4.friends(0).value(0).school());
  158. ASSERT_EQ(2007, ab4.friends(0).value(0).year());
  159. std::string old_json = "{\"addr\":\"baidu.com\","
  160. "\"numbers\":[{\"key\":\"tel\",\"value\":123456},"
  161. " {\"key\":\"cell\",\"value\":654321}]}";
  162. ab2.Clear();
  163. ASSERT_TRUE(json2pb::JsonToProtoMessage(old_json, &ab2, &error)) << error;
  164. ASSERT_EQ("baidu.com", ab2.addr());
  165. ASSERT_EQ("tel", ab2.numbers(0).key());
  166. ASSERT_EQ(123456, ab2.numbers(0).value());
  167. ASSERT_EQ("cell", ab2.numbers(1).key());
  168. ASSERT_EQ(654321, ab2.numbers(1).value());
  169. }
  170. TEST_F(ProtobufJsonTest, json_to_pb_encode_decode) {
  171. std::string info3 = "{\"@Content_Test%@\":[{\"Distance_info_\":1,\
  172. \"_ext%T_\":{\"Aa_ge(\":1666666666, \"databyte(std::string)\":\
  173. \"d2VsY29tZQ==\", \"enum--type\":\"HOME\"},\"uid*\":\"welcome\"}], \
  174. \"judge\":false, \"spur\":2, \"data:array\":[]}";
  175. printf("----------test json to pb------------\n\n");
  176. std::string error;
  177. JsonContextBodyEncDec data;
  178. ASSERT_TRUE(json2pb::JsonToProtoMessage(info3, &data, &error));
  179. std::string info4;
  180. std::string error1;
  181. ASSERT_TRUE(json2pb::ProtoMessageToJson(data, &info4, &error1));
  182. #ifndef RAPIDJSON_VERSION_0_1
  183. ASSERT_STREQ("{\"judge\":false,\"spur\":2.0,"
  184. "\"@Content_Test%@\":[{\"uid*\":\"welcome\",\"Distance_info_\":1.0,"
  185. "\"_ext%T_\":{\"Aa_ge(\":1666666666,\"databyte(std::string)\":\"d2VsY29tZQ==\","
  186. "\"enum--type\":\"HOME\"}}]}", info4.data());
  187. #else
  188. ASSERT_STREQ("{\"judge\":false,\"spur\":2,"
  189. "\"@Content_Test%@\":[{\"uid*\":\"welcome\",\"Distance_info_\":1,"
  190. "\"_ext%T_\":{\"Aa_ge(\":1666666666,\"databyte(std::string)\":\"d2VsY29tZQ==\","
  191. "\"enum--type\":\"HOME\"}}]}", info4.data());
  192. #endif
  193. }
  194. TEST_F(ProtobufJsonTest, json_to_pb_unicode_case) {
  195. AddressBook address_book;
  196. Person* person = address_book.add_person();
  197. person->set_id(100);
  198. char name[255 * 1024];
  199. for (int j = 0; j < 255; j++) {
  200. for (int i = 0; i < 1024; i++) {
  201. name[j*1024 + i] = i + 1;
  202. }
  203. }
  204. name[255 * 1024 - 1] = '\0';
  205. person->set_name(name);
  206. person->set_data(-240000000);
  207. person->set_data32(6);
  208. person->set_data64(-1820000000);
  209. person->set_datadouble(123.456);
  210. person->set_datadouble_scientific(1.23456789e+08);
  211. person->set_datafloat_scientific(1.23456789e+08);
  212. person->set_datafloat(8.6123);
  213. person->set_datau32(60);
  214. person->set_datau64(960);
  215. person->set_databool(0);
  216. person->set_databyte("welcome to china");
  217. person->set_datafix32(1);
  218. person->set_datafix64(666);
  219. person->set_datasfix32(120);
  220. person->set_datasfix64(-802);
  221. std::string info1;
  222. std::string error;
  223. google::protobuf::TextFormat::Printer printer;
  224. std::string text;
  225. printer.PrintToString(*person, &text);
  226. printf("----------test pb to json------------\n\n");
  227. bool ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  228. ASSERT_TRUE(ret);
  229. AddressBook address_book_test;
  230. ret = json2pb::JsonToProtoMessage(info1, &address_book_test, &error);
  231. ASSERT_TRUE(ret);
  232. std::string info2;
  233. ret = json2pb::ProtoMessageToJson(address_book_test, &info2, &error);
  234. ASSERT_TRUE(ret);
  235. ASSERT_TRUE(!info1.compare(info2));
  236. butil::IOBuf buf;
  237. butil::IOBufAsZeroCopyOutputStream stream(&buf);
  238. bool res = json2pb::ProtoMessageToJson(address_book, &stream, NULL);
  239. ASSERT_TRUE(res);
  240. butil::IOBufAsZeroCopyInputStream stream2(buf);
  241. AddressBook address_book_test3;
  242. ret = json2pb::JsonToProtoMessage(&stream2, &address_book_test3, &error);
  243. ASSERT_TRUE(ret);
  244. std::string info3;
  245. ret = json2pb::ProtoMessageToJson(address_book_test3, &info3, &error);
  246. ASSERT_TRUE(ret);
  247. ASSERT_TRUE(!info2.compare(info3));
  248. }
  249. TEST_F(ProtobufJsonTest, json_to_pb_edge_case) {
  250. std::string info3 = "{\"judge\":false, \"spur\":2.0e1}";
  251. std::string error;
  252. JsonContextBody data;
  253. bool ret = json2pb::JsonToProtoMessage(info3, &data, &error);
  254. ASSERT_TRUE(ret);
  255. std::string info4;
  256. std::string error1;
  257. ret = json2pb::ProtoMessageToJson(data, &info4, &error1);
  258. ASSERT_TRUE(ret);
  259. info3 = "{\"judge\":false, \"spur\":-2, \"data\":[], \"info\":[],\"content\":[]}";
  260. error.clear();
  261. JsonContextBody data1;
  262. ret = json2pb::JsonToProtoMessage(info3, &data1, &error);
  263. ASSERT_TRUE(ret);
  264. info4.clear();
  265. error1.clear();
  266. ret = json2pb::ProtoMessageToJson(data1, &info4, &error1);
  267. ASSERT_TRUE(ret);
  268. info3 = "{\"judge\":false, \"spur\":\"NaN\"}";
  269. error.clear();
  270. JsonContextBody data2;
  271. ret = json2pb::JsonToProtoMessage(info3, &data2, &error);
  272. ASSERT_TRUE(ret);
  273. info4.clear();
  274. error1.clear();
  275. ret = json2pb::ProtoMessageToJson(data2, &info4, &error1);
  276. ASSERT_TRUE(ret);
  277. info3 = "{\"judge\":false, \"spur\":\"Infinity\"}";
  278. error.clear();
  279. JsonContextBody data3;
  280. ret = json2pb::JsonToProtoMessage(info3, &data3, &error);
  281. ASSERT_TRUE(ret);
  282. info4.clear();
  283. error1.clear();
  284. ret = json2pb::ProtoMessageToJson(data3, &info4, &error1);
  285. ASSERT_TRUE(ret);
  286. info3 = "{\"judge\":false, \"spur\":\"-inFiNITY\"}";
  287. error.clear();
  288. JsonContextBody data4;
  289. ret = json2pb::JsonToProtoMessage(info3, &data4, &error);
  290. ASSERT_TRUE(ret);
  291. info4.clear();
  292. error1.clear();
  293. ret = json2pb::ProtoMessageToJson(data4, &info4, &error1);
  294. ASSERT_TRUE(ret);
  295. info3 = "{\"judge\":false, \"spur\":2.0, \"content\":[{\"distance\":2.5, "
  296. "\"ext\":{\"databyte\":\"d2VsY29tZQ==\", \"enumtype\":\"MOBILE\"}}]}";
  297. error.clear();
  298. JsonContextBody data5;
  299. ret = json2pb::JsonToProtoMessage(info3, &data5, &error);
  300. ASSERT_TRUE(ret);
  301. info4.clear();
  302. error1.clear();
  303. ret = json2pb::ProtoMessageToJson(data5, &info4, &error1);
  304. ASSERT_TRUE(ret);
  305. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  306. \"ext\":{\"age\":1666666666, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":1},\
  307. \"uid\":\"someone\"},{\"distance\":2.3,\"unknown_member\":20,\
  308. \"ext\":{\"age\":1666666660, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":\"Test\"},\
  309. \"uid\":\"someone0\"}], \"judge\":false, \
  310. \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  311. error.clear();
  312. JsonContextBody data9;
  313. ret = json2pb::JsonToProtoMessage(info3, &data9, &error);
  314. ASSERT_TRUE(ret);
  315. ASSERT_STREQ("Invalid value `\"Test\"' for optional field `Ext.enumtype' which SHOULD be enum", error.data());
  316. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  317. \"ext\":{\"age\":1666666666, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":1},\
  318. \"uid\":\"someone\"},{\"distance\":5,\"unknown_member\":20,\
  319. \"ext\":{\"age\":1666666660, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":15},\
  320. \"uid\":\"someone0\"}], \"judge\":false, \
  321. \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  322. error.clear();
  323. JsonContextBody data10;
  324. ret = json2pb::JsonToProtoMessage(info3, &data10, &error);
  325. ASSERT_TRUE(ret);
  326. ASSERT_STREQ("Invalid value `15' for optional field `Ext.enumtype' which SHOULD be enum", error.data());
  327. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  328. \"ext\":{\"age\":1666666666, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":1},\
  329. \"uid\":\"someone\"},{\"distance\":5,\"unknown_member\":20,\
  330. \"ext\":{\"age\":1666666660, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":15},\
  331. \"uid\":\"someone0\"}], \"judge\":false, \
  332. \"spur\":2, \"type\":[\"123\"]}";
  333. error.clear();
  334. JsonContextBody data11;
  335. ret = json2pb::JsonToProtoMessage(info3, &data11, &error);
  336. ASSERT_TRUE(ret);
  337. ASSERT_STREQ("Invalid value `array' for optional field `JsonContextBody.type' which SHOULD be INT64, Invalid value `15' for optional field `Ext.enumtype' which SHOULD be enum",
  338. error.data());
  339. }
  340. TEST_F(ProtobufJsonTest, json_to_pb_expected_failed_case) {
  341. std::string info3 = "{\"content\":[{\"unknown_member\":2,\"ext\":{\"age\":1666666666, \
  342. \"databyte\":\"welcome\", \"enumtype\":1},\"uid\":\"someone\"},\
  343. {\"unknown_member\":20,\"ext\":{\"age\":1666666660, \"databyte\":\
  344. \"welcome0\", \"enumtype\":2},\"uid\":\"someone0\"}], \
  345. \"judge\":false, \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  346. std::string error;
  347. JsonContextBody data;
  348. bool ret = json2pb::JsonToProtoMessage(info3, &data, &error);
  349. ASSERT_FALSE(ret);
  350. ASSERT_STREQ("Missing required field: Content.distance", error.data());
  351. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\"ext\":{\"age\":1666666666, \
  352. \"enumtype\":1},\"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,\
  353. \"ext\":{\"age\":1666666660, \"databyte\":\"welcome0\", \"enumtype\":2},\
  354. \"uid\":\"someone0\"}], \"judge\":false, \
  355. \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  356. error.clear();
  357. JsonContextBody data2;
  358. ret = json2pb::JsonToProtoMessage(info3, &data2, &error);
  359. ASSERT_FALSE(ret);
  360. ASSERT_STREQ("Missing required field: Ext.databyte", error.data());
  361. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  362. \"ext\":{\"age\":1666666666, \"databyte\":\"welcome\", \"enumtype\":1},\
  363. \"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,\
  364. \"ext\":{\"age\":1666666660, \"databyte\":\"welcome0\", \"enumtype\":2},\
  365. \"uid\":\"someone0\"}], \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  366. error.clear();
  367. JsonContextBody data3;
  368. ret = json2pb::JsonToProtoMessage(info3, &data, &error);
  369. ASSERT_FALSE(ret);
  370. ASSERT_STREQ("Missing required field: JsonContextBody.judge", error.data());
  371. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  372. \"ext\":{\"age\":1666666666, \"databyte\":\"welcome\", \"enumtype\":1},\
  373. \"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,\
  374. \"ext\":{\"age\":1666666660, \"databyte\":\"welcome0\", \"enumtype\":2},\
  375. \"uid\":\"someone0\"}], \"judge\":\"false\", \
  376. \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  377. error.clear();
  378. JsonContextBody data4;
  379. ret = json2pb::JsonToProtoMessage(info3, &data4, &error);
  380. ASSERT_FALSE(ret);
  381. ASSERT_STREQ("Invalid value `\"false\"' for field `JsonContextBody.judge' which SHOULD be BOOL", error.data());
  382. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  383. \"ext\":{\"age\":1666666666, \"databyte\":\"welcome\", \"enumtype\":1},\
  384. \"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,\
  385. \"ext\":{\"age\":1666666660, \"databyte\":\"welcome0\", \"enumtype\":2},\
  386. \"uid\":\"someone0\"}], \"judge\":false, \
  387. \"spur\":2, \"data\":[\"1\",\"2\",\"3\",\"4\"]}";
  388. error.clear();
  389. JsonContextBody data5;
  390. ret = json2pb::JsonToProtoMessage(info3, &data5, &error);
  391. ASSERT_FALSE(ret);
  392. ASSERT_STREQ("Invalid value `\"1\"' for field `JsonContextBody.data' which SHOULD be INT32", error.data());
  393. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\
  394. \"ext\":{\"age\":1666666666, \"databyte\":\"welcome\", \"enumtype\":1},\
  395. \"uid\":\"someone\"},{\"distance\":10,\"unknown_member\":20,\
  396. \"ext\":{\"age\":1666666660, \"databyte\":\"welcome0\", \"enumtype\":2},\
  397. \"uid\":\"someone0\"}], \"judge\":false, \
  398. \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10], \"info\":2}";
  399. error.clear();
  400. JsonContextBody data6;
  401. ret = json2pb::JsonToProtoMessage(info3, &data6, &error);
  402. ASSERT_FALSE(ret);
  403. ASSERT_STREQ("Invalid value for repeated field: JsonContextBody.info", error.data());
  404. info3 = "{\"judge\":false, \"spur\":\"NaNa\"}";
  405. error.clear();
  406. JsonContextBody data7;
  407. ret = json2pb::JsonToProtoMessage(info3, &data7, &error);
  408. ASSERT_FALSE(ret);
  409. ASSERT_STREQ("Invalid value `\"NaNa\"' for field `JsonContextBody.spur' which SHOULD be d",
  410. error.data());
  411. info3 = "{\"judge\":false, \"spur\":\"Infinty\"}";
  412. error.clear();
  413. JsonContextBody data8;
  414. ret = json2pb::JsonToProtoMessage(info3, &data8, &error);
  415. ASSERT_FALSE(ret);
  416. ASSERT_STREQ("Invalid value `\"Infinty\"' for field `JsonContextBody.spur' which SHOULD be d",
  417. error.data());
  418. info3 = "{\"content\":[{\"distance\":1,\"unknown_member\":2,\"ext\":{\"age\":1666666666, \
  419. \"enumtype\":1},\"uid\":23},{\"distance\":10,\"unknown_member\":20,\
  420. \"ext\":{\"age\":1666666660, \"databyte\":\"welcome0\", \"enumtype\":2},\
  421. \"uid\":\"someone0\"}], \"judge\":false, \
  422. \"spur\":2, \"data\":[1,2,3,4,5,6,7,8,9,10]}";
  423. error.clear();
  424. JsonContextBody data9;
  425. ret = json2pb::JsonToProtoMessage(info3, &data9, &error);
  426. ASSERT_FALSE(ret);
  427. ASSERT_STREQ("Invalid value `23' for optional field `Content.uid' which SHOULD be string, Missing required field: Ext.databyte", error.data());
  428. }
  429. TEST_F(ProtobufJsonTest, json_to_pb_perf_case) {
  430. std::string info3 = "{\"content\":[{\"distance\":1.0,\
  431. \"ext\":{\"age\":1666666666, \"databyte\":\"d2VsY29tZQ==\", \"enumtype\":1},\
  432. \"uid\":\"welcome\"}], \"judge\":false, \"spur\":2.0, \"data\":[]}";
  433. printf("----------test json to pb performance------------\n\n");
  434. std::string error;
  435. ProfilerStart("json_to_pb_perf.prof");
  436. butil::Timer timer;
  437. bool res;
  438. float avg_time1 = 0;
  439. float avg_time2 = 0;
  440. const int times = 100000;
  441. for (int i = 0; i < times; i++) {
  442. JsonContextBody data;
  443. timer.start();
  444. res = json2pb::JsonToProtoMessage(info3, &data, &error);
  445. timer.stop();
  446. avg_time1 += timer.u_elapsed();
  447. ASSERT_TRUE(res);
  448. std::string info4;
  449. std::string error1;
  450. timer.start();
  451. res = json2pb::ProtoMessageToJson(data, &info4, &error1);
  452. timer.stop();
  453. avg_time2 += timer.u_elapsed();
  454. ASSERT_TRUE(res);
  455. }
  456. avg_time1 /= times;
  457. avg_time2 /= times;
  458. ProfilerStop();
  459. printf("avg time to convert json to pb is %fus\n", avg_time1);
  460. printf("avg time to convert pb to json is %fus\n", avg_time2);
  461. }
  462. TEST_F(ProtobufJsonTest, json_to_pb_encode_decode_perf_case) {
  463. std::string info3 = "{\"@Content_Test%@\":[{\"Distance_info_\":1,\
  464. \"_ext%T_\":{\"Aa_ge(\":1666666666, \"databyte(std::string)\":\
  465. \"welcome\", \"enum--type\":1},\"uid*\":\"welcome\"}], \
  466. \"judge\":false, \"spur\":2, \"data:array\":[]}";
  467. printf("----------test json to pb encode/decode performance------------\n\n");
  468. std::string error;
  469. ProfilerStart("json_to_pb_encode_decode_perf.prof");
  470. butil::Timer timer;
  471. bool res;
  472. float avg_time1 = 0;
  473. float avg_time2 = 0;
  474. const int times = 100000;
  475. for (int i = 0; i < times; i++) {
  476. JsonContextBody data;
  477. timer.start();
  478. res = json2pb::JsonToProtoMessage(info3, &data, &error);
  479. timer.stop();
  480. avg_time1 += timer.u_elapsed();
  481. ASSERT_TRUE(res);
  482. std::string info4;
  483. std::string error1;
  484. timer.start();
  485. res = json2pb::ProtoMessageToJson(data, &info4, &error1);
  486. timer.stop();
  487. avg_time2 += timer.u_elapsed();
  488. ASSERT_TRUE(res);
  489. }
  490. avg_time1 /= times;
  491. avg_time2 /= times;
  492. ProfilerStop();
  493. printf("avg time to convert json to pb is %fus\n", avg_time1);
  494. printf("avg time to convert pb to json is %fus\n", avg_time2);
  495. }
  496. TEST_F(ProtobufJsonTest, json_to_pb_complex_perf_case) {
  497. std::ifstream in("jsonout", std::ios::in);
  498. std::ostringstream tmp;
  499. tmp << in.rdbuf();
  500. butil::IOBuf buf;
  501. buf.append(tmp.str());
  502. in.close();
  503. printf("----------test json to pb performance------------\n\n");
  504. std::string error;
  505. butil::Timer timer;
  506. bool res;
  507. float avg_time1 = 0;
  508. const int times = 10000;
  509. json2pb::Json2PbOptions options;
  510. options.base64_to_bytes = false;
  511. ProfilerStart("json_to_pb_complex_perf.prof");
  512. for (int i = 0; i < times; i++) {
  513. gss::message::gss_us_res_t data;
  514. butil::IOBufAsZeroCopyInputStream stream(buf);
  515. timer.start();
  516. res = json2pb::JsonToProtoMessage(&stream, &data, options, &error);
  517. timer.stop();
  518. avg_time1 += timer.u_elapsed();
  519. ASSERT_TRUE(res);
  520. }
  521. ProfilerStop();
  522. avg_time1 /= times;
  523. printf("avg time to convert json to pb is %fus\n", avg_time1);
  524. }
  525. TEST_F(ProtobufJsonTest, json_to_pb_to_string_complex_perf_case) {
  526. std::ifstream in("jsonout", std::ios::in);
  527. std::ostringstream tmp;
  528. tmp << in.rdbuf();
  529. std::string info3 = tmp.str();
  530. in.close();
  531. printf("----------test json to pb performance------------\n\n");
  532. std::string error;
  533. butil::Timer timer;
  534. bool res;
  535. float avg_time1 = 0;
  536. const int times = 10000;
  537. json2pb::Json2PbOptions options;
  538. options.base64_to_bytes = false;
  539. ProfilerStart("json_to_pb_to_string_complex_perf.prof");
  540. for (int i = 0; i < times; i++) {
  541. gss::message::gss_us_res_t data;
  542. timer.start();
  543. res = json2pb::JsonToProtoMessage(info3, &data, options, &error);
  544. timer.stop();
  545. avg_time1 += timer.u_elapsed();
  546. ASSERT_TRUE(res);
  547. }
  548. avg_time1 /= times;
  549. ProfilerStop();
  550. printf("avg time to convert json to pb is %fus\n", avg_time1);
  551. }
  552. TEST_F(ProtobufJsonTest, pb_to_json_normal_case) {
  553. AddressBook address_book;
  554. Person* person = address_book.add_person();
  555. person->set_id(100);
  556. person->set_name("baidu");
  557. person->set_email("welcome@baidu.com");
  558. Person::PhoneNumber* phone_number = person->add_phone();
  559. phone_number->set_number("number123");
  560. phone_number->set_type(Person::HOME);
  561. person->set_data(-240000000);
  562. person->set_data32(6);
  563. person->set_data64(-1820000000);
  564. person->set_datadouble(123.456);
  565. person->set_datadouble_scientific(1.23456789e+08);
  566. person->set_datafloat_scientific(1.23456789e+08);
  567. person->set_datafloat(8.6123);
  568. person->set_datau32(60);
  569. person->set_datau64(960);
  570. person->set_databool(0);
  571. person->set_databyte("welcome");
  572. person->set_datafix32(1);
  573. person->set_datafix64(666);
  574. person->set_datasfix32(120);
  575. person->set_datasfix64(-802);
  576. std::string info1;
  577. google::protobuf::TextFormat::Printer printer;
  578. std::string text;
  579. printer.PrintToString(*person, &text);
  580. printf("text:%s\n", text.data());
  581. printf("----------test pb to json------------\n\n");
  582. json2pb::Pb2JsonOptions option;
  583. option.bytes_to_base64 = true;
  584. bool ret = json2pb::ProtoMessageToJson(address_book, &info1, option, NULL);
  585. ASSERT_TRUE(ret);
  586. #ifndef RAPIDJSON_VERSION_0_1
  587. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  588. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  589. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  590. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  591. "\"databool\":false,\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,"
  592. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  593. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  594. info1.data());
  595. #else
  596. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  597. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  598. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  599. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,\"databool\":false,"
  600. "\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,\"datafix64\":666,"
  601. "\"datasfix32\":120,\"datasfix64\":-802,\"datafloat_scientific\":123456792,"
  602. "\"datadouble_scientific\":123456789}]}", info1.data());
  603. #endif
  604. info1.clear();
  605. {
  606. json2pb::Pb2JsonOptions option;
  607. option.bytes_to_base64 = true;
  608. ret = ProtoMessageToJson(address_book, &info1, option, NULL);
  609. }
  610. ASSERT_TRUE(ret);
  611. #ifndef RAPIDJSON_VERSION_0_1
  612. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  613. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  614. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  615. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  616. "\"databool\":false,\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,"
  617. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  618. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  619. info1.data());
  620. #else
  621. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  622. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  623. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  624. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,\"databool\":false,"
  625. "\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,\"datafix64\":666,"
  626. "\"datasfix32\":120,\"datasfix64\":-802,\"datafloat_scientific\":123456792,"
  627. "\"datadouble_scientific\":123456789}]}", info1.data());
  628. #endif
  629. info1.clear();
  630. {
  631. json2pb::Pb2JsonOptions option;
  632. option.bytes_to_base64 = true;
  633. option.enum_option = json2pb::OUTPUT_ENUM_BY_NUMBER;
  634. ret = ProtoMessageToJson(address_book, &info1, option, NULL);
  635. }
  636. ASSERT_TRUE(ret);
  637. #ifndef RAPIDJSON_VERSION_0_1
  638. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  639. "\"phone\":[{\"number\":\"number123\",\"type\":1}],\"data\":-240000000,"
  640. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  641. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  642. "\"databool\":false,\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,"
  643. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  644. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  645. info1.data());
  646. #else
  647. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  648. "\"phone\":[{\"number\":\"number123\",\"type\":1}],\"data\":-240000000,"
  649. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  650. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,\"databool\":false,"
  651. "\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,\"datafix64\":666,"
  652. "\"datasfix32\":120,\"datasfix64\":-802,\"datafloat_scientific\":123456792,"
  653. "\"datadouble_scientific\":123456789}]}", info1.data());
  654. #endif
  655. printf("----------test json to pb------------\n\n");
  656. const int N = 1000;
  657. int64_t total_tm = 0;
  658. int64_t total_tm2 = 0;
  659. for (int i = 0; i < N; ++i) {
  660. std::string info3;
  661. AddressBook data1;
  662. std::string error1;
  663. const int64_t tm1 = gettimeofday_us();
  664. bool ret1 = json2pb::JsonToProtoMessage(info1, &data1, &error1);
  665. const int64_t tm2 = gettimeofday_us();
  666. total_tm += tm2 - tm1;
  667. ASSERT_TRUE(ret1);
  668. std::string error2;
  669. const int64_t tm3 = gettimeofday_us();
  670. ret1 = json2pb::ProtoMessageToJson(data1, &info3, &error2);
  671. const int64_t tm4 = gettimeofday_us();
  672. ASSERT_TRUE(ret1);
  673. total_tm2 += tm4 - tm3;
  674. #ifndef RAPIDJSON_VERSION_0_1
  675. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  676. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  677. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  678. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  679. "\"databool\":false,\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,"
  680. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  681. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  682. info3.data());
  683. #else
  684. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu\",\"id\":100,\"email\":\"welcome@baidu.com\","
  685. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  686. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  687. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,\"databool\":false,"
  688. "\"databyte\":\"d2VsY29tZQ==\",\"datafix32\":1,\"datafix64\":666,"
  689. "\"datasfix32\":120,\"datasfix64\":-802,\"datafloat_scientific\":123456792,"
  690. "\"datadouble_scientific\":123456789}]}", info3.data());
  691. #endif
  692. }
  693. std::cout << "json2pb=" << total_tm / N
  694. << "us pb2json=" << total_tm2 / N << "us"
  695. << std::endl;
  696. }
  697. TEST_F(ProtobufJsonTest, pb_to_json_map_case) {
  698. std::string json = "{\"addr\":\"baidu.com\","
  699. "\"numbers\":{\"tel\":123456,\"cell\":654321},"
  700. "\"contacts\":{\"email\":\"frank@baidu.com\","
  701. " \"office\":\"Shanghai\"},"
  702. "\"friends\":{\"John\":[{\"school\":\"SJTU\",\"year\":2007}]}}";
  703. std::string output;
  704. std::string error;
  705. AddressNoMap ab1;
  706. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab1, &error));
  707. ASSERT_TRUE(json2pb::ProtoMessageToJson(ab1, &output, &error));
  708. ASSERT_TRUE(output.find("\"addr\":\"baidu.com\"") != std::string::npos);
  709. output.clear();
  710. AddressIntMap ab2;
  711. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab2, &error));
  712. ASSERT_TRUE(json2pb::ProtoMessageToJson(ab2, &output, &error));
  713. ASSERT_TRUE(output.find("\"addr\":\"baidu.com\"") != std::string::npos);
  714. ASSERT_TRUE(output.find("\"tel\":123456") != std::string::npos);
  715. ASSERT_TRUE(output.find("\"cell\":654321") != std::string::npos);
  716. output.clear();
  717. AddressStringMap ab3;
  718. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab3, &error));
  719. ASSERT_TRUE(json2pb::ProtoMessageToJson(ab3, &output, &error));
  720. ASSERT_TRUE(output.find("\"addr\":\"baidu.com\"") != std::string::npos);
  721. ASSERT_TRUE(output.find("\"email\":\"frank@baidu.com\"") != std::string::npos);
  722. ASSERT_TRUE(output.find("\"office\":\"Shanghai\"") != std::string::npos);
  723. output.clear();
  724. AddressComplex ab4;
  725. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &ab4, &error));
  726. ASSERT_TRUE(json2pb::ProtoMessageToJson(ab4, &output, &error));
  727. ASSERT_TRUE(output.find("\"addr\":\"baidu.com\"") != std::string::npos);
  728. ASSERT_TRUE(output.find("\"friends\":{\"John\":[{\"school\":\"SJTU\","
  729. "\"year\":2007}]}") != std::string::npos);
  730. }
  731. TEST_F(ProtobufJsonTest, pb_to_json_encode_decode) {
  732. JsonContextBodyEncDec json_data;
  733. json_data.set_type(80000);
  734. json_data.add_data_z058_array(200);
  735. json_data.add_data_z058_array(300);
  736. json_data.add_info("this is json data's info");
  737. json_data.add_info("this is a test");
  738. json_data.set_judge(true);
  739. json_data.set_spur(3.45);
  740. ContentEncDec * content = json_data.add__z064_content_test_z037__z064_();
  741. content->set_uid_z042_("content info");
  742. content->set_distance_info_(1234.56);
  743. ExtEncDec* ext = content->mutable__ext_z037_t_();
  744. ext->set_aa_ge_z040_(160000);
  745. ext->set_databyte_z040_std_z058__z058_string_z041_("databyte");
  746. ext->set_enum_z045__z045_type(ExtEncDec_PhoneTypeEncDec_WORK);
  747. std::string info1;
  748. google::protobuf::TextFormat::Printer printer;
  749. std::string text;
  750. printer.PrintToString(json_data, &text);
  751. printf("text:%s\n", text.data());
  752. printf("----------test pb to json------------\n\n");
  753. json2pb::Pb2JsonOptions option;
  754. option.bytes_to_base64 = true;
  755. ASSERT_TRUE(ProtoMessageToJson(json_data, &info1, option, NULL));
  756. #ifndef RAPIDJSON_VERSION_0_1
  757. ASSERT_STREQ("{\"info\":[\"this is json data's info\",\"this is a test\"],\"type\":80000,"
  758. "\"data:array\":[200,300],\"judge\":true,\"spur\":3.45,\"@Content_Test%@\":"
  759. "[{\"uid*\":\"content info\",\"Distance_info_\":1234.56005859375,\"_ext%T_\":"
  760. "{\"Aa_ge(\":160000,\"databyte(std::string)\":\"ZGF0YWJ5dGU=\","
  761. "\"enum--type\":\"WORK\"}}]}",
  762. info1.data());
  763. #else
  764. ASSERT_STREQ("{\"info\":[\"this is json data's info\",\"this is a test\"],\"type\":80000,"
  765. "\"data:array\":[200,300],\"judge\":true,\"spur\":3.45,\"@Content_Test%@\":"
  766. "[{\"uid*\":\"content info\",\"Distance_info_\":1234.560059,\"_ext%T_\":"
  767. "{\"Aa_ge(\":160000,\"databyte(std::string)\":\"ZGF0YWJ5dGU=\","
  768. "\"enum--type\":\"WORK\"}}]}",
  769. info1.data());
  770. #endif
  771. printf("----------test json to pb------------\n\n");
  772. std::string info3;
  773. JsonContextBody data1;
  774. json2pb::JsonToProtoMessage(info1, &data1, NULL);
  775. json2pb::ProtoMessageToJson(data1, &info3, NULL);
  776. #ifndef RAPIDJSON_VERSION_0_1
  777. ASSERT_STREQ("{\"info\":[\"this is json data's info\",\"this is a test\"],\"type\":80000,"
  778. "\"data:array\":[200,300],\"judge\":true,\"spur\":3.45,\"@Content_Test%@\":"
  779. "[{\"uid*\":\"content info\",\"Distance_info_\":1234.56005859375,\"_ext%T_\":"
  780. "{\"Aa_ge(\":160000,\"databyte(std::string)\":\"ZGF0YWJ5dGU=\","
  781. "\"enum--type\":\"WORK\"}}]}",
  782. info1.data());
  783. #else
  784. ASSERT_STREQ("{\"info\":[\"this is json data's info\",\"this is a test\"],\"type\":80000,"
  785. "\"data:array\":[200,300],\"judge\":true,\"spur\":3.45,\"@Content_Test%@\":"
  786. "[{\"uid*\":\"content info\",\"Distance_info_\":1234.560059,\"_ext%T_\":"
  787. "{\"Aa_ge(\":160000,\"databyte(std::string)\":\"ZGF0YWJ5dGU=\","
  788. "\"enum--type\":\"WORK\"}}]}",
  789. info1.data());
  790. #endif
  791. }
  792. TEST_F(ProtobufJsonTest, pb_to_json_control_char_case) {
  793. AddressBook address_book;
  794. Person* person = address_book.add_person();
  795. person->set_id(100);
  796. char ch = 0x01;
  797. char* name = new char[17];
  798. memcpy(name, "baidu ", 6);
  799. name[6] = ch;
  800. char c = 0x08;
  801. char t = 0x1A;
  802. memcpy(name + 7, "test", 4);
  803. name[11] = c;
  804. name[12] = t;
  805. memcpy(name + 13, "end", 3);
  806. name[16] = '\0';
  807. person->set_name(name);
  808. printf("name is %s\n", name);
  809. person->set_email("welcome@baidu.com");
  810. Person::PhoneNumber* phone_number = person->add_phone();
  811. phone_number->set_number("number123");
  812. phone_number->set_type(Person::HOME);
  813. person->set_data(-240000000);
  814. person->set_data32(6);
  815. person->set_data64(-1820000000);
  816. person->set_datadouble(123.456);
  817. person->set_datadouble_scientific(1.23456789e+08);
  818. person->set_datafloat_scientific(1.23456789e+08);
  819. person->set_datafloat(8.6123);
  820. person->set_datau32(60);
  821. person->set_datau64(960);
  822. person->set_databool(0);
  823. person->set_databyte("welcome to china");
  824. person->set_datafix32(1);
  825. person->set_datafix64(666);
  826. person->set_datasfix32(120);
  827. person->set_datasfix64(-802);
  828. std::string info1;
  829. google::protobuf::TextFormat::Printer printer;
  830. std::string text;
  831. printer.PrintToString(*person, &text);
  832. printf("text:%s\n", text.data());
  833. bool ret = false;
  834. printf("----------test pb to json------------\n\n");
  835. {
  836. json2pb::Pb2JsonOptions option;
  837. option.bytes_to_base64 = false;
  838. ret = ProtoMessageToJson(address_book, &info1, option, NULL);
  839. ASSERT_TRUE(ret);
  840. }
  841. #ifndef RAPIDJSON_VERSION_0_1
  842. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu \\u0001test\\b\\u001Aend\",\"id\":100,\"email\":"
  843. "\"welcome@baidu.com\","
  844. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  845. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  846. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  847. "\"databool\":false,\"databyte\":\"welcome to china\",\"datafix32\":1,"
  848. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  849. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  850. info1.data());
  851. #else
  852. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu \\u0001test\\b\\u001Aend\",\"id\":100,\"email\":"
  853. "\"welcome@baidu.com\","
  854. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  855. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  856. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,\"databool\":false,"
  857. "\"databyte\":\"welcome to china\",\"datafix32\":1,\"datafix64\":666,"
  858. "\"datasfix32\":120,\"datasfix64\":-802,\"datafloat_scientific\":123456792,"
  859. "\"datadouble_scientific\":123456789}]}", info1.data());
  860. #endif
  861. info1.clear();
  862. {
  863. json2pb::Pb2JsonOptions option;
  864. option.bytes_to_base64 = true;
  865. ret = ProtoMessageToJson(address_book, &info1, option, NULL);
  866. ASSERT_TRUE(ret);
  867. }
  868. #ifndef RAPIDJSON_VERSION_0_1
  869. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu \\u0001test\\b\\u001Aend\",\"id\":100,\"email\":"
  870. "\"welcome@baidu.com\","
  871. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  872. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  873. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  874. "\"databool\":false,\"databyte\":\"d2VsY29tZSB0byBjaGluYQ==\",\"datafix32\":1,"
  875. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  876. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  877. info1.data());
  878. #else
  879. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu \\u0001test\\b\\u001Aend\",\"id\":100,\"email\":"
  880. "\"welcome@baidu.com\","
  881. "\"phone\":[{\"number\":\"number123\",\"type\":\"HOME\"}],\"data\":-240000000,"
  882. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  883. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,\"databool\":false,"
  884. "\"databyte\":\"d2VsY29tZSB0byBjaGluYQ==\",\"datafix32\":1,\"datafix64\":666,"
  885. "\"datasfix32\":120,\"datasfix64\":-802,\"datafloat_scientific\":123456792,"
  886. "\"datadouble_scientific\":123456789}]}", info1.data());
  887. #endif
  888. info1.clear();
  889. {
  890. json2pb::Pb2JsonOptions option;
  891. option.enum_option = json2pb::OUTPUT_ENUM_BY_NUMBER;
  892. option.bytes_to_base64 = false;
  893. ret = ProtoMessageToJson(address_book, &info1, option, NULL);
  894. ASSERT_TRUE(ret);
  895. }
  896. #ifndef RAPIDJSON_VERSION_0_1
  897. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu \\u0001test\\b\\u001Aend\",\"id\":100,\"email\":"
  898. "\"welcome@baidu.com\","
  899. "\"phone\":[{\"number\":\"number123\",\"type\":1}],\"data\":-240000000,"
  900. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  901. "\"datafloat\":8.612299919128418,\"datau32\":60,\"datau64\":960,"
  902. "\"databool\":false,\"databyte\":\"welcome to china\",\"datafix32\":1,"
  903. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  904. "\"datafloat_scientific\":123456792.0,\"datadouble_scientific\":123456789.0}]}",
  905. info1.data());
  906. #else
  907. std::cout << info1.data() << std::endl;
  908. ASSERT_STREQ("{\"person\":[{\"name\":\"baidu \\u0001test\\b\\u001Aend\",\"id\":100,\"email\":"
  909. "\"welcome@baidu.com\","
  910. "\"phone\":[{\"number\":\"number123\",\"type\":1}],\"data\":-240000000,"
  911. "\"data32\":6,\"data64\":-1820000000,\"datadouble\":123.456,"
  912. "\"datafloat\":8.612299919,\"datau32\":60,\"datau64\":960,"
  913. "\"databool\":false,\"databyte\":\"welcome to china\",\"datafix32\":1,"
  914. "\"datafix64\":666,\"datasfix32\":120,\"datasfix64\":-802,"
  915. "\"datafloat_scientific\":123456792,\"datadouble_scientific\":123456789}]}",
  916. info1.data());
  917. #endif
  918. }
  919. TEST_F(ProtobufJsonTest, pb_to_json_unicode_case) {
  920. AddressBook address_book;
  921. Person* person = address_book.add_person();
  922. person->set_id(100);
  923. char name[255*1024];
  924. for (int j = 0; j < 1024; j++) {
  925. for (int i = 0; i < 255; i++) {
  926. name[j*255 + i] = i + 1;
  927. }
  928. }
  929. name[255*1024 - 1] = '\0';
  930. person->set_name(name);
  931. person->set_data(-240000000);
  932. person->set_data32(6);
  933. person->set_data64(-1820000000);
  934. person->set_datadouble(123.456);
  935. person->set_datadouble_scientific(1.23456789e+08);
  936. person->set_datafloat_scientific(1.23456789e+08);
  937. person->set_datafloat(8.6123);
  938. person->set_datau32(60);
  939. person->set_datau64(960);
  940. person->set_databool(0);
  941. person->set_databyte("welcome to china");
  942. person->set_datafix32(1);
  943. person->set_datafix64(666);
  944. person->set_datasfix32(120);
  945. person->set_datasfix64(-802);
  946. std::string info1;
  947. std::string error;
  948. google::protobuf::TextFormat::Printer printer;
  949. std::string text;
  950. printer.PrintToString(*person, &text);
  951. printf("----------test pb to json------------\n\n");
  952. bool ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  953. ASSERT_TRUE(ret);
  954. butil::IOBuf buf;
  955. butil::IOBufAsZeroCopyOutputStream stream(&buf);
  956. bool res = json2pb::ProtoMessageToJson(address_book, &stream, NULL);
  957. ASSERT_TRUE(res);
  958. ASSERT_TRUE(!info1.compare(buf.to_string()));
  959. }
  960. TEST_F(ProtobufJsonTest, pb_to_json_edge_case) {
  961. AddressBook address_book;
  962. std::string info1;
  963. std::string error;
  964. bool ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  965. ASSERT_TRUE(ret);
  966. info1.clear();
  967. Person* person = address_book.add_person();
  968. person->set_id(100);
  969. person->set_name("baidu");
  970. Person::PhoneNumber* phone_number = person->add_phone();
  971. phone_number->set_number("1234556");
  972. person->set_datadouble(-345.67);
  973. person->set_datafloat(8.6123);
  974. ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  975. ASSERT_TRUE(ret);
  976. ASSERT_TRUE(error.empty());
  977. std::string info3;
  978. AddressBook data1;
  979. std::string error1;
  980. bool ret1 = json2pb::JsonToProtoMessage(info1, &data1, &error1);
  981. ASSERT_TRUE(ret1);
  982. ASSERT_TRUE(error1.empty());
  983. std::string error2;
  984. bool ret2 = json2pb::ProtoMessageToJson(data1, &info3, &error2);
  985. ASSERT_TRUE(ret2);
  986. ASSERT_TRUE(error2.empty());
  987. }
  988. TEST_F(ProtobufJsonTest, pb_to_json_expected_failed_case) {
  989. AddressBook address_book;
  990. std::string info1;
  991. std::string error;
  992. Person* person = address_book.add_person();
  993. person->set_name("baidu");
  994. person->set_email("welcome@baidu.com");
  995. bool ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  996. ASSERT_FALSE(ret);
  997. ASSERT_STREQ("Missing required field: addressbook.Person.id", error.data());
  998. address_book.clear_person();
  999. person = address_book.add_person();
  1000. person->set_id(2);
  1001. person->set_email("welcome@baidu.com");
  1002. ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  1003. ASSERT_FALSE(ret);
  1004. ASSERT_STREQ("Missing required field: addressbook.Person.name", error.data());
  1005. address_book.clear_person();
  1006. person = address_book.add_person();
  1007. person->set_id(2);
  1008. person->set_name("name");
  1009. person->set_email("welcome@baidu.com");
  1010. ret = json2pb::ProtoMessageToJson(address_book, &info1, &error);
  1011. ASSERT_FALSE(ret);
  1012. ASSERT_STREQ("Missing required field: addressbook.Person.datadouble", error.data());
  1013. }
  1014. TEST_F(ProtobufJsonTest, pb_to_json_perf_case) {
  1015. AddressBook address_book;
  1016. Person* person = address_book.add_person();
  1017. person->set_id(100);
  1018. person->set_name("baidu");
  1019. person->set_email("welcome@baidu.com");
  1020. Person::PhoneNumber* phone_number = person->add_phone();
  1021. phone_number->set_number("number123");
  1022. phone_number->set_type(Person::HOME);
  1023. person->set_data(-240000000);
  1024. person->set_data32(6);
  1025. person->set_data64(-1820000000);
  1026. person->set_datadouble(123.456);
  1027. person->set_datadouble_scientific(1.23456789e+08);
  1028. person->set_datafloat_scientific(1.23456789e+08);
  1029. person->set_datafloat(8.6123);
  1030. person->set_datau32(60);
  1031. person->set_datau64(960);
  1032. person->set_databool(0);
  1033. person->set_databyte("welcome to china");
  1034. person->set_datafix32(1);
  1035. person->set_datafix64(666);
  1036. person->set_datasfix32(120);
  1037. person->set_datasfix64(-802);
  1038. std::string info1;
  1039. google::protobuf::TextFormat::Printer printer;
  1040. std::string text;
  1041. printer.PrintToString(*person, &text);
  1042. printf("text:%s\n", text.data());
  1043. printf("----------test pb to json performance------------\n\n");
  1044. ProfilerStart("pb_to_json_perf.prof");
  1045. butil::Timer timer;
  1046. bool res;
  1047. float avg_time1 = 0;
  1048. float avg_time2 = 0;
  1049. const int times = 100000;
  1050. ASSERT_TRUE(json2pb::ProtoMessageToJson(address_book, &info1, NULL));
  1051. for (int i = 0; i < times; i++) {
  1052. std::string info3;
  1053. AddressBook data1;
  1054. timer.start();
  1055. res = json2pb::JsonToProtoMessage(info1, &data1, NULL);
  1056. timer.stop();
  1057. avg_time1 += timer.u_elapsed();
  1058. ASSERT_TRUE(res);
  1059. timer.start();
  1060. res = json2pb::ProtoMessageToJson(data1, &info3, NULL);
  1061. timer.stop();
  1062. avg_time2 += timer.u_elapsed();
  1063. ASSERT_TRUE(res);
  1064. }
  1065. avg_time1 /= times;
  1066. avg_time2 /= times;
  1067. ProfilerStop();
  1068. printf("avg time to convert json to pb is %fus\n", avg_time1);
  1069. printf("avg time to convert pb to json is %fus\n", avg_time2);
  1070. }
  1071. TEST_F(ProtobufJsonTest, pb_to_json_encode_decode_perf_case) {
  1072. JsonContextBodyEncDec json_data;
  1073. json_data.set_type(80000);
  1074. json_data.add_data_z058_array(200);
  1075. json_data.add_data_z058_array(300);
  1076. json_data.add_info("this is json data's info");
  1077. json_data.add_info("this is a test");
  1078. json_data.set_judge(true);
  1079. json_data.set_spur(3.45);
  1080. ContentEncDec * content = json_data.add__z064_content_test_z037__z064_();
  1081. content->set_uid_z042_("content info");
  1082. content->set_distance_info_(1234.56);
  1083. ExtEncDec* ext = content->mutable__ext_z037_t_();
  1084. ext->set_aa_ge_z040_(160000);
  1085. ext->set_databyte_z040_std_z058__z058_string_z041_("databyte");
  1086. ext->set_enum_z045__z045_type(ExtEncDec_PhoneTypeEncDec_WORK);
  1087. std::string info1;
  1088. google::protobuf::TextFormat::Printer printer;
  1089. std::string text;
  1090. printer.PrintToString(json_data, &text);
  1091. printf("text:%s\n", text.data());
  1092. ASSERT_TRUE(json2pb::ProtoMessageToJson(json_data, &info1, NULL));
  1093. printf("----------test pb to json encode decode performance------------\n\n");
  1094. ProfilerStart("pb_to_json_encode_decode_perf.prof");
  1095. butil::Timer timer;
  1096. bool res;
  1097. float avg_time1 = 0;
  1098. float avg_time2 = 0;
  1099. const int times = 100000;
  1100. for (int i = 0; i < times; i++) {
  1101. std::string info3;
  1102. JsonContextBody json_body;
  1103. timer.start();
  1104. res = json2pb::JsonToProtoMessage(info1, &json_body, NULL);
  1105. timer.stop();
  1106. avg_time1 += timer.u_elapsed();
  1107. ASSERT_TRUE(res);
  1108. timer.start();
  1109. res = json2pb::ProtoMessageToJson(json_body, &info3, NULL);
  1110. timer.stop();
  1111. avg_time2 += timer.u_elapsed();
  1112. ASSERT_TRUE(res);
  1113. }
  1114. avg_time1 /= times;
  1115. avg_time2 /= times;
  1116. ProfilerStop();
  1117. printf("avg time to convert json to pb is %fus\n", avg_time1);
  1118. printf("avg time to convert pb to json is %fus\n", avg_time2);
  1119. }
  1120. TEST_F(ProtobufJsonTest, pb_to_json_complex_perf_case) {
  1121. std::ifstream in("jsonout", std::ios::in);
  1122. std::ostringstream tmp;
  1123. tmp << in.rdbuf();
  1124. std::string info3 = tmp.str();
  1125. in.close();
  1126. printf("----------test pb to json performance------------\n\n");
  1127. std::string error;
  1128. butil::Timer timer;
  1129. bool res;
  1130. float avg_time1 = 0;
  1131. float avg_time2 = 0;
  1132. const int times = 10000;
  1133. gss::message::gss_us_res_t data;
  1134. json2pb::Json2PbOptions option;
  1135. option.base64_to_bytes = false;
  1136. timer.start();
  1137. res = JsonToProtoMessage(info3, &data, option, &error);
  1138. timer.stop();
  1139. avg_time1 += timer.u_elapsed();
  1140. ASSERT_TRUE(res) << error;
  1141. ProfilerStart("pb_to_json_complex_perf.prof");
  1142. for (int i = 0; i < times; i++) {
  1143. std::string error1;
  1144. timer.start();
  1145. butil::IOBuf buf;
  1146. butil::IOBufAsZeroCopyOutputStream stream(&buf);
  1147. res = json2pb::ProtoMessageToJson(data, &stream, &error1);
  1148. timer.stop();
  1149. avg_time2 += timer.u_elapsed();
  1150. ASSERT_TRUE(res);
  1151. }
  1152. avg_time2 /= times;
  1153. ProfilerStop();
  1154. printf("avg time to convert pb to json is %fus\n", avg_time2);
  1155. }
  1156. TEST_F(ProtobufJsonTest, pb_to_json_to_string_complex_perf_case) {
  1157. std::ifstream in("jsonout", std::ios::in);
  1158. std::ostringstream tmp;
  1159. tmp << in.rdbuf();
  1160. std::string info3 = tmp.str();
  1161. in.close();
  1162. printf("----------test pb to json performance------------\n\n");
  1163. std::string error;
  1164. butil::Timer timer;
  1165. bool res;
  1166. float avg_time1 = 0;
  1167. float avg_time2 = 0;
  1168. const int times = 10000;
  1169. gss::message::gss_us_res_t data;
  1170. json2pb::Json2PbOptions option;
  1171. option.base64_to_bytes = false;
  1172. timer.start();
  1173. res = JsonToProtoMessage(info3, &data, option, &error);
  1174. timer.stop();
  1175. avg_time1 += timer.u_elapsed();
  1176. ASSERT_TRUE(res);
  1177. ProfilerStart("pb_to_json_to_string_complex_perf.prof");
  1178. for (int i = 0; i < times; i++) {
  1179. std::string info4;
  1180. std::string error1;
  1181. timer.start();
  1182. std::string inf4;
  1183. res = json2pb::ProtoMessageToJson(data, &info4, &error1);
  1184. timer.stop();
  1185. avg_time2 += timer.u_elapsed();
  1186. ASSERT_TRUE(res);
  1187. }
  1188. avg_time2 /= times;
  1189. ProfilerStop();
  1190. printf("avg time to convert pb to json is %fus\n", avg_time2);
  1191. }
  1192. TEST_F(ProtobufJsonTest, encode_decode_case) {
  1193. std::string json_key = "abcdek123lske_slkejfl_l1kdle";
  1194. std::string field_name;
  1195. ASSERT_FALSE(json2pb::encode_name(json_key, field_name));
  1196. ASSERT_TRUE(field_name.empty());
  1197. std::string json_key_decode;
  1198. ASSERT_FALSE(json2pb::decode_name(field_name, json_key_decode));
  1199. ASSERT_TRUE(json_key_decode.empty());
  1200. json_key = "_Afledk2e*_+%leGi___hE_Z278_t#";
  1201. field_name.clear();
  1202. json2pb::encode_name(json_key, field_name);
  1203. const char* encode_json_key = "_Afledk2e_Z042___Z043__Z037_leGi___hE_Z278_t_Z035_";
  1204. ASSERT_TRUE(strcmp(field_name.data(), encode_json_key) == 0);
  1205. json_key_decode.clear();
  1206. json2pb::decode_name(field_name, json_key_decode);
  1207. ASSERT_TRUE(strcmp(json_key_decode.data(), json_key.data()) == 0);
  1208. json_key = "_ext%T_";
  1209. field_name.clear();
  1210. json2pb::encode_name(json_key, field_name);
  1211. encode_json_key = "_ext_Z037_T_";
  1212. ASSERT_TRUE(strcmp(field_name.data(), encode_json_key) == 0);
  1213. json_key_decode.clear();
  1214. json2pb::decode_name(field_name, json_key_decode);
  1215. ASSERT_TRUE(strcmp(json_key_decode.data(), json_key.data()) == 0);
  1216. std::string empty_key;
  1217. std::string empty_result;
  1218. ASSERT_FALSE(json2pb::encode_name(empty_key, empty_result));
  1219. ASSERT_TRUE(empty_result.empty() == true);
  1220. ASSERT_FALSE(json2pb::decode_name(empty_result, empty_key));
  1221. ASSERT_TRUE(empty_key.empty() == true);
  1222. }
  1223. TEST_F(ProtobufJsonTest, json_to_zero_copy_stream_normal_case) {
  1224. Person person;
  1225. person.set_name("hello");
  1226. person.set_id(9);
  1227. person.set_datadouble(2.2);
  1228. person.set_datafloat(1);
  1229. butil::IOBuf iobuf;
  1230. butil::IOBufAsZeroCopyOutputStream wrapper(&iobuf);
  1231. std::string error;
  1232. ASSERT_TRUE(json2pb::ProtoMessageToJson(person, &wrapper, &error)) << error;
  1233. std::string out = iobuf.to_string();
  1234. ASSERT_EQ("{\"name\":\"hello\",\"id\":9,\"datadouble\":2.2,\"datafloat\":1.0}", out);
  1235. }
  1236. TEST_F(ProtobufJsonTest, zero_copy_stream_to_json_normal_case) {
  1237. butil::IOBuf iobuf;
  1238. iobuf = "{\"name\":\"hello\",\"id\":9,\"datadouble\":2.2,\"datafloat\":1.0}";
  1239. butil::IOBufAsZeroCopyInputStream wrapper(iobuf);
  1240. Person person;
  1241. ASSERT_TRUE(json2pb::JsonToProtoMessage(&wrapper, &person));
  1242. ASSERT_STREQ("hello", person.name().c_str());
  1243. ASSERT_EQ(9, person.id());
  1244. ASSERT_EQ(2.2, person.datadouble());
  1245. ASSERT_EQ(1, person.datafloat());
  1246. }
  1247. TEST_F(ProtobufJsonTest, extension_case) {
  1248. std::string json = "{\"name\":\"hello\",\"id\":9,\"datadouble\":2.2,\"datafloat\":1.0,\"hobby\":\"coding\"}";
  1249. Person person;
  1250. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &person));
  1251. ASSERT_STREQ("coding", person.GetExtension(addressbook::hobby).data());
  1252. std::string output;
  1253. ASSERT_TRUE(json2pb::ProtoMessageToJson(person, &output));
  1254. ASSERT_EQ("{\"hobby\":\"coding\",\"name\":\"hello\",\"id\":9,\"datadouble\":2.2,\"datafloat\":1.0}", output);
  1255. }
  1256. TEST_F(ProtobufJsonTest, string_to_int64) {
  1257. auto json = R"({"name":"hello", "id":9, "data": "123456", "datadouble":2.2, "datafloat":1.0})";
  1258. Person person;
  1259. std::string err;
  1260. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &person, &err)) << err;
  1261. ASSERT_EQ(person.data(), 123456);
  1262. json = R"({"name":"hello", "id":9, "data": 1234567, "datadouble":2.2, "datafloat":1.0})";
  1263. ASSERT_TRUE(json2pb::JsonToProtoMessage(json, &person));
  1264. ASSERT_EQ(person.data(), 1234567);
  1265. }
  1266. }