Qpid Proton C++  0.12.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
decoder.hpp
1 #ifndef DECODER_H
2 #define DECODER_H
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements. See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership. The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License. You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied. See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21 
24 
25 #include "proton/error.hpp"
26 #include "proton/type_traits.hpp"
27 #include "proton/types.hpp"
28 #include "proton/object.hpp"
29 #include <iosfwd>
30 
31 #ifndef PN_NO_CONTAINER_CONVERT
32 
33 #include <vector>
34 #include <deque>
35 #include <list>
36 #include <map>
37 
38 #if PN_HAS_CPP11
39 #include <array>
40 #include <forward_list>
41 #include <unordered_map>
42 #endif // PN_HAS_CPP11
43 
44 #endif // PN_NO_CONTAINER_CONVERT
45 
46 struct pn_data_t;
47 
48 namespace proton {
49 
50 class scalar;
51 class data;
52 class message_id;
53 class annotation_key;
54 class value;
55 
57 struct skip{};
58 
62 struct assert_type {
63  type_id type;
64  assert_type(type_id t) : type(t) {}
65 };
66 
68 struct rewind{};
69 
154 class decoder : public object<pn_data_t> {
155  public:
156  decoder(pn_data_t* d) : object<pn_data_t>(d) {}
157 
159  PN_CPP_EXTERN decoder(const char* buffer, size_t size);
160 
162  PN_CPP_EXTERN decoder(const std::string&);
163 
165  PN_CPP_EXTERN void decode(const char* buffer, size_t size);
166 
168  PN_CPP_EXTERN void decode(const std::string&);
169 
171  PN_CPP_EXTERN bool more() const;
172 
176  PN_CPP_EXTERN type_id type() const;
177 
179  PN_CPP_EXTERN void rewind();
180 
182  PN_CPP_EXTERN void skip();
183 
185  PN_CPP_EXTERN void backup();
186 
187  PN_CPP_EXTERN class data data();
188 
194  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_null);
195  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_boolean&);
196  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ubyte&);
197  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_byte&);
198  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ushort&);
199  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_short&);
200  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uint&);
201  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_int&);
202  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_char&);
203  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ulong&);
204  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_long&);
205  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_timestamp&);
206  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_float&);
207  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_double&);
208  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal32&);
209  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal64&);
210  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal128&);
211  PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uuid&);
212  PN_CPP_EXTERN friend decoder operator>>(decoder, std::string&);
213  PN_CPP_EXTERN friend decoder operator>>(decoder, message_id&);
214  PN_CPP_EXTERN friend decoder operator>>(decoder, annotation_key&);
215  PN_CPP_EXTERN friend decoder operator>>(decoder, value&);
216  PN_CPP_EXTERN friend decoder operator>>(decoder, scalar&);
218 
220  template <class T> T extract() { T value; *this >> value; return value; }
221 
248  PN_CPP_EXTERN friend decoder operator>>(decoder, start&);
249 
251  PN_CPP_EXTERN friend decoder operator>>(decoder, finish);
252 
254  PN_CPP_EXTERN friend decoder operator>>(decoder, struct skip);
255 
257  PN_CPP_EXTERN friend decoder operator>>(decoder, assert_type);
258 
260  PN_CPP_EXTERN friend decoder operator>>(decoder, struct rewind);
261 
262  private:
263  PN_CPP_EXTERN void check_type(type_id);
264 };
265 
269 struct scope : public start {
270  decoder decoder_;
271  scope(decoder d) : decoder_(d) { decoder_ >> *this; }
272  ~scope() { decoder_ >> finish(); }
273 };
274 
275 // operator >> for integer types that are not covered by the standard overrides.
276 template <class T>
277 typename enable_if<is_unknown_integer<T>::value, decoder>::type
278 operator>>(decoder d, T& i) {
279  typename integer_type<sizeof(T), is_signed<T>::value>::type v;
280  d >> v; // Extract as a known integer type
281  i = v;
282  return d;
283 }
284 
286 template <class T> struct ref {
287  ref(T& v) : value(v) {}
288  T& value;
289 };
290 template <class T> struct sequence_ref : public ref<T> { sequence_ref(T& v) : ref<T>(v) {} };
291 template <class T> struct map_ref : public ref<T> { map_ref(T& v) : ref<T>(v) {} };
292 template <class T> struct pairs_ref : public ref<T> { pairs_ref(T& v) : ref<T>(v) {} };
294 
308 template <class T> sequence_ref<T> to_sequence(T& v) { return sequence_ref<T>(v); }
309 
317 template <class T> map_ref<T> to_map(T& v) { return map_ref<T>(v); }
318 
330 template <class T> pairs_ref<T> to_pairs(T& v) { return pairs_ref<T>(v); }
331 
336 template <class T> decoder operator>>(decoder d, sequence_ref<T> ref) {
337  scope s(d);
338  if (s.is_described) d >> skip();
339  T& v = ref.value;
340  v.clear();
341  v.resize(s.size);
342  for (typename T::iterator i = v.begin(); i != v.end(); ++i)
343  d >> *i;
344  return d;
345 }
346 
347 PN_CPP_EXTERN void assert_map_scope(const scope& s);
348 
350 template <class T> decoder operator>>(decoder d, map_ref<T> ref) {
351  scope s(d);
352  assert_map_scope(s);
353  T& m = ref.value;
354  m.clear();
355  for (size_t i = 0; i < s.size/2; ++i) {
356  typename remove_const<typename T::key_type>::type k;
357  typename remove_const<typename T::mapped_type>::type v;
358  d >> k >> v;
359  m[k] = v;
360  }
361  return d;
362 }
363 
365 template <class T> decoder operator>>(decoder d, pairs_ref<T> ref) {
366  scope s(d);
367  assert_map_scope(s);
368  T& m = ref.value;
369  m.clear();
370  m.resize(s.size/2);
371  for (typename T::iterator i = m.begin(); i != m.end(); ++i) {
372  d >> i->first >> i->second;
373  }
374  return d;
375 }
376 
377 #ifndef PN_NO_CONTAINER_CONVERT
378 
379 // Decode to sequence.
380 template <class T, class A> decoder operator>>(decoder d, std::vector<T, A>& v) { return d >> to_sequence(v); }
381 template <class T, class A> decoder operator>>(decoder d, std::deque<T, A>& v) { return d >> to_sequence(v); }
382 template <class T, class A> decoder operator>>(decoder d, std::list<T, A>& v) { return d >> to_sequence(v); }
383 
384 // Decode to map.
385 template <class K, class T, class C, class A> decoder operator>>(decoder d, std::map<K, T, C, A>& v) { return d >> to_map(v); }
386 
387 #if PN_HAS_CPP11
388 
389 // Decode to sequence.
390 template <class T, class A> decoder operator>>(decoder d, std::forward_list<T, A>& v) { return d >> to_sequence(v); }
391 template <class T, std::size_t N> decoder operator>>(decoder d, std::array<T, N>& v) { return d >> to_sequence(v); }
392 
393 // Decode to map.
394 template <class K, class T, class C, class A> decoder operator>>(decoder d, std::unordered_map<K, T, C, A>& v) { return d >> to_map(v); }
395 
396 #endif // PN_HAS_CPP11
397 #endif // PN_NO_CONTAINER_CONVERT
398 
399 }
400 
402 
403 #endif // DECODER_H
Defines C++ types representing AMQP types.