MessageField.cc 10 KB

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