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 <utility>
00031
00032 namespace proton {
00033
00034 class annotation_key;
00035 class message_id;
00036 class scalar;
00037 class value;
00038
00039 namespace internal {
00040 class value_base;
00041 }
00042
00043 namespace codec {
00044
00051 class decoder : public internal::data {
00052 public:
00056 explicit decoder(const data& d, bool exact=false) : data(d), exact_(exact) {}
00057
00060 PN_CPP_EXTERN explicit decoder(const internal::value_base&, bool exact=false);
00061
00064 PN_CPP_EXTERN void decode(const char* buffer, size_t size);
00065
00068 PN_CPP_EXTERN void decode(const std::string&);
00069
00071 PN_CPP_EXTERN bool more();
00072
00078 PN_CPP_EXTERN type_id next_type();
00079
00086 PN_CPP_EXTERN decoder& operator>>(bool&);
00087 PN_CPP_EXTERN decoder& operator>>(uint8_t&);
00088 PN_CPP_EXTERN decoder& operator>>(int8_t&);
00089 PN_CPP_EXTERN decoder& operator>>(uint16_t&);
00090 PN_CPP_EXTERN decoder& operator>>(int16_t&);
00091 PN_CPP_EXTERN decoder& operator>>(uint32_t&);
00092 PN_CPP_EXTERN decoder& operator>>(int32_t&);
00093 PN_CPP_EXTERN decoder& operator>>(wchar_t&);
00094 PN_CPP_EXTERN decoder& operator>>(uint64_t&);
00095 PN_CPP_EXTERN decoder& operator>>(int64_t&);
00096 PN_CPP_EXTERN decoder& operator>>(timestamp&);
00097 PN_CPP_EXTERN decoder& operator>>(float&);
00098 PN_CPP_EXTERN decoder& operator>>(double&);
00099 PN_CPP_EXTERN decoder& operator>>(decimal32&);
00100 PN_CPP_EXTERN decoder& operator>>(decimal64&);
00101 PN_CPP_EXTERN decoder& operator>>(decimal128&);
00102 PN_CPP_EXTERN decoder& operator>>(uuid&);
00103 PN_CPP_EXTERN decoder& operator>>(std::string&);
00104 PN_CPP_EXTERN decoder& operator>>(symbol&);
00105 PN_CPP_EXTERN decoder& operator>>(binary&);
00106 PN_CPP_EXTERN decoder& operator>>(message_id&);
00107 PN_CPP_EXTERN decoder& operator>>(annotation_key&);
00108 PN_CPP_EXTERN decoder& operator>>(scalar&);
00109 PN_CPP_EXTERN decoder& operator>>(internal::value_base&);
00110 PN_CPP_EXTERN decoder& operator>>(null&);
00112
00117 PN_CPP_EXTERN decoder& operator>>(start&);
00118
00121 PN_CPP_EXTERN decoder& operator>>(const finish&);
00122
00124 template <class T> struct sequence_ref { T& ref; sequence_ref(T& r) : ref(r) {} };
00125 template <class T> struct associative_ref { T& ref; associative_ref(T& r) : ref(r) {} };
00126 template <class T> struct pair_sequence_ref { T& ref; pair_sequence_ref(T& r) : ref(r) {} };
00127
00128 template <class T> static sequence_ref<T> sequence(T& x) { return sequence_ref<T>(x); }
00129 template <class T> static associative_ref<T> associative(T& x) { return associative_ref<T>(x); }
00130 template <class T> static pair_sequence_ref<T> pair_sequence(T& x) { return pair_sequence_ref<T>(x); }
00132
00136 template <class T> decoder& operator>>(sequence_ref<T> r) {
00137 start s;
00138 *this >> s;
00139 if (s.is_described) next();
00140 r.ref.resize(s.size);
00141 for (typename T::iterator i = r.ref.begin(); i != r.ref.end(); ++i)
00142 *this >> *i;
00143 return *this;
00144 }
00145
00147 template <class T> decoder& operator>>(associative_ref<T> r) {
00148 using namespace internal;
00149 start s;
00150 *this >> s;
00151 assert_type_equal(MAP, s.type);
00152 r.ref.clear();
00153 for (size_t i = 0; i < s.size/2; ++i) {
00154 typename remove_const<typename T::key_type>::type k;
00155 typename remove_const<typename T::mapped_type>::type v;
00156 *this >> k >> v;
00157 r.ref[k] = v;
00158 }
00159 return *this;
00160 }
00161
00164 template <class T> decoder& operator>>(pair_sequence_ref<T> r) {
00165 using namespace internal;
00166 start s;
00167 *this >> s;
00168 assert_type_equal(MAP, s.type);
00169 r.ref.clear();
00170 for (size_t i = 0; i < s.size/2; ++i) {
00171 typedef typename T::value_type value_type;
00172 typename remove_const<typename value_type::first_type>::type k;
00173 typename remove_const<typename value_type::second_type>::type v;
00174 *this >> k >> v;
00175 r.ref.push_back(value_type(k, v));
00176 }
00177 return *this;
00178 }
00179
00180 private:
00181 type_id pre_get();
00182 template <class T, class U> decoder& extract(T& x, U (*get)(pn_data_t*));
00183 bool exact_;
00184
00185 friend class message;
00186 };
00187
00190 template<class T> T get(decoder& d) {
00191 assert_type_equal(internal::type_id_of<T>::value, d.next_type());
00192 T x;
00193 d >> x;
00194 return x;
00195 }
00197
00200 template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, decoder&>::type
00201 operator>>(decoder& d, T& i) {
00202 using namespace internal;
00203 typename integer_type<sizeof(T), is_signed<T>::value>::type v;
00204 d >> v;
00205 i = v;
00206 return d;
00207 }
00208
00209 }
00210 }
00211
00212 #endif // PROTON_CODEC_DECODER_HPP