00001 #ifndef PROTON_CODEC_ENCODER_HPP
00002 #define PROTON_CODEC_ENCODER_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "../internal/data.hpp"
00026 #include "../internal/type_traits.hpp"
00027 #include "../types_fwd.hpp"
00028 #include "./common.hpp"
00029
00030 #include <proton/type_compat.h>
00031
00034
00035 namespace proton {
00036 class scalar_base;
00037
00038 namespace internal{
00039 class value_base;
00040 }
00041
00042 namespace codec {
00043
00050 class encoder : public internal::data {
00051 public:
00053 explicit encoder(const data& d) : data(d) {}
00054
00056 PN_CPP_EXTERN explicit encoder(internal::value_base& v);
00057
00066 PN_CPP_EXTERN bool encode(char* buffer, size_t& size);
00067
00070 PN_CPP_EXTERN void encode(std::string&);
00071
00074 PN_CPP_EXTERN std::string encode();
00075
00078 PN_CPP_EXTERN encoder& operator<<(bool);
00079 PN_CPP_EXTERN encoder& operator<<(uint8_t);
00080 PN_CPP_EXTERN encoder& operator<<(int8_t);
00081 PN_CPP_EXTERN encoder& operator<<(uint16_t);
00082 PN_CPP_EXTERN encoder& operator<<(int16_t);
00083 PN_CPP_EXTERN encoder& operator<<(uint32_t);
00084 PN_CPP_EXTERN encoder& operator<<(int32_t);
00085 PN_CPP_EXTERN encoder& operator<<(wchar_t);
00086 PN_CPP_EXTERN encoder& operator<<(uint64_t);
00087 PN_CPP_EXTERN encoder& operator<<(int64_t);
00088 PN_CPP_EXTERN encoder& operator<<(timestamp);
00089 PN_CPP_EXTERN encoder& operator<<(float);
00090 PN_CPP_EXTERN encoder& operator<<(double);
00091 PN_CPP_EXTERN encoder& operator<<(decimal32);
00092 PN_CPP_EXTERN encoder& operator<<(decimal64);
00093 PN_CPP_EXTERN encoder& operator<<(decimal128);
00094 PN_CPP_EXTERN encoder& operator<<(const uuid&);
00095 PN_CPP_EXTERN encoder& operator<<(const std::string&);
00096 PN_CPP_EXTERN encoder& operator<<(const symbol&);
00097 PN_CPP_EXTERN encoder& operator<<(const binary&);
00098 PN_CPP_EXTERN encoder& operator<<(const scalar_base&);
00099 PN_CPP_EXTERN encoder& operator<<(const null&);
00100 #if PN_CPP_HAS_NULLPTR
00101 PN_CPP_EXTERN encoder& operator<<(decltype(nullptr));
00102 #endif
00104
00109 PN_CPP_EXTERN encoder& operator<<(const internal::value_base&);
00110
00112 PN_CPP_EXTERN encoder& operator<<(const start&);
00113
00115 PN_CPP_EXTERN encoder& operator<<(const finish&);
00116
00118
00119
00120 template <class T> void* operator<<(const T*);
00121
00122 template <class T> struct list_cref { T& ref; list_cref(T& r) : ref(r) {} };
00123 template <class T> struct map_cref { T& ref; map_cref(T& r) : ref(r) {} };
00124
00125 template <class T> struct array_cref {
00126 start array_start;
00127 T& ref;
00128 array_cref(T& r, type_id el, bool described) : array_start(ARRAY, el, described), ref(r) {}
00129 };
00130
00131 template <class T> static list_cref<T> list(T& x) { return list_cref<T>(x); }
00132 template <class T> static map_cref<T> map(T& x) { return map_cref<T>(x); }
00133 template <class T> static array_cref<T> array(T& x, type_id element, bool described=false) {
00134 return array_cref<T>(x, element, described);
00135 }
00136
00137 template <class T> encoder& operator<<(const map_cref<T>& x) {
00138 internal::state_guard sg(*this);
00139 *this << start::map();
00140 for (typename T::const_iterator i = x.ref.begin(); i != x.ref.end(); ++i)
00141 *this << i->first << i->second;
00142 *this << finish();
00143 return *this;
00144 }
00145
00146 template <class T> encoder& operator<<(const list_cref<T>& x) {
00147 internal::state_guard sg(*this);
00148 *this << start::list();
00149 for (typename T::const_iterator i = x.ref.begin(); i != x.ref.end(); ++i)
00150 *this << *i;
00151 *this << finish();
00152 return *this;
00153 }
00154
00155 template <class T> encoder& operator<<(const array_cref<T>& x) {
00156 internal::state_guard sg(*this);
00157 *this << x.array_start;
00158 for (typename T::const_iterator i = x.ref.begin(); i != x.ref.end(); ++i)
00159 *this << *i;
00160 *this << finish();
00161 return *this;
00162 }
00164
00165 private:
00166 template<class T, class U> encoder& insert(const T& x, int (*put)(pn_data_t*, U));
00167 void check(long result);
00168 };
00169
00171 inline encoder& operator<<(encoder& e, const char* s) { return e << std::string(s); }
00172
00174 template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, encoder&>::type
00175 operator<<(encoder& e, T i) {
00176 using namespace internal;
00177 return e << static_cast<typename integer_type<sizeof(T), is_signed<T>::value>::type>(i);
00178 }
00179
00181
00182 namespace is_encodable_impl {
00183
00184 using namespace internal;
00185
00186 sfinae::no operator<<(encoder const&, const sfinae::any_t &);
00187
00188 template<typename T> struct is_encodable : public sfinae {
00189 static yes test(encoder&);
00190 static no test(...);
00191 static encoder* e;
00192 static const T* t;
00193 static bool const value = sizeof(test(*e << *t)) == sizeof(yes);
00194 };
00195
00196
00197 template <> struct is_encodable<value> : public true_type {};
00198
00199 }
00200
00201 using is_encodable_impl::is_encodable;
00202
00203
00204 template <class M, class K, class T, class Enable = void>
00205 struct is_encodable_map : public internal::false_type {};
00206
00207 template <class M, class K, class T> struct is_encodable_map<
00208 M, K, T, typename internal::enable_if<
00209 internal::is_same<K, typename M::key_type>::value &&
00210 internal::is_same<T, typename M::mapped_type>::value &&
00211 is_encodable<M>::value
00212 >::type
00213 > : public internal::true_type {};
00214
00215
00217
00218 }
00219 }
00220
00221 #endif