Qpid Proton C++ API  0.18.1
decoder.hpp
Go to the documentation of this file.
1 #ifndef PROTON_CODEC_DECODER_HPP
2 #define PROTON_CODEC_DECODER_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 
32 #include <utility>
33 
36 
37 namespace proton {
38 
39 class annotation_key;
40 class message_id;
41 class scalar;
42 class value;
43 
44 namespace internal {
45 class value_base;
46 }
47 
48 namespace codec {
49 
56 class decoder : public internal::data {
57  public:
61  explicit decoder(const data& d, bool exact=false) : data(d), exact_(exact) {}
62 
65  PN_CPP_EXTERN explicit decoder(const internal::value_base&, bool exact=false);
66 
69  PN_CPP_EXTERN void decode(const char* buffer, size_t size);
70 
73  PN_CPP_EXTERN void decode(const std::string&);
74 
76  PN_CPP_EXTERN bool more();
77 
83  PN_CPP_EXTERN type_id next_type();
84 
91  PN_CPP_EXTERN decoder& operator>>(bool&);
92  PN_CPP_EXTERN decoder& operator>>(uint8_t&);
93  PN_CPP_EXTERN decoder& operator>>(int8_t&);
94  PN_CPP_EXTERN decoder& operator>>(uint16_t&);
95  PN_CPP_EXTERN decoder& operator>>(int16_t&);
96  PN_CPP_EXTERN decoder& operator>>(uint32_t&);
97  PN_CPP_EXTERN decoder& operator>>(int32_t&);
98  PN_CPP_EXTERN decoder& operator>>(wchar_t&);
99  PN_CPP_EXTERN decoder& operator>>(uint64_t&);
100  PN_CPP_EXTERN decoder& operator>>(int64_t&);
101  PN_CPP_EXTERN decoder& operator>>(timestamp&);
102  PN_CPP_EXTERN decoder& operator>>(float&);
103  PN_CPP_EXTERN decoder& operator>>(double&);
104  PN_CPP_EXTERN decoder& operator>>(decimal32&);
105  PN_CPP_EXTERN decoder& operator>>(decimal64&);
106  PN_CPP_EXTERN decoder& operator>>(decimal128&);
107  PN_CPP_EXTERN decoder& operator>>(uuid&);
108  PN_CPP_EXTERN decoder& operator>>(std::string&);
109  PN_CPP_EXTERN decoder& operator>>(symbol&);
110  PN_CPP_EXTERN decoder& operator>>(binary&);
111  PN_CPP_EXTERN decoder& operator>>(message_id&);
112  PN_CPP_EXTERN decoder& operator>>(annotation_key&);
113  PN_CPP_EXTERN decoder& operator>>(scalar&);
114  PN_CPP_EXTERN decoder& operator>>(internal::value_base&);
115  PN_CPP_EXTERN decoder& operator>>(null&);
117 
122  PN_CPP_EXTERN decoder& operator>>(start&);
123 
126  PN_CPP_EXTERN decoder& operator>>(const finish&);
127 
129  template <class T> struct sequence_ref { T& ref; sequence_ref(T& r) : ref(r) {} };
130  template <class T> struct associative_ref { T& ref; associative_ref(T& r) : ref(r) {} };
131  template <class T> struct pair_sequence_ref { T& ref; pair_sequence_ref(T& r) : ref(r) {} };
132 
133  template <class T> static sequence_ref<T> sequence(T& x) { return sequence_ref<T>(x); }
134  template <class T> static associative_ref<T> associative(T& x) { return associative_ref<T>(x); }
135  template <class T> static pair_sequence_ref<T> pair_sequence(T& x) { return pair_sequence_ref<T>(x); }
137 
141  template <class T> decoder& operator>>(sequence_ref<T> r) {
142  start s;
143  *this >> s;
144  if (s.is_described) next();
145  r.ref.resize(s.size);
146  for (typename T::iterator i = r.ref.begin(); i != r.ref.end(); ++i)
147  *this >> *i;
148  return *this;
149  }
150 
152  template <class T> decoder& operator>>(associative_ref<T> r) {
153  using namespace internal;
154  start s;
155  *this >> s;
156  assert_type_equal(MAP, s.type);
157  r.ref.clear();
158  for (size_t i = 0; i < s.size/2; ++i) {
159  typename remove_const<typename T::key_type>::type k;
160  typename remove_const<typename T::mapped_type>::type v;
161  *this >> k >> v;
162  r.ref[k] = v;
163  }
164  return *this;
165  }
166 
169  template <class T> decoder& operator>>(pair_sequence_ref<T> r) {
170  using namespace internal;
171  start s;
172  *this >> s;
173  assert_type_equal(MAP, s.type);
174  r.ref.clear();
175  for (size_t i = 0; i < s.size/2; ++i) {
176  typedef typename T::value_type value_type;
177  typename remove_const<typename value_type::first_type>::type k;
178  typename remove_const<typename value_type::second_type>::type v;
179  *this >> k >> v;
180  r.ref.push_back(value_type(k, v));
181  }
182  return *this;
183  }
184 
185  private:
186  type_id pre_get();
187  template <class T, class U> decoder& extract(T& x, U (*get)(pn_data_t*));
188  bool exact_;
189 
190  friend class message;
191 };
192 
195 template<class T> T get(decoder& d) {
196  assert_type_equal(internal::type_id_of<T>::value, d.next_type());
197  T x;
198  d >> x;
199  return x;
200 }
202 
205 template <class T> typename internal::enable_if<internal::is_unknown_integer<T>::value, decoder&>::type
206 operator>>(decoder& d, T& i) {
207  using namespace internal;
208  typename integer_type<sizeof(T), is_signed<T>::value>::type v;
209  d >> v; // Extract as a known integer type
210  i = v; // C++ conversion to the target type.
211  return d;
212 }
213 
214 } // codec
215 } // proton
216 
217 #endif // PROTON_CODEC_DECODER_HPP
A holder for an instance of any scalar AMQP type.
Definition: scalar.hpp:35
An AMQP message.
Definition: message.hpp:50
Unsettled API - Start encoding a complex type.
Definition: common.hpp:34
A key for use with AMQP annotation maps.
Definition: annotation_key.hpp:38
A sequence of key-value pairs.
Definition: type_id.hpp:62
A 16-byte universally unique identifier.
Definition: uuid.hpp:37
decoder & operator>>(sequence_ref< T > r)
Extract any AMQP sequence (ARRAY, LIST or MAP) to a C++ sequence container of T if the elements types...
Definition: decoder.hpp:141
proton::codec::decoder & operator>>(proton::codec::decoder &d, map< K, T > &m)
Decode from a proton::map.
decoder & operator>>(associative_ref< T > r)
Extract an AMQP MAP to a C++ associative container.
Definition: decoder.hpp:152
A 64-bit decimal floating-point value.
Definition: decimal.hpp:49
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
decoder & operator>>(pair_sequence_ref< T > r)
Extract an AMQP MAP to a C++ push_back sequence of pairs preserving encoded order.
Definition: decoder.hpp:169
void assert_type_equal(type_id want, type_id got)
Throw a conversion_error if want != got with a message including the names of the types...
Unsettled API - Finish inserting or extracting a complex type.
Definition: common.hpp:57
decoder(const data &d, bool exact=false)
Wrap a Proton C data object.
Definition: decoder.hpp:61
The main Proton namespace.
Definition: annotation_key.hpp:33
Unsettled API - A stream-like decoder from AMQP bytes to C++ values.
Definition: decoder.hpp:56
An AMQP message ID.
Definition: message_id.hpp:47