MessageField.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. // Copyright: All Rights Reserved
  2. // Author: egametang@gmail.com (tanghai)
  3. #include <string>
  4. #include <iostream>
  5. #include <boost/algorithm/string.hpp>
  6. #include <boost/lexical_cast.hpp>
  7. #include <google/protobuf/descriptor.h>
  8. #include <google/protobuf/text_format.h>
  9. #include <glog/logging.h>
  10. #include <gflags/gflags.h>
  11. #include "Base/Typedef.h"
  12. #include "Orm/MessageField.h"
  13. namespace Egametang {
  14. MessageField::MessageField(google::protobuf::Message& message,
  15. const google::protobuf::FieldDescriptor* field):
  16. message(message), field(field)
  17. {
  18. }
  19. MessageField::~MessageField()
  20. {
  21. }
  22. std::string MessageField::GetField()
  23. {
  24. std::string valueStr;
  25. if (field->is_repeated())
  26. {
  27. valueStr = GetRepeatedField();
  28. }
  29. else
  30. {
  31. valueStr = GetOptionalField();
  32. }
  33. return valueStr;
  34. }
  35. std::string MessageField::GetRepeatedField()
  36. {
  37. const google::protobuf::Reflection* reflection = message.GetReflection();
  38. google::protobuf::FieldDescriptor::Type type = field->type();
  39. std::string valueStr;
  40. switch (type)
  41. {
  42. case google::protobuf::FieldDescriptor::TYPE_BOOL:
  43. {
  44. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  45. {
  46. bool value = reflection->GetBool(message, field);
  47. valueStr += value? "1\t" : "0\t";
  48. }
  49. break;
  50. }
  51. case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
  52. {
  53. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  54. {
  55. double value = reflection->GetDouble(message, field);
  56. valueStr += boost::lexical_cast<std::string>(value) + "\t";
  57. }
  58. break;
  59. }
  60. case google::protobuf::FieldDescriptor::TYPE_INT32:
  61. {
  62. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  63. {
  64. int32 value = reflection->GetInt32(message, field);
  65. valueStr += boost::lexical_cast<std::string>(value) + "\t";
  66. }
  67. break;
  68. }
  69. case google::protobuf::FieldDescriptor::TYPE_INT64:
  70. {
  71. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  72. {
  73. int64 value = reflection->GetInt64(message, field);
  74. valueStr += boost::lexical_cast<std::string>(value) + "\t";
  75. }
  76. break;
  77. }
  78. case google::protobuf::FieldDescriptor::TYPE_UINT32:
  79. {
  80. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  81. {
  82. int64 value = reflection->GetUInt32(message, field);
  83. valueStr += boost::lexical_cast<std::string>(value) + "\t";
  84. }
  85. break;
  86. }
  87. case google::protobuf::FieldDescriptor::TYPE_UINT64:
  88. {
  89. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  90. {
  91. int64 value = reflection->GetUInt64(message, field);
  92. valueStr += boost::lexical_cast<std::string>(value) + "\t";
  93. }
  94. break;
  95. }
  96. case google::protobuf::FieldDescriptor::TYPE_STRING:
  97. {
  98. valueStr += "'";
  99. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  100. {
  101. valueStr += reflection->GetString(message, field) + "\t";
  102. }
  103. valueStr += "'";
  104. break;
  105. }
  106. case google::protobuf::FieldDescriptor::TYPE_BYTES:
  107. {
  108. valueStr += "'";
  109. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  110. {
  111. valueStr += reflection->GetString(message, field) + "\t";
  112. }
  113. valueStr += "'";
  114. break;
  115. }
  116. case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
  117. {
  118. valueStr += "'";
  119. for (int i = 0; i < reflection->FieldSize(message, field); ++i)
  120. {
  121. const google::protobuf::Message& message = reflection->GetMessage(message, field);
  122. valueStr += message.ShortDebugString() + "\t";
  123. }
  124. valueStr += "'";
  125. break;
  126. }
  127. default:
  128. {
  129. break;
  130. }
  131. }
  132. return valueStr;
  133. }
  134. std::string MessageField::GetOptionalField()
  135. {
  136. const google::protobuf::Reflection* reflection = message.GetReflection();
  137. google::protobuf::FieldDescriptor::Type type = field->type();
  138. std::string valueStr;
  139. VLOG(2) << "FieldDescriptor::Type: " << type;
  140. switch (type)
  141. {
  142. case google::protobuf::FieldDescriptor::TYPE_BOOL:
  143. {
  144. bool value = reflection->GetBool(message, field);
  145. valueStr = value? "1" : "0";
  146. break;
  147. }
  148. case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
  149. {
  150. double value = reflection->GetDouble(message, field);
  151. valueStr = boost::lexical_cast<std::string>(value);
  152. break;
  153. }
  154. case google::protobuf::FieldDescriptor::TYPE_INT32:
  155. {
  156. int32 value = reflection->GetInt32(message, field);
  157. valueStr = boost::lexical_cast<std::string>(value);
  158. break;
  159. }
  160. case google::protobuf::FieldDescriptor::TYPE_INT64:
  161. {
  162. int64 value = reflection->GetInt64(message, field);
  163. valueStr = boost::lexical_cast<std::string>(value);
  164. break;
  165. }
  166. case google::protobuf::FieldDescriptor::TYPE_UINT32:
  167. {
  168. uint32 value = reflection->GetUInt32(message, field);
  169. valueStr = boost::lexical_cast<std::string>(value);
  170. break;
  171. }
  172. case google::protobuf::FieldDescriptor::TYPE_UINT64:
  173. {
  174. uint64 value = reflection->GetUInt64(message, field);
  175. valueStr = boost::lexical_cast<std::string>(value);
  176. break;
  177. }
  178. case google::protobuf::FieldDescriptor::TYPE_STRING:
  179. {
  180. valueStr = "'" + reflection->GetString(message, field) + "'";
  181. break;
  182. }
  183. case google::protobuf::FieldDescriptor::TYPE_BYTES:
  184. {
  185. valueStr = "'" + reflection->GetString(message, field) + "'";
  186. break;
  187. }
  188. case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
  189. {
  190. const google::protobuf::Message& msg = reflection->GetMessage(message, field);
  191. valueStr = msg.ShortDebugString();
  192. break;
  193. }
  194. default:
  195. {
  196. break;
  197. }
  198. }
  199. return valueStr;
  200. }
  201. void MessageField::SetRepeatedField(ResultSetPtr resultSet)
  202. {
  203. const google::protobuf::Reflection* reflection = message.GetReflection();
  204. google::protobuf::FieldDescriptor::Type type = field->type();
  205. // 获取blob string(repeated字段统一存成blob type)
  206. int index = field->index() + 1;
  207. std::istream* is = resultSet->getBlob(index);
  208. std::ostringstream os;
  209. os << is->rdbuf();
  210. std::string fieldStr = os.str();
  211. std::vector<std::string> strVector;
  212. boost::split(strVector, fieldStr, boost::is_any_of("\t"));
  213. switch (type)
  214. {
  215. case google::protobuf::FieldDescriptor::TYPE_BOOL:
  216. {
  217. for (std::size_t i = 0; i < strVector.size(); ++i)
  218. {
  219. int intValue = boost::lexical_cast<int>(strVector[i]);
  220. bool value = intValue? true : false;
  221. reflection->SetRepeatedBool(&message, field, i, value);
  222. }
  223. break;
  224. }
  225. case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
  226. {
  227. for (std::size_t i = 0; i < strVector.size(); ++i)
  228. {
  229. double value = boost::lexical_cast<double>(strVector[i]);
  230. reflection->SetRepeatedDouble(&message, field, i, value);
  231. }
  232. break;
  233. }
  234. case google::protobuf::FieldDescriptor::TYPE_INT32:
  235. {
  236. for (std::size_t i = 0; i < strVector.size(); ++i)
  237. {
  238. int32 value = boost::lexical_cast<int32>(strVector[i]);
  239. reflection->SetRepeatedInt32(&message, field, i, value);
  240. }
  241. break;
  242. }
  243. case google::protobuf::FieldDescriptor::TYPE_INT64:
  244. {
  245. for (std::size_t i = 0; i < strVector.size(); ++i)
  246. {
  247. int64 value = boost::lexical_cast<int64>(strVector[i]);
  248. reflection->SetRepeatedInt64(&message, field, i, value);
  249. }
  250. break;
  251. }
  252. case google::protobuf::FieldDescriptor::TYPE_UINT32:
  253. {
  254. for (std::size_t i = 0; i < strVector.size(); ++i)
  255. {
  256. uint32 value = boost::lexical_cast<uint32>(strVector[i]);
  257. reflection->SetRepeatedUInt32(&message, field, i, value);
  258. }
  259. break;
  260. }
  261. case google::protobuf::FieldDescriptor::TYPE_UINT64:
  262. {
  263. for (std::size_t i = 0; i < strVector.size(); ++i)
  264. {
  265. uint64 value = boost::lexical_cast<uint64>(strVector[i]);
  266. reflection->SetRepeatedUInt64(&message, field, i, value);
  267. }
  268. break;
  269. }
  270. case google::protobuf::FieldDescriptor::TYPE_STRING:
  271. {
  272. for (std::size_t i = 0; i < strVector.size(); ++i)
  273. {
  274. reflection->SetRepeatedString(&message, field, i, strVector[i]);
  275. }
  276. break;
  277. }
  278. case google::protobuf::FieldDescriptor::TYPE_BYTES:
  279. {
  280. for (std::size_t i = 0; i < strVector.size(); ++i)
  281. {
  282. reflection->SetRepeatedString(&message, field, i, strVector[i]);
  283. }
  284. break;
  285. }
  286. case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
  287. {
  288. for (std::size_t i = 0; i < strVector.size(); ++i)
  289. {
  290. google::protobuf::Message* msg =
  291. reflection->MutableRepeatedMessage(&message, field, i);
  292. google::protobuf::TextFormat::ParseFromString(strVector[i], msg);
  293. }
  294. break;
  295. }
  296. default:
  297. {
  298. break;
  299. }
  300. }
  301. }
  302. void MessageField::SetOptionalField(ResultSetPtr resultSet)
  303. {
  304. const google::protobuf::Reflection* reflection = message.GetReflection();
  305. google::protobuf::FieldDescriptor::Type type = field->type();
  306. int index = field->index() + 1;
  307. switch (type)
  308. {
  309. case google::protobuf::FieldDescriptor::TYPE_BOOL:
  310. {
  311. bool value = resultSet->getBoolean(index);
  312. reflection->SetBool(&message, field, value);
  313. break;
  314. }
  315. case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
  316. {
  317. double value = resultSet->getDouble(index);
  318. reflection->SetDouble(&message, field, value);
  319. break;
  320. }
  321. case google::protobuf::FieldDescriptor::TYPE_INT32:
  322. {
  323. int32 value = resultSet->getInt(index);
  324. reflection->SetInt32(&message, field, value);
  325. break;
  326. }
  327. case google::protobuf::FieldDescriptor::TYPE_INT64:
  328. {
  329. int64 value = resultSet->getInt64(index);
  330. reflection->SetInt64(&message, field, value);
  331. break;
  332. }
  333. case google::protobuf::FieldDescriptor::TYPE_UINT32:
  334. {
  335. uint32 value = resultSet->getUInt(index);
  336. reflection->SetUInt32(&message, field, value);
  337. break;
  338. }
  339. case google::protobuf::FieldDescriptor::TYPE_UINT64:
  340. {
  341. uint64 value = resultSet->getUInt64(index);
  342. reflection->SetUInt64(&message, field, value);
  343. break;
  344. }
  345. case google::protobuf::FieldDescriptor::TYPE_STRING:
  346. {
  347. std::string value = resultSet->getString(index);
  348. reflection->SetString(&message, field, value);
  349. break;
  350. }
  351. case google::protobuf::FieldDescriptor::TYPE_BYTES:
  352. {
  353. std::string value = resultSet->getString(index);
  354. reflection->SetString(&message, field, value);
  355. break;
  356. }
  357. case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
  358. {
  359. std::istream* is = resultSet->getBlob(index);
  360. std::ostringstream os;
  361. os << is->rdbuf();
  362. std::string value = os.str();
  363. google::protobuf::Message* msg =
  364. reflection->MutableMessage(&message, field);
  365. google::protobuf::TextFormat::ParseFromString(value, msg);
  366. break;
  367. }
  368. default:
  369. {
  370. break;
  371. }
  372. }
  373. }
  374. void MessageField::SetField(ResultSetPtr resultSet)
  375. {
  376. if (field->is_repeated())
  377. {
  378. SetRepeatedField(resultSet);
  379. }
  380. else
  381. {
  382. SetOptionalField(resultSet);
  383. }
  384. }
  385. } // namespace Egametang