/include/common/message_helper.h

https://github.com/baidu/BaikalDB · C Header · 362 lines · 325 code · 24 blank · 13 comment · 29 complexity · 36edcf3a375fef51852b54652da6bed6 MD5 · raw file

  1. // Copyright (c) 2018-present Baidu, Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #pragma once
  15. #include "common.h"
  16. #include "key_encoder.h"
  17. #include "rocksdb/slice.h"
  18. #include "expr_value.h"
  19. namespace baikaldb {
  20. class MessageHelper {
  21. using FieldDescriptor = google::protobuf::FieldDescriptor;
  22. using Message = google::protobuf::Message;
  23. using Reflection = google::protobuf::Reflection;
  24. public:
  25. static bool is_null(const FieldDescriptor* field, Message* message) {
  26. const Reflection* reflection = message->GetReflection();
  27. if (!reflection->HasField(*message, field)) {
  28. return true;
  29. }
  30. return false;
  31. }
  32. static int get_int32(const FieldDescriptor* field, Message* message, int32_t& val) {
  33. const Reflection* reflection = message->GetReflection();
  34. if (!reflection->HasField(*message, field)) {
  35. DB_WARNING("missing field-value idx=%u", field->number());
  36. return -2;
  37. }
  38. val = reflection->GetInt32(*message, field);
  39. return 0;
  40. }
  41. static void set_int32(const FieldDescriptor* field, Message* message, int32_t val) {
  42. const Reflection* reflection = message->GetReflection();
  43. reflection->SetInt32(message, field, val);
  44. }
  45. static int get_uint32(const FieldDescriptor* field, Message* message, uint32_t& val) {
  46. const Reflection* reflection = message->GetReflection();
  47. if (!reflection->HasField(*message, field)) {
  48. DB_WARNING("missing field-value idx=%d", field->number());
  49. return -2;
  50. }
  51. val = reflection->GetUInt32(*message, field);
  52. return 0;
  53. }
  54. static void set_uint32(const FieldDescriptor* field, Message* message, uint32_t val) {
  55. const Reflection* reflection = message->GetReflection();
  56. reflection->SetUInt32(message, field, val);
  57. }
  58. static int get_int64(const FieldDescriptor* field, Message* message, int64_t& val) {
  59. const Reflection* reflection = message->GetReflection();
  60. if (!reflection->HasField(*message, field)) {
  61. DB_WARNING("missing field-value idx=%d", field->number());
  62. return -2;
  63. }
  64. val = reflection->GetInt64(*message, field);
  65. return 0;
  66. }
  67. static void set_int64(const FieldDescriptor* field, Message* message, int64_t val) {
  68. const Reflection* reflection = message->GetReflection();
  69. reflection->SetInt64(message, field, val);
  70. }
  71. static int get_uint64(const FieldDescriptor* field, Message* message, uint64_t& val) {
  72. const Reflection* reflection = message->GetReflection();
  73. if (!reflection->HasField(*message, field)) {
  74. DB_WARNING("missing field-value idx=%d", field->number());
  75. return -2;
  76. }
  77. val = reflection->GetUInt64(*message, field);
  78. return 0;
  79. }
  80. static void set_uint64(const FieldDescriptor* field, Message* message, uint64_t val) {
  81. const Reflection* reflection = message->GetReflection();
  82. reflection->SetUInt64(message, field, val);
  83. }
  84. static int get_float(const FieldDescriptor* field, Message* message, float& val) {
  85. const Reflection* reflection = message->GetReflection();
  86. if (!reflection->HasField(*message, field)) {
  87. DB_WARNING("missing field-value idx=%d", field->number());
  88. return -2;
  89. }
  90. val = reflection->GetFloat(*message, field);
  91. return 0;
  92. }
  93. static void set_float(const FieldDescriptor* field, Message* message, float val) {
  94. const Reflection* reflection = message->GetReflection();
  95. reflection->SetFloat(message, field, val);
  96. }
  97. static int get_double(const FieldDescriptor* field, Message* message, double& val) {
  98. const Reflection* reflection = message->GetReflection();
  99. if (!reflection->HasField(*message, field)) {
  100. DB_WARNING("missing field-value idx=%d", field->number());
  101. return -2;
  102. }
  103. val = reflection->GetDouble(*message, field);
  104. return 0;
  105. }
  106. static void set_double(const FieldDescriptor* field, Message* message, double val) {
  107. const Reflection* reflection = message->GetReflection();
  108. reflection->SetDouble(message, field, val);
  109. }
  110. static int get_string(const FieldDescriptor* field, Message* message, std::string& val) {
  111. const Reflection* reflection = message->GetReflection();
  112. if (!reflection->HasField(*message, field)) {
  113. DB_WARNING("missing field-value idx=%d", field->number());
  114. return -2;
  115. }
  116. val = reflection->GetString(*message, field);
  117. return 0;
  118. }
  119. static void set_string(const FieldDescriptor* field, Message* message, std::string val) {
  120. const Reflection* reflection = message->GetReflection();
  121. reflection->SetString(message, field, val);
  122. }
  123. static int get_boolean(const FieldDescriptor* field, Message* message, bool& val) {
  124. const Reflection* reflection = message->GetReflection();
  125. if (!reflection->HasField(*message, field)) {
  126. DB_WARNING("missing field-value idx=%d", field->number());
  127. return -2;
  128. }
  129. val = reflection->GetBool(*message, field);
  130. return 0;
  131. }
  132. static void set_boolean(const FieldDescriptor* field, Message* message, bool val) {
  133. const Reflection* reflection = message->GetReflection();
  134. reflection->SetBool(message, field, val);
  135. }
  136. static int set_value(const FieldDescriptor* field, Message* message, const ExprValue& value) {
  137. if (field == nullptr) {
  138. return -1;
  139. }
  140. const Reflection* reflection = message->GetReflection();
  141. if (value.is_null()) {
  142. reflection->ClearField(message, field);
  143. return 0;
  144. }
  145. auto type = field->cpp_type();
  146. switch (type) {
  147. case FieldDescriptor::CPPTYPE_INT32: {
  148. reflection->SetInt32(message, field, value.get_numberic<int32_t>());
  149. } break;
  150. case FieldDescriptor::CPPTYPE_UINT32: {
  151. reflection->SetUInt32(message, field, value.get_numberic<uint32_t>());
  152. } break;
  153. case FieldDescriptor::CPPTYPE_INT64: {
  154. reflection->SetInt64(message, field, value.get_numberic<int64_t>());
  155. } break;
  156. case FieldDescriptor::CPPTYPE_UINT64: {
  157. reflection->SetUInt64(message, field, value.get_numberic<uint64_t>());
  158. } break;
  159. case FieldDescriptor::CPPTYPE_FLOAT: {
  160. reflection->SetFloat(message, field, value.get_numberic<float>());
  161. } break;
  162. case FieldDescriptor::CPPTYPE_DOUBLE: {
  163. reflection->SetDouble(message, field, value.get_numberic<double>());
  164. } break;
  165. case FieldDescriptor::CPPTYPE_BOOL: {
  166. reflection->SetBool(message, field, value.get_numberic<bool>());
  167. } break;
  168. case FieldDescriptor::CPPTYPE_STRING: {
  169. reflection->SetString(message, field, value.get_string());
  170. } break;
  171. default: {
  172. return -1;
  173. }
  174. }
  175. return 0;
  176. }
  177. static ExprValue get_value(const FieldDescriptor* field, Message* message) {
  178. if (field == nullptr) {
  179. return ExprValue::Null();
  180. }
  181. const Reflection* reflection = message->GetReflection();
  182. if (!reflection->HasField(*message, field)) {
  183. return ExprValue::Null();
  184. }
  185. auto type = field->cpp_type();
  186. switch (type) {
  187. case FieldDescriptor::CPPTYPE_INT32: {
  188. ExprValue value(pb::INT32);
  189. value._u.int32_val = reflection->GetInt32(*message, field);
  190. return value;
  191. } break;
  192. case FieldDescriptor::CPPTYPE_UINT32: {
  193. ExprValue value(pb::UINT32);
  194. value._u.uint32_val = reflection->GetUInt32(*message, field);
  195. return value;
  196. } break;
  197. case FieldDescriptor::CPPTYPE_INT64: {
  198. ExprValue value(pb::INT64);
  199. value._u.int64_val = reflection->GetInt64(*message, field);
  200. return value;
  201. } break;
  202. case FieldDescriptor::CPPTYPE_UINT64: {
  203. ExprValue value(pb::UINT64);
  204. value._u.uint64_val = reflection->GetUInt64(*message, field);
  205. return value;
  206. } break;
  207. case FieldDescriptor::CPPTYPE_FLOAT: {
  208. ExprValue value(pb::FLOAT);
  209. value._u.float_val = reflection->GetFloat(*message, field);
  210. return value;
  211. } break;
  212. case FieldDescriptor::CPPTYPE_DOUBLE: {
  213. ExprValue value(pb::DOUBLE);
  214. value._u.double_val = reflection->GetDouble(*message, field);
  215. return value;
  216. } break;
  217. case FieldDescriptor::CPPTYPE_BOOL: {
  218. ExprValue value(pb::BOOL);
  219. value._u.bool_val = reflection->GetBool(*message, field);
  220. return value;
  221. } break;
  222. case FieldDescriptor::CPPTYPE_STRING: {
  223. ExprValue value(pb::STRING);
  224. value.str_val = reflection->GetString(*message, field);
  225. return value;
  226. }
  227. default: {
  228. return ExprValue::Null();
  229. }
  230. }
  231. return ExprValue::Null();
  232. }
  233. static int decode_field(const FieldDescriptor* field, pb::PrimitiveType field_type,
  234. Message* message, const rocksdb::Slice& in) {
  235. const Reflection* reflection = message->GetReflection();
  236. char* c = const_cast<char*>(in.data());
  237. switch (field_type) {
  238. case pb::INT8: {
  239. if (sizeof(int8_t) > in.size()) {
  240. DB_WARNING("int8_t out of bound: %d %zu", field->number(), in.size());
  241. return -2;
  242. }
  243. reflection->SetInt32(message, field, *reinterpret_cast<int8_t*>(c));
  244. } break;
  245. case pb::INT16: {
  246. if (sizeof(int16_t) > in.size()) {
  247. DB_WARNING("int16_t out of bound: %d %zu", field->number(), in.size());
  248. return -2;
  249. }
  250. reflection->SetInt32(message, field, static_cast<int16_t>(
  251. KeyEncoder::to_little_endian_u16(*reinterpret_cast<uint16_t*>(c))));
  252. } break;
  253. case pb::TIME:
  254. case pb::INT32: {
  255. if (sizeof(int32_t) > in.size()) {
  256. DB_WARNING("int32_t out of bound: %d %zu", field->number(), in.size());
  257. return -2;
  258. }
  259. reflection->SetInt32(message, field, static_cast<int32_t>(
  260. KeyEncoder::to_little_endian_u32(*reinterpret_cast<uint32_t*>(c))));
  261. } break;
  262. case pb::INT64: {
  263. if (sizeof(int64_t) > in.size()) {
  264. DB_WARNING("int64_t out of bound: %d %zu", field->number(), in.size());
  265. return -2;
  266. }
  267. reflection->SetInt64(message, field, static_cast<int64_t>(
  268. KeyEncoder::to_little_endian_u64(*reinterpret_cast<uint64_t*>(c))));
  269. } break;
  270. case pb::UINT8: {
  271. if (sizeof(uint8_t) > in.size()) {
  272. DB_WARNING("uint8_t out of bound: %d %zu", field->number(), in.size());
  273. return -2;
  274. }
  275. reflection->SetUInt32(message, field, *reinterpret_cast<uint8_t*>(c));
  276. } break;
  277. case pb::UINT16: {
  278. if (sizeof(uint16_t) > in.size()) {
  279. DB_WARNING("uint16_t out of bound: %d %zu", field->number(), in.size());
  280. return -2;
  281. }
  282. reflection->SetUInt32(message, field,
  283. KeyEncoder::to_little_endian_u16(*reinterpret_cast<uint16_t*>(c)));
  284. } break;
  285. case pb::TIMESTAMP:
  286. case pb::DATE:
  287. case pb::UINT32: {
  288. if (sizeof(uint32_t) > in.size()) {
  289. DB_WARNING("uint32_t out of bound: %d %zu", field->number(), in.size());
  290. return -2;
  291. }
  292. reflection->SetUInt32(message, field,
  293. KeyEncoder::to_little_endian_u32(*reinterpret_cast<uint32_t*>(c)));
  294. } break;
  295. case pb::DATETIME:
  296. case pb::UINT64: {
  297. if (sizeof(uint64_t) > in.size()) {
  298. DB_WARNING("uint64_t out of bound: %d %zu", field->number(), in.size());
  299. return -2;
  300. }
  301. reflection->SetUInt64(message, field,
  302. KeyEncoder::to_little_endian_u64(*reinterpret_cast<uint64_t*>(c)));
  303. } break;
  304. case pb::FLOAT: {
  305. if (sizeof(float) > in.size()) {
  306. DB_WARNING("float out of bound: %d %zu", field->number(), in.size());
  307. return -2;
  308. }
  309. uint32_t val = KeyEncoder::to_little_endian_u32(*reinterpret_cast<uint32_t*>(c));
  310. reflection->SetFloat(message, field, *reinterpret_cast<float*>(&val));
  311. } break;
  312. case pb::DOUBLE: {
  313. if (sizeof(double) > in.size()) {
  314. DB_WARNING("double out of bound: %d %zu", field->number(), in.size());
  315. return -2;
  316. }
  317. uint64_t val = KeyEncoder::to_little_endian_u64(*reinterpret_cast<uint64_t*>(c));
  318. reflection->SetDouble(message, field, *reinterpret_cast<double*>(&val));
  319. } break;
  320. case pb::BOOL: {
  321. if (sizeof(uint8_t) > in.size()) {
  322. DB_WARNING("bool out of bound: %d %zu", field->number(), in.size());
  323. return -2;
  324. }
  325. reflection->SetBool(message, field, *reinterpret_cast<uint8_t*>(c));
  326. } break;
  327. case pb::STRING: {
  328. reflection->SetString(message, field, std::string(in.data(), in.size()));
  329. } break;
  330. default: {
  331. DB_WARNING("un-supported field type: %d, %d", field->number(), field_type);
  332. return -1;
  333. } break;
  334. }
  335. return 0;
  336. }
  337. };
  338. }