MessageField.cc 10 KB

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