json_encoder.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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_JSON_ENCODER_H
  17. #define __X_PACK_JSON_ENCODER_H
  18. #include <string>
  19. #include "rapidjson_custom.h"
  20. #include "thirdparty/rapidjson/prettywriter.h"
  21. #include "thirdparty/rapidjson/stringbuffer.h"
  22. #include "xencoder.h"
  23. namespace xpack {
  24. class JsonEncoder:public XEncoder<JsonEncoder>, private noncopyable {
  25. typedef rapidjson::StringBuffer JSON_WRITER_BUFFER;
  26. typedef rapidjson::Writer<rapidjson::StringBuffer> JSON_WRITER_WRITER;
  27. typedef rapidjson::PrettyWriter<rapidjson::StringBuffer> JSON_WRITER_PRETTY;
  28. public:
  29. friend class XEncoder<JsonEncoder>;
  30. using xdoc_type::encode;
  31. JsonEncoder(int indentCount=-1, char indentChar=' ') {
  32. _buf = new JSON_WRITER_BUFFER;
  33. if (indentCount < 0) {
  34. _writer = new JSON_WRITER_WRITER(*_buf);
  35. _pretty = NULL;
  36. } else {
  37. _pretty = new JSON_WRITER_PRETTY(*_buf);
  38. _pretty->SetIndent(indentChar, indentCount);
  39. _writer = NULL;
  40. }
  41. }
  42. ~JsonEncoder() {
  43. if (NULL != _buf) {
  44. delete _buf;
  45. _buf = NULL;
  46. }
  47. if (NULL != _writer) {
  48. delete _writer;
  49. _writer = NULL;
  50. }
  51. if (NULL != _pretty) {
  52. delete _pretty;
  53. _pretty = NULL;
  54. }
  55. }
  56. inline const char *Type() const {
  57. return "json";
  58. }
  59. inline const char *IndexKey(size_t index) {
  60. (void)index;
  61. return NULL;
  62. }
  63. std::string String() {
  64. return _buf->GetString();
  65. }
  66. public:
  67. void ArrayBegin(const char *key, const Extend *ext) {
  68. (void)ext;
  69. xpack_set_key(key);
  70. if (NULL != _writer) {
  71. _writer->StartArray();
  72. } else {
  73. _pretty->StartArray();
  74. }
  75. }
  76. void ArrayEnd(const char *key, const Extend *ext) {
  77. (void)key;
  78. (void)ext;
  79. if (NULL != _writer) {
  80. _writer->EndArray();
  81. } else {
  82. _pretty->EndArray();
  83. }
  84. }
  85. void ObjectBegin(const char *key, const Extend *ext) {
  86. (void)ext;
  87. xpack_set_key(key);
  88. if (NULL != _writer) {
  89. _writer->StartObject();
  90. } else {
  91. _pretty->StartObject();
  92. }
  93. }
  94. void ObjectEnd(const char *key, const Extend *ext) {
  95. (void)key;
  96. (void)ext;
  97. if (NULL != _writer) {
  98. _writer->EndObject();
  99. } else {
  100. _pretty->EndObject();
  101. }
  102. }
  103. public:
  104. #define X_PACK_JSON_ENCODE(cond, f) \
  105. if ((cond) && Extend::OmitEmpty(ext)){ \
  106. return false; \
  107. } \
  108. xpack_set_key(key); \
  109. if (NULL != _writer) { \
  110. _writer->f(val); \
  111. } else { \
  112. _pretty->f(val); \
  113. } \
  114. return true
  115. bool writeNull(const char*key, const Extend *ext) {
  116. if (Extend::OmitEmpty(ext)) {
  117. return false;
  118. }
  119. xpack_set_key(key);
  120. if (NULL != _writer) {
  121. _writer->Null();
  122. } else {
  123. _pretty->Null();
  124. }
  125. return true;
  126. }
  127. bool encode(const char*key, const std::string &val, const Extend *ext) {
  128. X_PACK_JSON_ENCODE(val.empty(), String);
  129. }
  130. bool encode(const char*key, const bool &val, const Extend *ext) {
  131. X_PACK_JSON_ENCODE(!val, Bool);
  132. }
  133. bool encode(const char*key, const char &val, const Extend *ext) {
  134. return this->encode(key, (const int&)val, ext);
  135. }
  136. bool encode(const char*key, const signed char &val, const Extend *ext) {
  137. return this->encode(key, (const int&)val, ext);
  138. }
  139. bool encode(const char*key, const unsigned char &val, const Extend *ext) {
  140. return this->encode(key, (const unsigned int&)val, ext);
  141. }
  142. bool encode(const char*key, const short & val, const Extend *ext) {
  143. return this->encode(key, (const int&)val, ext);
  144. }
  145. bool encode(const char*key, const unsigned short & val, const Extend *ext) {
  146. return this->encode(key, (const unsigned int&)val, ext);
  147. }
  148. bool encode(const char*key, const int& val, const Extend *ext) {
  149. X_PACK_JSON_ENCODE(val==0, Int);
  150. }
  151. bool encode(const char*key, const unsigned int& val, const Extend *ext) {
  152. X_PACK_JSON_ENCODE(val==0, Uint);
  153. }
  154. bool encode(const char*key, const long long& val, const Extend *ext) {
  155. X_PACK_JSON_ENCODE(val==0, Int64);
  156. }
  157. bool encode(const char*key, const unsigned long long & val, const Extend *ext) {
  158. X_PACK_JSON_ENCODE(val==0, Uint64);
  159. }
  160. bool encode(const char*key, const long &val, const Extend *ext) {
  161. return this->encode(key, (const long long&)val, ext);
  162. }
  163. bool encode(const char*key, const unsigned long &val, const Extend *ext) {
  164. return this->encode(key, (const unsigned long long&)val, ext);
  165. }
  166. bool encode(const char*key, const float & val, const Extend *ext) {
  167. X_PACK_JSON_ENCODE(val==0, Double);
  168. }
  169. bool encode(const char*key, const double & val, const Extend *ext) {
  170. X_PACK_JSON_ENCODE(val==0, Double);
  171. }
  172. bool encode(const char*key, const long double & val, const Extend *ext) {
  173. X_PACK_JSON_ENCODE(val==0, Double);
  174. }
  175. // map<int, T> xml not support use number as label
  176. template <class K, class T>
  177. typename x_enable_if<numeric<K>::is_integer, bool>::type encode(const char*key, const std::map<K,T>& val, const Extend *ext) {
  178. std::map<std::string,T> tmpv;
  179. for (typename std::map<K,T>::const_iterator iter = val.begin(); iter!=val.end(); ++iter) {
  180. tmpv[Util::itoa(iter->first)] = iter->second;
  181. }
  182. return this->encode(key, tmpv, ext);
  183. }
  184. #ifdef XPACK_SUPPORT_QT
  185. template <class K, class T>
  186. typename x_enable_if<numeric<K>::is_integer, bool>::type encode(const char*key, const QMap<K,T>& val, const Extend *ext) {
  187. std::map<std::string,T> tmpv;
  188. for (typename QMap<K,T>::const_iterator iter = val.constBegin(); iter!=val.constEnd(); ++iter) {
  189. tmpv[Util::itoa(iter.key())] = iter.value();
  190. }
  191. return this->encode(key, tmpv, ext);
  192. }
  193. #endif
  194. private:
  195. void xpack_set_key(const char*key) { // openssl defined set_key macro, so we named it xpack_set_key
  196. if (NULL!=key && key[0]!='\0') {
  197. if (NULL != _writer) {
  198. _writer->Key(key);
  199. } else {
  200. _pretty->Key(key);
  201. }
  202. }
  203. }
  204. JSON_WRITER_BUFFER* _buf;
  205. JSON_WRITER_WRITER* _writer;
  206. JSON_WRITER_PRETTY* _pretty;
  207. };
  208. }
  209. #endif