proton/codec/encoder.hpp

Go to the documentation of this file.
00001 #ifndef PROTON_CODEC_ENCODER_HPP
00002 #define PROTON_CODEC_ENCODER_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 
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     // Undefined template to  prevent pointers being implicitly converted to bool.
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 {   // Protect the world from fallback operator<<
00183 
00184 using namespace internal;
00185 
00186 sfinae::no operator<<(encoder const&, const sfinae::any_t &); // Fallback
00187 
00188 template<typename T> struct is_encodable : public sfinae {
00189     static yes test(encoder&);
00190     static no test(...);         // Failed test, no match.
00191     static encoder* e;
00192     static const T* t;
00193     static bool const value = sizeof(test(*e << *t)) == sizeof(yes);
00194 };
00195 
00196 // Avoid recursion
00197 template <> struct is_encodable<value> : public true_type {};
00198 
00199 } // is_encodable_impl
00200 
00201 using is_encodable_impl::is_encodable;
00202 
00203 // Metafunction to test if a class looks like an encodable map from K to T.
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 } // codec
00219 } // proton
00220 
00221 #endif 

Generated on 17 Jan 2019 for Qpid Proton C++ by  doxygen 1.6.1