00001 #ifndef PROTON_CODEC_DECODER_HPP
00002 #define PROTON_CODEC_DECODER_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
00032 #include <utility>
00033
00036
00037 namespace proton {
00038
00039 class annotation_key;
00040 class message_id;
00041 class scalar;
00042 class value;
00043
00044 namespace internal {
00045 class value_base;
00046 }
00047
00048 namespace codec {
00049
00056 class decoder : public internal::data {
00057 public:
00061 explicit decoder(const data& d, bool exact=false) : data(d), exact_(exact) {}
00062
00065 PN_CPP_EXTERN explicit decoder(const internal::value_base&, bool exact=false);
00066
00069 PN_CPP_EXTERN void decode(const char* buffer, size_t size);
00070
00073 PN_CPP_EXTERN void decode(const std::string&);
00074
00076 PN_CPP_EXTERN bool more();
00077
00083 PN_CPP_EXTERN type_id next_type();
00084
00091 PN_CPP_EXTERN decoder& operator>>(bool&);
00092 PN_CPP_EXTERN decoder& operator>>(uint8_t&);
00093 PN_CPP_EXTERN decoder& operator>>(int8_t&);
00094 PN_CPP_EXTERN decoder& operator>>(uint16_t&);
00095 PN_CPP_EXTERN decoder& operator>>(int16_t&);
00096 PN_CPP_EXTERN decoder& operator>>(uint32_t&);
00097 PN_CPP_EXTERN decoder& operator>>(int32_t&);
00098 PN_CPP_EXTERN decoder& operator>>(wchar_t&);
00099 PN_CPP_EXTERN decoder& operator>>(uint64_t&);
00100 PN_CPP_EXTERN decoder& operator>>(int64_t&);
00101 PN_CPP_EXTERN decoder& operator>>(timestamp&);
00102 PN_CPP_EXTERN decoder& operator>>(float&);
00103 PN_CPP_EXTERN decoder& operator>>(double&);
00104 PN_CPP_EXTERN decoder& operator>>(decimal32&);
00105 PN_CPP_EXTERN decoder& operator>>(decimal64&);
00106 PN_CPP_EXTERN decoder& operator>>(decimal128&);
00107 PN_CPP_EXTERN decoder& operator>>(uuid&);
00108 PN_CPP_EXTERN decoder& operator>>(std::string&);
00109 PN_CPP_EXTERN decoder& operator>>(symbol&);
00110 PN_CPP_EXTERN decoder& operator>>(binary&);
00111 PN_CPP_EXTERN decoder& operator>>(message_id&);
00112 PN_CPP_EXTERN decoder& operator>>(annotation_key&);
00113 PN_CPP_EXTERN decoder& operator>>(scalar&);
00114 PN_CPP_EXTERN decoder& operator>>(internal::value_base&);
00115 PN_CPP_EXTERN decoder& operator>>(null&);
00116 #if PN_CPP_HAS_NULLPTR
00117 PN_CPP_EXTERN decoder& operator>>(decltype(nullptr)&);
00118 #endif
00120
00125 PN_CPP_EXTERN decoder& operator>>(start&);
00126
00129 PN_CPP_EXTERN decoder& operator>>(const finish&);
00130
00132 template <class T> struct sequence_ref { T& ref; sequence_ref(T& r) : ref(r) {} };
00133 template <class T> struct associative_ref { T& ref; associative_ref(T& r) : ref(r) {} };
00134 template <class T> struct pair_sequence_ref { T& ref; pair_sequence_ref(T& r) : ref(r) {} };
00135
00136 template <class T> static sequence_ref<T> sequence(T& x) { return sequence_ref<T>(x); }
00137 template <class T> static associative_ref<T> associative(T& x) { return associative_ref<T>(x); }
00138 template <class T> static pair_sequence_ref<T> pair_sequence(T& x) { return pair_sequence_ref<T>(x); }
00140
00144 template <class T> decoder& operator>>(sequence_ref<T> r) {
00145 start s;
00146 *this >> s;
00147 if (s.is_described) next();
00148 r.ref.resize(s.size);
00149 for (typename T::iterator i = r.ref.begin(); i != r.ref.end(); ++i)
00150 *this >> *i;
00151 return *this;
00152 }
00153
00155 template <class T> decoder& operator>>(associative_ref<T> r) {
00156 using namespace internal;
00157 start s;
00158 *this >> s;
00159 assert_type_equal(MAP, s.type);
00160 r.ref.clear();
00161 for (size_t i = 0; i < s.size/2; ++i) {
00162 typename remove_const<typename T::key_type>::type k;
00163 typename remove_const<typename T::mapped_type>::type v;
00164 *this >> k >> v;
00165 r.ref[k] = v;
00166 }
00167 return *this;
00168 }
00169
00172 template <class T> decoder& operator>>(pair_sequence_ref<T> r) {
00173 using namespace internal;
00174 start s;
00175 *this >> s;
00176 assert_type_equal(MAP, s.type);
00177 r.ref.clear();
00178 for (size_t i = 0; i < s.size/2; ++i) {
00179 typedef typename T::value_type value_type;
00180 typename remove_const<typename value_type::first_type>::type k;
00181 typename remove_const<typename value_type::second_type>::type v;
00182 *this >> k >> v;
00183 r.ref.push_back(value_type(k, v));
00184 }
00185 return *this;
00186 }
00187
00188 private:
00189 type_id pre_get();
00190 template <class T, class U> decoder& extract(T& x, U (*get)(pn_data_t*));
00191 bool exact_;
00192
00193 friend class message;
00194 };
00195
00198 template<class T> T get(decoder& d) {
00199 assert_type_equal(internal::type_id_of<T>::value, d.next_type());
00200 T x;
00201 d >> x;
00202 return x;
00203 }
00205
00208 template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, decoder&>::type
00209 operator>>(decoder& d, T& i) {
00210 using namespace internal;
00211 typename integer_type<sizeof(T), is_signed<T>::value>::type v;
00212 d >> v;
00213 i = v;
00214 return d;
00215 }
00216
00217 }
00218 }
00219
00220 #endif // PROTON_CODEC_DECODER_HPP