bson_decoder.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * Copyright (C) 2021 Duowan Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing,
  11. * software distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef __X_PACK_BSON_DECODER_H
  17. #define __X_PACK_BSON_DECODER_H
  18. #include "libbson-1.0/bson.h"
  19. #include "string.h"
  20. #include "xpack/util.h"
  21. #include "xpack/xdecoder.h"
  22. namespace xpack {
  23. class BsonDecoder:public XDecoder<BsonDecoder>, private noncopyable {
  24. friend class XDecoder<BsonDecoder>;
  25. class MemberIterator {
  26. friend class BsonDecoder;
  27. public:
  28. MemberIterator(size_t iter, BsonDecoder* parent):_iter(iter),_parent(parent){}
  29. bool operator != (const MemberIterator &that) const {
  30. return _iter != that._iter;
  31. }
  32. MemberIterator& operator ++ () {
  33. ++_iter;
  34. return *this;
  35. }
  36. const char* Key() const {
  37. if (NULL != _parent) {
  38. return _parent->get_iter_key(_iter);
  39. }
  40. return "";
  41. }
  42. BsonDecoder& Val() const {
  43. return _parent->member(*this, *_parent->alloc());
  44. }
  45. private:
  46. size_t _iter;
  47. BsonDecoder* _parent;
  48. };
  49. public:
  50. using xdoc_type::decode;
  51. typedef MemberIterator Iterator;
  52. BsonDecoder(const uint8_t*data, size_t length, bool copy):xdoc_type(0, "") {
  53. parse(data, length, copy);
  54. }
  55. BsonDecoder(const std::string&data, bool copy):xdoc_type(0, "") {
  56. parse((const uint8_t*)data.data(), data.length(), copy);
  57. }
  58. ~BsonDecoder() {
  59. }
  60. inline const char * Type() const {
  61. return "bson";
  62. }
  63. std::string json() const {
  64. if (NULL == _data) {
  65. return "";
  66. }
  67. size_t length=BSON_UINT32_TO_LE(*(int32_t*)_data);
  68. bson_t b; // local is ok
  69. bson_init_static(&b, _data, length);
  70. size_t s;
  71. char *jstr = bson_as_json(&b, &s);
  72. if (jstr) {
  73. std::string j(jstr);
  74. bson_free(jstr);
  75. return j;
  76. } else {
  77. return "";
  78. }
  79. }
  80. public:
  81. #define XPACK_BSON_DECODE_CHECK() \
  82. const bson_iter_t* it = get_val(key); \
  83. if (NULL == it) { \
  84. if (Extend::Mandatory(ext)) { \
  85. decode_exception("mandatory key not found", key); \
  86. } \
  87. return false; \
  88. }
  89. bool decode(const char *key, std::string &val, const Extend *ext) {
  90. XPACK_BSON_DECODE_CHECK()
  91. uint32_t length;
  92. const char* data = bson_iter_utf8(it, &length);
  93. if (NULL != data) {
  94. val = std::string(data, length);
  95. }
  96. return true;
  97. }
  98. bool decode(const char *key, bool &val, const Extend *ext) {
  99. XPACK_BSON_DECODE_CHECK()
  100. val = bson_iter_as_bool(it);
  101. return true;
  102. }
  103. // vtype is type of val, and f is function name, all use int64, or will fail if type not match
  104. #define XPACK_BSON_DECODE_NUMBER(vtype, f) \
  105. inline bool decode(const char *key, vtype &val, const Extend *ext) {\
  106. const bson_iter_t* it = get_val(key); \
  107. if (NULL == it) { \
  108. if (Extend::Mandatory(ext)) { \
  109. decode_exception("mandatory key not found", key); \
  110. } \
  111. return false; \
  112. } else { \
  113. val = (vtype)f(it); return true; \
  114. } \
  115. }
  116. XPACK_BSON_DECODE_NUMBER(char, bson_iter_as_int64)
  117. XPACK_BSON_DECODE_NUMBER(signed char, bson_iter_as_int64)
  118. XPACK_BSON_DECODE_NUMBER(unsigned char, bson_iter_as_int64)
  119. XPACK_BSON_DECODE_NUMBER(short, bson_iter_as_int64)
  120. XPACK_BSON_DECODE_NUMBER(unsigned short, bson_iter_as_int64)
  121. XPACK_BSON_DECODE_NUMBER(int, bson_iter_as_int64)
  122. XPACK_BSON_DECODE_NUMBER(unsigned int, bson_iter_as_int64)
  123. XPACK_BSON_DECODE_NUMBER(long, bson_iter_as_int64)
  124. XPACK_BSON_DECODE_NUMBER(unsigned long, bson_iter_as_int64)
  125. XPACK_BSON_DECODE_NUMBER(long long, bson_iter_as_int64)
  126. XPACK_BSON_DECODE_NUMBER(unsigned long long, bson_iter_as_int64)
  127. XPACK_BSON_DECODE_NUMBER(float, bson_iter_double)
  128. XPACK_BSON_DECODE_NUMBER(double, bson_iter_double)
  129. XPACK_BSON_DECODE_NUMBER(long double, bson_iter_double)
  130. size_t Size() const {
  131. return _childs.size();
  132. }
  133. BsonDecoder& operator[](size_t index) {
  134. BsonDecoder *d = alloc();
  135. member(index, *d);
  136. return *d;
  137. }
  138. BsonDecoder& operator[](const char* key) {
  139. BsonDecoder *d = alloc();
  140. member(key, *d);
  141. return *d;
  142. }
  143. Iterator Begin() {
  144. return Iterator(0, this);
  145. }
  146. Iterator End() {
  147. return Iterator(_childs.size(), this);
  148. }
  149. operator bool() const {
  150. return NULL != _node;
  151. }
  152. private:
  153. typedef std::map<const char*, size_t, cmp_str> node_index; // index of _childs
  154. void parse(const uint8_t*data, size_t length, bool copy){
  155. bson_t b; // local is ok
  156. length = (length>0)?length:BSON_UINT32_TO_LE(*(int32_t*)data);
  157. if (copy) {
  158. std::string tmp(std::string((const char*)data, length));
  159. _tmp.swap(tmp);
  160. _data = (const uint8_t*)_tmp.data();
  161. } else {
  162. _data = data;
  163. }
  164. bson_init_static(&b, _data, length);
  165. bson_iter_init(&_root, &b);
  166. _node = &_root;
  167. init(true);
  168. }
  169. // get object or array info
  170. void init(bool top = false) {
  171. _childs.clear();
  172. _childs_index.clear();
  173. bson_iter_t sub;
  174. if (NULL == _node) {
  175. return;
  176. } else { // is array or object
  177. bool isobj;
  178. if (top) {
  179. isobj = true;
  180. memcpy((void*)&sub, (void*)_node, sizeof(sub));
  181. } else if (bson_iter_recurse(_node, &sub)) {
  182. isobj = BSON_TYPE_ARRAY != bson_iter_type(_node);
  183. } else {
  184. return;
  185. }
  186. size_t i = 0;
  187. while (bson_iter_next(&sub)) {
  188. _childs.push_back(sub);
  189. if (isobj) {
  190. _childs_index[bson_iter_key(&sub)] = i++;
  191. }
  192. }
  193. }
  194. }
  195. BsonDecoder():xdoc_type(0, ""),_node(NULL) {
  196. _data = NULL;
  197. }
  198. const bson_iter_t* get_val(const char *key) {
  199. if (NULL == key) {
  200. return _node;
  201. } else if (NULL != _node) {
  202. node_index::iterator iter = _childs_index.find(key);
  203. if (iter != _childs_index.end()) {
  204. return &_childs[iter->second];
  205. } else {
  206. return NULL;
  207. }
  208. } else {
  209. return NULL;
  210. }
  211. }
  212. BsonDecoder& member(size_t index, BsonDecoder&d) {
  213. if (index < _childs.size()) {
  214. d.init_base(this, index);
  215. d._node = &_childs[index];
  216. d.init();
  217. } else {
  218. decode_exception("Out of index", NULL);
  219. }
  220. return d;
  221. }
  222. BsonDecoder& member(const char*key, BsonDecoder&d) {
  223. node_index::iterator iter;
  224. if (_childs_index.end() != (iter=_childs_index.find(key))) {
  225. d.init_base(this, key);
  226. d._node = &_childs[iter->second];
  227. d.init();
  228. }
  229. return d;
  230. }
  231. BsonDecoder& member(const Iterator &iter, BsonDecoder&d) {
  232. const bson_iter_t* node = &_childs[iter._iter];
  233. d.init_base(iter._parent, bson_iter_key(node));
  234. d._node = node;
  235. d.init();
  236. return d;
  237. }
  238. const char *get_iter_key(size_t index) const {
  239. return bson_iter_key(&_childs[index]);
  240. }
  241. // only for parse
  242. std::string _tmp;
  243. const uint8_t* _data;
  244. bson_iter_t _root;
  245. const bson_iter_t* _node; // current node
  246. std::vector<bson_iter_t> _childs; // childs
  247. node_index _childs_index;
  248. size_t _iter;
  249. };
  250. }
  251. #endif