bson_encoder.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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_ENCODER_H
  17. #define __X_PACK_BSON_ENCODER_H
  18. #include "libbson-1.0/bson.h"
  19. #include "xpack/util.h"
  20. #include "xpack/xencoder.h"
  21. namespace xpack {
  22. class BsonEncoder:public XEncoder<BsonEncoder>, private noncopyable {
  23. struct Node {
  24. const char *key;
  25. Node *parent;
  26. bson_t data;
  27. Node(const char *_key = NULL, Node *_parent=NULL):key(_key), parent(_parent) {
  28. if (NULL == parent) {
  29. bson_init(&data);
  30. }
  31. }
  32. ~Node() {
  33. if (NULL == parent) {
  34. bson_destroy(&data);
  35. }
  36. }
  37. };
  38. public:
  39. friend class XEncoder<BsonEncoder>;
  40. using xdoc_type::encode;
  41. BsonEncoder(const char*key = NULL, Node*parent = NULL) {
  42. cur = new Node(key, parent);
  43. nodes.push_back(cur);
  44. }
  45. ~BsonEncoder() {
  46. std::list<Node*>::iterator it;
  47. for (it = nodes.begin(); it!=nodes.end(); ++it) {
  48. delete *it;
  49. }
  50. }
  51. inline const char *Type() const {
  52. return "bson";
  53. }
  54. inline const char *IndexKey(size_t index) {
  55. if (index > indexStr.size()+1) {
  56. std::string s = Util::itoa(index);
  57. errCase.push_back(s);
  58. return errCase.back().c_str();
  59. }
  60. if (index >= indexStr.size()) {
  61. std::string s = Util::itoa(index);
  62. indexStr.push_back(s);
  63. }
  64. return indexStr[index].c_str();
  65. }
  66. // return bson binary data
  67. std::string String() const {
  68. return std::string((const char*)bson_get_data(&cur->data), cur->data.len);
  69. }
  70. // return json format string
  71. std::string Json() const {
  72. size_t len;
  73. char *jstr = bson_as_json(&cur->data, &len);
  74. std::string ret(jstr);
  75. bson_free(jstr);
  76. return ret;
  77. }
  78. public:
  79. void ArrayBegin(const char *key, const Extend *ext) {
  80. (void)ext;
  81. if (key != NULL) {
  82. Node *tmp = new Node(key, cur);
  83. nodes.push_back(tmp);
  84. bson_append_array_begin(&cur->data, key, strlen(key), &tmp->data);
  85. cur = tmp;
  86. }
  87. }
  88. void ArrayEnd(const char *key, const Extend *ext) {
  89. (void)ext;
  90. if (NULL != key) {
  91. bson_append_array_end(&cur->parent->data, &cur->data);
  92. cur = cur->parent; // do not pop and delete
  93. }
  94. }
  95. void ObjectBegin(const char *key, const Extend *ext) {
  96. (void)ext;
  97. if (key != NULL) {
  98. Node *tmp = new Node(key, cur);
  99. nodes.push_back(tmp);
  100. bson_append_document_begin(&cur->data, key, strlen(key), &tmp->data);
  101. cur = tmp;
  102. }
  103. }
  104. void ObjectEnd(const char *key, const Extend *ext) {
  105. (void)ext;
  106. if (NULL != key) { // in case of inherit, object key is NULL
  107. bson_append_document_end(&cur->parent->data, &cur->data);
  108. cur = cur->parent; // do not pop and delete
  109. }
  110. }
  111. bool writeNull(const char*key, const Extend *ext) {
  112. if (Extend::OmitEmpty(ext)) {
  113. return false;
  114. }
  115. bson_append_null(&cur->data, key, strlen(key));
  116. return true;
  117. }
  118. bool encode(const char*key, const char* val, const Extend *ext) {
  119. if (NULL==val && Extend::OmitEmpty(ext)){
  120. return false;
  121. }
  122. if (NULL != val) {
  123. bson_append_utf8(&cur->data, key, strlen(key), val, strlen(val));
  124. } else {
  125. bson_append_utf8(&cur->data, key, strlen(key), "", 0);
  126. }
  127. return true;
  128. }
  129. bool encode(const char*key, const std::string& val, const Extend *ext) {
  130. if (val.empty() && Extend::OmitEmpty(ext)){
  131. return false;
  132. }
  133. bson_append_utf8(&cur->data, key, strlen(key), (const char*)val.data(), val.length());
  134. return true;
  135. }
  136. bool encode(const char*key, const bool &val, const Extend *ext) {
  137. (void)ext;
  138. bson_append_bool(&cur->data, key, strlen(key), val);
  139. return true;
  140. }
  141. #define X_PACK_BSON_ENCODE_NUMBER(vtype, ftype, ctype) \
  142. bool encode(const char*key, const vtype&val, const Extend*ext) {\
  143. if (val==0 && Extend::OmitEmpty(ext)){ \
  144. return false; \
  145. } else { \
  146. bson_append_##ftype(&cur->data, key, strlen(key), (vtype)val);\
  147. return true; \
  148. } \
  149. }
  150. X_PACK_BSON_ENCODE_NUMBER(char, int32, int32_t)
  151. X_PACK_BSON_ENCODE_NUMBER(signed char, int32, int32_t)
  152. X_PACK_BSON_ENCODE_NUMBER(unsigned char, int32, int32_t)
  153. X_PACK_BSON_ENCODE_NUMBER(short, int32, int32_t)
  154. X_PACK_BSON_ENCODE_NUMBER(unsigned short, int32, int32_t)
  155. X_PACK_BSON_ENCODE_NUMBER(int, int32, int32_t)
  156. X_PACK_BSON_ENCODE_NUMBER(unsigned int, int32, int32_t)
  157. X_PACK_BSON_ENCODE_NUMBER(long, int64, int64_t)
  158. X_PACK_BSON_ENCODE_NUMBER(unsigned long, int64, int64_t)
  159. X_PACK_BSON_ENCODE_NUMBER(long long, int64, int64_t)
  160. X_PACK_BSON_ENCODE_NUMBER(unsigned long long, int64, int64_t)
  161. X_PACK_BSON_ENCODE_NUMBER(float, double, double)
  162. X_PACK_BSON_ENCODE_NUMBER(double, double, double)
  163. X_PACK_BSON_ENCODE_NUMBER(long double, double, double)
  164. private:
  165. std::vector<std::string> indexStr;
  166. std::list<std::string> errCase;
  167. std::list<Node*> nodes;
  168. Node *cur;
  169. };
  170. }
  171. #endif