proton/codec/decoder.hpp

Go to the documentation of this file.
00001 #ifndef PROTON_CODEC_DECODER_HPP
00002 #define PROTON_CODEC_DECODER_HPP
00003 
00004 /*
00005  *
00006  * Licensed to the Apache Software Foundation (ASF) under one
00007  * or more contributor license agreements.  See the NOTICE file
00008  * distributed with this work for additional information
00009  * regarding copyright ownership.  The ASF licenses this file
00010  * to you under the Apache License, Version 2.0 (the
00011  * "License"); you may not use this file except in compliance
00012  * with the License.  You may obtain a copy of the License at
00013  *
00014  *   http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing,
00017  * software distributed under the License is distributed on an
00018  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
00019  * KIND, either express or implied.  See the License for the
00020  * specific language governing permissions and limitations
00021  * under the License.
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;                     // Extract as a known integer type
00213     i = v;                      // C++ conversion to the target type.
00214     return d;
00215 }
00216 
00217 } // codec
00218 } // proton
00219 
00220 #endif // PROTON_CODEC_DECODER_HPP

Generated on 8 Oct 2019 for Qpid Proton C++ by  doxygen 1.6.1