Qpid Proton C++ API  0.18.1
encoder.hpp
Go to the documentation of this file.
1 #ifndef PROTON_CODEC_ENCODER_HPP
2 #define PROTON_CODEC_ENCODER_HPP
3 
4 /*
5  *
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  *
23  */
24 
25 #include "../internal/data.hpp"
26 #include "../internal/type_traits.hpp"
27 #include "../types_fwd.hpp"
28 #include "./common.hpp"
29 
30 #include <proton/type_compat.h>
31 
34 
35 namespace proton {
36 class scalar_base;
37 
38 namespace internal{
39 class value_base;
40 }
41 
42 namespace codec {
43 
50 class encoder : public internal::data {
51  public:
53  explicit encoder(const data& d) : data(d) {}
54 
56  PN_CPP_EXTERN explicit encoder(internal::value_base& v);
57 
66  PN_CPP_EXTERN bool encode(char* buffer, size_t& size);
67 
70  PN_CPP_EXTERN void encode(std::string&);
71 
74  PN_CPP_EXTERN std::string encode();
75 
78  PN_CPP_EXTERN encoder& operator<<(bool);
79  PN_CPP_EXTERN encoder& operator<<(uint8_t);
80  PN_CPP_EXTERN encoder& operator<<(int8_t);
81  PN_CPP_EXTERN encoder& operator<<(uint16_t);
82  PN_CPP_EXTERN encoder& operator<<(int16_t);
83  PN_CPP_EXTERN encoder& operator<<(uint32_t);
84  PN_CPP_EXTERN encoder& operator<<(int32_t);
85  PN_CPP_EXTERN encoder& operator<<(wchar_t);
86  PN_CPP_EXTERN encoder& operator<<(uint64_t);
87  PN_CPP_EXTERN encoder& operator<<(int64_t);
88  PN_CPP_EXTERN encoder& operator<<(timestamp);
89  PN_CPP_EXTERN encoder& operator<<(float);
90  PN_CPP_EXTERN encoder& operator<<(double);
91  PN_CPP_EXTERN encoder& operator<<(decimal32);
92  PN_CPP_EXTERN encoder& operator<<(decimal64);
93  PN_CPP_EXTERN encoder& operator<<(decimal128);
94  PN_CPP_EXTERN encoder& operator<<(const uuid&);
95  PN_CPP_EXTERN encoder& operator<<(const std::string&);
96  PN_CPP_EXTERN encoder& operator<<(const symbol&);
97  PN_CPP_EXTERN encoder& operator<<(const binary&);
98  PN_CPP_EXTERN encoder& operator<<(const scalar_base&);
99  PN_CPP_EXTERN encoder& operator<<(const null&);
101 
106  PN_CPP_EXTERN encoder& operator<<(const internal::value_base&);
107 
109  PN_CPP_EXTERN encoder& operator<<(const start&);
110 
112  PN_CPP_EXTERN encoder& operator<<(const finish&);
113 
115 
116  // Undefined template to prevent pointers being implicitly converted to bool.
117  template <class T> void* operator<<(const T*);
118 
119  template <class T> struct list_cref { T& ref; list_cref(T& r) : ref(r) {} };
120  template <class T> struct map_cref { T& ref; map_cref(T& r) : ref(r) {} };
121 
122  template <class T> struct array_cref {
123  start array_start;
124  T& ref;
125  array_cref(T& r, type_id el, bool described) : array_start(ARRAY, el, described), ref(r) {}
126  };
127 
128  template <class T> static list_cref<T> list(T& x) { return list_cref<T>(x); }
129  template <class T> static map_cref<T> map(T& x) { return map_cref<T>(x); }
130  template <class T> static array_cref<T> array(T& x, type_id element, bool described=false) {
131  return array_cref<T>(x, element, described);
132  }
133 
134  template <class T> encoder& operator<<(const map_cref<T>& x) {
135  internal::state_guard sg(*this);
136  *this << start::map();
137  for (typename T::const_iterator i = x.ref.begin(); i != x.ref.end(); ++i)
138  *this << i->first << i->second;
139  *this << finish();
140  return *this;
141  }
142 
143  template <class T> encoder& operator<<(const list_cref<T>& x) {
144  internal::state_guard sg(*this);
145  *this << start::list();
146  for (typename T::const_iterator i = x.ref.begin(); i != x.ref.end(); ++i)
147  *this << *i;
148  *this << finish();
149  return *this;
150  }
151 
152  template <class T> encoder& operator<<(const array_cref<T>& x) {
153  internal::state_guard sg(*this);
154  *this << x.array_start;
155  for (typename T::const_iterator i = x.ref.begin(); i != x.ref.end(); ++i)
156  *this << *i;
157  *this << finish();
158  return *this;
159  }
161 
162  private:
163  template<class T, class U> encoder& insert(const T& x, int (*put)(pn_data_t*, U));
164  void check(long result);
165 };
166 
168 inline encoder& operator<<(encoder& e, const char* s) { return e << std::string(s); }
169 
171 template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, encoder&>::type
172 operator<<(encoder& e, T i) {
173  using namespace internal;
174  return e << static_cast<typename integer_type<sizeof(T), is_signed<T>::value>::type>(i);
175 }
176 
178 
179 namespace is_encodable_impl { // Protect the world from fallback operator<<
180 
181 using namespace internal;
182 
183 sfinae::no operator<<(encoder const&, const sfinae::any_t &); // Fallback
184 
185 template<typename T> struct is_encodable : public sfinae {
186  static yes test(encoder&);
187  static no test(...); // Failed test, no match.
188  static encoder* e;
189  static const T* t;
190  static bool const value = sizeof(test(*e << *t)) == sizeof(yes);
191 };
192 
193 // Avoid recursion
194 template <> struct is_encodable<value> : public true_type {};
195 
196 } // is_encodable_impl
197 
198 using is_encodable_impl::is_encodable;
199 
200 // Metafunction to test if a class looks like an encodable map from K to T.
201 template <class M, class K, class T, class Enable = void>
202 struct is_encodable_map : public internal::false_type {};
203 
204 template <class M, class K, class T> struct is_encodable_map<
205  M, K, T, typename internal::enable_if<
206  internal::is_same<K, typename M::key_type>::value &&
207  internal::is_same<T, typename M::mapped_type>::value &&
208  is_encodable<M>::value
209  >::type
210  > : public internal::true_type {};
211 
212 
214 
215 } // codec
216 } // proton
217 
218 #endif
std::ostream & operator<<(std::ostream &, const binary &)
Print a binary value.
Unsettled API - Start encoding a complex type.
Definition: common.hpp:34
Unsettled API - A stream-like encoder from C++ values to AMQP bytes.
Definition: encoder.hpp:50
A sequence of values of the same type.
Definition: type_id.hpp:60
A 16-byte universally unique identifier.
Definition: uuid.hpp:37
A 64-bit decimal floating-point value.
Definition: decimal.hpp:49
encoder(const data &d)
Wrap Proton-C data object.
Definition: encoder.hpp:53
The base class for scalar types.
Definition: scalar_base.hpp:60
A collection of key-value pairs.
Definition: map.hpp:44
Unsettled API - Shared codec functions.
A string that represents the AMQP symbol type.
Definition: symbol.hpp:35
Arbitrary binary data.
Definition: binary.hpp:40
A 128-bit decimal floating-point value.
Definition: decimal.hpp:52
type_id
An identifier for AMQP types.
Definition: type_id.hpp:37
A 32-bit decimal floating-point value.
Definition: decimal.hpp:46
A 64-bit timestamp in milliseconds since the Unix epoch.
Definition: timestamp.hpp:35
A holder for any AMQP value, simple or complex.
Definition: value.hpp:57
Unsettled API - Finish inserting or extracting a complex type.
Definition: common.hpp:57
The main Proton namespace.
Definition: annotation_key.hpp:33