Specific.hh 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * https://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #ifndef avro_Codec_hh__
  19. #define avro_Codec_hh__
  20. #include "array"
  21. #include <algorithm>
  22. #include <map>
  23. #include <string>
  24. #include <vector>
  25. #include "boost/blank.hpp"
  26. #include "AvroTraits.hh"
  27. #include "Config.hh"
  28. #include "Decoder.hh"
  29. #include "Encoder.hh"
  30. /**
  31. * A bunch of templates and specializations for encoding and decoding
  32. * specific types.
  33. *
  34. * Primitive AVRO types BOOLEAN, INT, LONG, FLOAT, DOUBLE, STRING and BYTES
  35. * get decoded to and encoded from C++ types bool, int32_t, int64_t, float,
  36. * double, std::string and std::vector<uint8_t> respectively. In addition,
  37. * std::vector<T> for arbitrary type T gets encoded as an Avro array of T.
  38. * Similarly, std::map<std::string, T> for arbitrary type T gets encoded
  39. * as an Avro map with value type T.
  40. *
  41. * Users can have their custom types encoded/decoded by specializing
  42. * avro::codec_traits class for their types.
  43. */
  44. namespace avro {
  45. typedef boost::blank null;
  46. template<typename T>
  47. void encode(Encoder &e, const T &t);
  48. template<typename T>
  49. void decode(Decoder &d, T &t);
  50. /**
  51. * Codec_traits tells avro how to encode and decode an object of given type.
  52. *
  53. * The class is expected to have two static methods:
  54. * \li static void encode(Encoder& e, const T& value);
  55. * \li static void decode(Decoder& e, T& value);
  56. * The default is empty.
  57. */
  58. template<typename T>
  59. struct codec_traits;
  60. /**
  61. * codec_traits for Avro boolean.
  62. */
  63. template<>
  64. struct codec_traits<bool> {
  65. /**
  66. * Encodes a given value.
  67. */
  68. static void encode(Encoder &e, bool b) {
  69. e.encodeBool(b);
  70. }
  71. /**
  72. * Decodes into a given value.
  73. */
  74. static void decode(Decoder &d, bool &b) {
  75. b = d.decodeBool();
  76. }
  77. };
  78. /**
  79. * codec_traits for Avro int.
  80. */
  81. template<>
  82. struct codec_traits<int32_t> {
  83. /**
  84. * Encodes a given value.
  85. */
  86. static void encode(Encoder &e, int32_t i) {
  87. e.encodeInt(i);
  88. }
  89. /**
  90. * Decodes into a given value.
  91. */
  92. static void decode(Decoder &d, int32_t &i) {
  93. i = d.decodeInt();
  94. }
  95. };
  96. /**
  97. * codec_traits for Avro long.
  98. */
  99. template<>
  100. struct codec_traits<int64_t> {
  101. /**
  102. * Encodes a given value.
  103. */
  104. static void encode(Encoder &e, int64_t l) {
  105. e.encodeLong(l);
  106. }
  107. /**
  108. * Decodes into a given value.
  109. */
  110. static void decode(Decoder &d, int64_t &l) {
  111. l = d.decodeLong();
  112. }
  113. };
  114. /**
  115. * codec_traits for Avro float.
  116. */
  117. template<>
  118. struct codec_traits<float> {
  119. /**
  120. * Encodes a given value.
  121. */
  122. static void encode(Encoder &e, float f) {
  123. e.encodeFloat(f);
  124. }
  125. /**
  126. * Decodes into a given value.
  127. */
  128. static void decode(Decoder &d, float &f) {
  129. f = d.decodeFloat();
  130. }
  131. };
  132. /**
  133. * codec_traits for Avro double.
  134. */
  135. template<>
  136. struct codec_traits<double> {
  137. /**
  138. * Encodes a given value.
  139. */
  140. static void encode(Encoder &e, double d) {
  141. e.encodeDouble(d);
  142. }
  143. /**
  144. * Decodes into a given value.
  145. */
  146. static void decode(Decoder &d, double &dbl) {
  147. dbl = d.decodeDouble();
  148. }
  149. };
  150. /**
  151. * codec_traits for Avro string.
  152. */
  153. template<>
  154. struct codec_traits<std::string> {
  155. /**
  156. * Encodes a given value.
  157. */
  158. static void encode(Encoder &e, const std::string &s) {
  159. e.encodeString(s);
  160. }
  161. /**
  162. * Decodes into a given value.
  163. */
  164. static void decode(Decoder &d, std::string &s) {
  165. s = d.decodeString();
  166. }
  167. };
  168. /**
  169. * codec_traits for Avro bytes.
  170. */
  171. template<>
  172. struct codec_traits<std::vector<uint8_t>> {
  173. /**
  174. * Encodes a given value.
  175. */
  176. static void encode(Encoder &e, const std::vector<uint8_t> &b) {
  177. e.encodeBytes(b);
  178. }
  179. /**
  180. * Decodes into a given value.
  181. */
  182. static void decode(Decoder &d, std::vector<uint8_t> &s) {
  183. d.decodeBytes(s);
  184. }
  185. };
  186. /**
  187. * codec_traits for Avro fixed.
  188. */
  189. template<size_t N>
  190. struct codec_traits<std::array<uint8_t, N>> {
  191. /**
  192. * Encodes a given value.
  193. */
  194. static void encode(Encoder &e, const std::array<uint8_t, N> &b) {
  195. e.encodeFixed(b.data(), N);
  196. }
  197. /**
  198. * Decodes into a given value.
  199. */
  200. static void decode(Decoder &d, std::array<uint8_t, N> &s) {
  201. std::vector<uint8_t> v(N);
  202. d.decodeFixed(N, v);
  203. std::copy(v.data(), v.data() + N, s.data());
  204. }
  205. };
  206. /**
  207. * codec_traits for Avro arrays.
  208. */
  209. template<typename T>
  210. struct codec_traits<std::vector<T>> {
  211. /**
  212. * Encodes a given value.
  213. */
  214. static void encode(Encoder &e, const std::vector<T> &b) {
  215. e.arrayStart();
  216. if (!b.empty()) {
  217. e.setItemCount(b.size());
  218. for (typename std::vector<T>::const_iterator it = b.begin();
  219. it != b.end(); ++it) {
  220. e.startItem();
  221. avro::encode(e, *it);
  222. }
  223. }
  224. e.arrayEnd();
  225. }
  226. /**
  227. * Decodes into a given value.
  228. */
  229. static void decode(Decoder &d, std::vector<T> &s) {
  230. s.clear();
  231. for (size_t n = d.arrayStart(); n != 0; n = d.arrayNext()) {
  232. for (size_t i = 0; i < n; ++i) {
  233. T t;
  234. avro::decode(d, t);
  235. s.push_back(std::move(t));
  236. }
  237. }
  238. }
  239. };
  240. typedef codec_traits<std::vector<bool>::const_reference> bool_codec_traits;
  241. template<>
  242. struct codec_traits<std::conditional<avro::is_not_defined<bool_codec_traits>::value,
  243. std::vector<bool>::const_reference, void>::type> {
  244. /**
  245. * Encodes a given value.
  246. */
  247. static void encode(Encoder &e, std::vector<bool>::const_reference b) {
  248. e.encodeBool(b);
  249. }
  250. };
  251. /**
  252. * codec_traits for Avro maps.
  253. */
  254. template<typename T>
  255. struct codec_traits<std::map<std::string, T>> {
  256. /**
  257. * Encodes a given value.
  258. */
  259. static void encode(Encoder &e, const std::map<std::string, T> &b) {
  260. e.mapStart();
  261. if (!b.empty()) {
  262. e.setItemCount(b.size());
  263. for (typename std::map<std::string, T>::const_iterator
  264. it = b.begin();
  265. it != b.end(); ++it) {
  266. e.startItem();
  267. avro::encode(e, it->first);
  268. avro::encode(e, it->second);
  269. }
  270. }
  271. e.mapEnd();
  272. }
  273. /**
  274. * Decodes into a given value.
  275. */
  276. static void decode(Decoder &d, std::map<std::string, T> &s) {
  277. s.clear();
  278. for (size_t n = d.mapStart(); n != 0; n = d.mapNext()) {
  279. for (size_t i = 0; i < n; ++i) {
  280. std::string k;
  281. avro::decode(d, k);
  282. T &t = s[std::move(k)];
  283. avro::decode(d, t);
  284. }
  285. }
  286. }
  287. };
  288. /**
  289. * codec_traits for Avro null.
  290. */
  291. template<>
  292. struct codec_traits<avro::null> {
  293. /**
  294. * Encodes a given value.
  295. */
  296. static void encode(Encoder &e, const avro::null &) {
  297. e.encodeNull();
  298. }
  299. /**
  300. * Decodes into a given value.
  301. */
  302. static void decode(Decoder &d, avro::null &) {
  303. d.decodeNull();
  304. }
  305. };
  306. /**
  307. * Generic encoder function that makes use of the codec_traits.
  308. */
  309. template<typename T>
  310. void encode(Encoder &e, const T &t) {
  311. codec_traits<T>::encode(e, t);
  312. }
  313. /**
  314. * Generic decoder function that makes use of the codec_traits.
  315. */
  316. template<typename T>
  317. void decode(Decoder &d, T &t) {
  318. codec_traits<T>::decode(d, t);
  319. }
  320. } // namespace avro
  321. #endif // avro_Codec_hh__