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&);
00117
00122 PN_CPP_EXTERN decoder& operator>>(start&);
00123
00126 PN_CPP_EXTERN decoder& operator>>(const finish&);
00127
00129 template <class T> struct sequence_ref { T& ref; sequence_ref(T& r) : ref(r) {} };
00130 template <class T> struct associative_ref { T& ref; associative_ref(T& r) : ref(r) {} };
00131 template <class T> struct pair_sequence_ref { T& ref; pair_sequence_ref(T& r) : ref(r) {} };
00132
00133 template <class T> static sequence_ref<T> sequence(T& x) { return sequence_ref<T>(x); }
00134 template <class T> static associative_ref<T> associative(T& x) { return associative_ref<T>(x); }
00135 template <class T> static pair_sequence_ref<T> pair_sequence(T& x) { return pair_sequence_ref<T>(x); }
00137
00141 template <class T> decoder& operator>>(sequence_ref<T> r) {
00142 start s;
00143 *this >> s;
00144 if (s.is_described) next();
00145 r.ref.resize(s.size);
00146 for (typename T::iterator i = r.ref.begin(); i != r.ref.end(); ++i)
00147 *this >> *i;
00148 return *this;
00149 }
00150
00152 template <class T> decoder& operator>>(associative_ref<T> r) {
00153 using namespace internal;
00154 start s;
00155 *this >> s;
00156 assert_type_equal(MAP, s.type);
00157 r.ref.clear();
00158 for (size_t i = 0; i < s.size/2; ++i) {
00159 typename remove_const<typename T::key_type>::type k;
00160 typename remove_const<typename T::mapped_type>::type v;
00161 *this >> k >> v;
00162 r.ref[k] = v;
00163 }
00164 return *this;
00165 }
00166
00169 template <class T> decoder& operator>>(pair_sequence_ref<T> r) {
00170 using namespace internal;
00171 start s;
00172 *this >> s;
00173 assert_type_equal(MAP, s.type);
00174 r.ref.clear();
00175 for (size_t i = 0; i < s.size/2; ++i) {
00176 typedef typename T::value_type value_type;
00177 typename remove_const<typename value_type::first_type>::type k;
00178 typename remove_const<typename value_type::second_type>::type v;
00179 *this >> k >> v;
00180 r.ref.push_back(value_type(k, v));
00181 }
00182 return *this;
00183 }
00184
00185 private:
00186 type_id pre_get();
00187 template <class T, class U> decoder& extract(T& x, U (*get)(pn_data_t*));
00188 bool exact_;
00189
00190 friend class message;
00191 };
00192
00195 template<class T> T get(decoder& d) {
00196 assert_type_equal(internal::type_id_of<T>::value, d.next_type());
00197 T x;
00198 d >> x;
00199 return x;
00200 }
00202
00205 template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, decoder&>::type
00206 operator>>(decoder& d, T& i) {
00207 using namespace internal;
00208 typename integer_type<sizeof(T), is_signed<T>::value>::type v;
00209 d >> v;
00210 i = v;
00211 return d;
00212 }
00213
00214 }
00215 }
00216
00217 #endif // PROTON_CODEC_DECODER_HPP