zmqpp  4.1.2
C++ bindings for 0mq (libzmq)
message.hpp
Go to the documentation of this file.
1 /*
2  * This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5  *
6  * This file is part of zmqpp.
7  * Copyright (c) 2011-2015 Contributors as noted in the AUTHORS file.
8  */
9 
17 #ifndef ZMQPP_MESSAGE_HPP_
18 #define ZMQPP_MESSAGE_HPP_
19 
20 #include <cassert>
21 #include <functional>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 #include <utility>
26 
27 #include <zmq.h>
28 
29 #include "compatibility.hpp"
30 #include "frame.hpp"
31 #include "signal.hpp"
32 
33 namespace zmqpp
34 {
35 
44 {
45 public:
56  typedef std::function<void (void*)> release_function;
57 
58  message();
59  ~message();
60 
61  template <typename T, typename ...Args>
62  message(T const &part, Args &&...args)
63  : message()
64  {
65  add(part, std::forward<Args>(args)...);
66  }
67 
68  size_t parts() const;
69  size_t size(size_t const part) const;
70  std::string get(size_t const part) const;
71 
72  void get(int8_t& integer, size_t const part) const;
73  void get(int16_t& integer, size_t const part) const;
74  void get(int32_t& integer, size_t const part) const;
75  void get(int64_t& integer, size_t const part) const;
76  void get(signal& sig, size_t const part) const;
77 
78  void get(uint8_t& unsigned_integer, size_t const part) const;
79  void get(uint16_t& unsigned_integer, size_t const part) const;
80  void get(uint32_t& unsigned_integer, size_t const part) const;
81  void get(uint64_t& unsigned_integer, size_t const part) const;
82 
83  void get(float& floating_point, size_t const part) const;
84  void get(double& double_precision, size_t const part) const;
85  void get(bool& boolean, size_t const part) const;
86 
87  void get(std::string& string, size_t const part) const;
88 
89  // Warn: If a pointer type is requested the message (well zmq) still 'owns'
90  // the data and will release it when the message object is freed.
91  template<typename Type>
92  Type get(size_t const part) const
93  {
94  Type value;
95  get(value, part);
96  return value;
97  }
98 
99  template<int part=0, typename T, typename ...Args>
100  void extract(T &nextpart, Args &...args) const
101  {
102  assert(part < parts());
103  get(nextpart,part);
104  extract<part+1>(args...);
105  }
106 
107  template<int part=0, typename T>
108  void extract(T &nextpart) const
109  {
110  assert(part < parts());
111  get(nextpart,part);
112  }
113 
114  // Raw get data operations, useful with data structures more than anything else
115  // Warn: The message (well zmq) still 'owns' the data and will release it
116  // when the message object is freed.
117  template<typename Type>
118  void get(Type*& value, size_t const part) const
119  {
120  value = static_cast<Type*>(raw_data(part));
121  }
122 
123  // Warn: The message (well zmq) still 'owns' the data and will release it
124  // when the message object is freed.
125  template<typename Type>
126  void get(Type** value, size_t const part) const
127  {
128  *value = static_cast<Type*>(raw_data(part));
129  }
130 
131  // Move operators will take ownership of message parts without copying
132  void move(void* part, size_t const size, release_function const& release);
133 
134  // Raw move data operation, useful with data structures more than anything else
135  template<typename Object>
136  void move(Object *part)
137  {
138  move(part, sizeof(Object), &deleter_callback<Object>);
139  }
140 
141  // Copy operators will take copies of any data
142  template<typename Type, typename ...Args>
143  void add(Type const& part, Args &&...args)
144  {
145  *this << part;
146  add(std::forward<Args>(args)...);
147  }
148 
149  template<typename Type>
150  void add(Type const part)
151  {
152  *this << part;
153  }
154 
155  // Copy operators will take copies of any data with a given size
156  template<typename Type>
157  void add_raw(Type *part, size_t const data_size)
158  {
159  _parts.push_back( frame( part, data_size ) );
160  }
161 
162  // Use exact data past, neither zmqpp nor 0mq will copy, alter or delete
163  // this data. It must remain as valid for at least the lifetime of the
164  // 0mq message, recommended only with const data.
165  template<typename Type>
166  ZMQPP_DEPRECATED("Use add_nocopy() or add_nocopy_const() instead.")
167  void add_const(Type *part, size_t const data_size)
168  {
169  _parts.push_back( frame( part, data_size, nullptr, nullptr ) );
170  }
171 
197  template<typename Type>
198  void add_nocopy(Type *part, size_t const data_size,
199  zmq_free_fn *ffn = nullptr, void *hint = nullptr)
200  {
201  static_assert(!std::is_const<Type>::value,
202  "Data part must not be const. Use add_nocopy_const() instead (and read its documentation)");
203  _parts.push_back(frame(part, data_size, ffn, hint));
204  }
205 
232  template<typename Type>
233  void add_nocopy_const(const Type *part, size_t const data_size,
234  zmq_free_fn *ffn = nullptr, void *hint = nullptr)
235  {
236  add_nocopy(const_cast<typename std::remove_const<Type *>::type>(part),
237  data_size, ffn, hint);
238  }
239 
240  // Stream reader style
241  void reset_read_cursor();
242 
243  template<typename Type>
244  message& operator>>(Type& value)
245  {
246  get(value, _read_cursor++);
247  return *this;
248  }
249 
250  // Stream writer style - these all use copy styles
251  message& operator<<(int8_t const integer);
252  message& operator<<(int16_t const integer);
253  message& operator<<(int32_t const integer);
254  message& operator<<(int64_t const integer);
255  message& operator<<(signal const sig);
256 
257  message& operator<<(uint8_t const unsigned_integer);
258  message& operator<<(uint16_t const unsigned_integer);
259  message& operator<<(uint32_t const unsigned_integer);
260  message& operator<<(uint64_t const unsigned_integer);
261 
262  message& operator<<(float const floating_point);
263  message& operator<<(double const double_precision);
264  message& operator<<(bool const boolean);
265 
266  message& operator<<(char const* c_string);
267  message& operator<<(std::string const& string);
268 
269  // Queue manipulation
270  void push_front(void const* part, size_t const size);
271 
272  // TODO: unify conversion of types with the stream operators
273  void push_front(int8_t const integer);
274  void push_front(int16_t const integer);
275  void push_front(int32_t const integer);
276  void push_front(int64_t const integer);
277  void push_front(signal const sig);
278 
279  void push_front(uint8_t const unsigned_integer);
280  void push_front(uint16_t const unsigned_integer);
281  void push_front(uint32_t const unsigned_integer);
282  void push_front(uint64_t const unsigned_integer);
283 
284  void push_front(float const floating_point);
285  void push_front(double const double_precision);
286  void push_front(bool const boolean);
287 
288  void push_front(char const* c_string);
289  void push_front(std::string const& string);
290 
291  void pop_front();
292 
293  void push_back(void const* part, size_t const data_size)
294  {
295  add_raw( part, data_size );
296  }
297 
298  template<typename Type>
299  void push_back(Type const part)
300  {
301  *this << part;
302  }
303 
304  void pop_back();
305 
306  void remove(size_t const part);
307 
308  // Move supporting
309  message(message&& source) NOEXCEPT;
310  message& operator=(message&& source) NOEXCEPT;
311 
312  // Copy support
313  message copy() const;
314  void copy(message const& source);
315 
316  // Used for internal tracking
317  void sent(size_t const part);
318 
319  // Access to raw zmq details
320  void const* raw_data(size_t const part = 0) const;
321  zmq_msg_t& raw_msg(size_t const part = 0);
322  zmq_msg_t& raw_new_msg();
323  zmq_msg_t& raw_new_msg(size_t const reserve_data_size);
324 
331  bool is_signal() const;
332 
336  size_t read_cursor() const NOEXCEPT { return _read_cursor; }
337 
341  size_t remaining() const NOEXCEPT { return _parts.size() - _read_cursor; }
342 
347  size_t next() NOEXCEPT { return ++_read_cursor; }
348 
349 
350 #if (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR >= 1)
351 
357  bool get_property(const std::string &property, std::string &out);
358 #endif
359 
360 private:
361  typedef std::vector<frame> parts_type;
362  parts_type _parts;
363  size_t _read_cursor;
364 
365  // Disable implicit copy support, code must request a copy to clone
366  message(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
367  message& operator=(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED;
368 
369  static void release_callback(void* data, void* hint);
370 
371  template<typename Object>
372  static void deleter_callback(void* data)
373  {
374  delete static_cast<Object*>(data);
375  }
376 };
377 
378 }
379 
380 #endif /* ZMQPP_MESSAGE_HPP_ */
void add(Type const &part, Args &&...args)
Definition: message.hpp:143
size_t size(size_t const part) const
Definition: message.cpp:56
void extract(T &nextpart, Args &...args) const
Definition: message.hpp:100
#define ZMQPP_DEPRECATED(reason)
Definition: compatibility.hpp:118
#define ZMQPP_EXPLICITLY_DELETED
Definition: compatibility.hpp:107
C++ wrapper around zmq.
Definition: actor.cpp:29
message & operator>>(Type &value)
Definition: message.hpp:244
size_t next() NOEXCEPT
Moves the read cursor to the next element.
Definition: message.hpp:347
message(T const &part, Args &&...args)
Definition: message.hpp:62
void add_nocopy(Type *part, size_t const data_size, zmq_free_fn *ffn=nullptr, void *hint=nullptr)
Add a no-copy frame.
Definition: message.hpp:198
std::vector< frame > parts_type
Definition: message.hpp:361
size_t remaining() const NOEXCEPT
Gets the remaining number of parts in the message.
Definition: message.hpp:341
void push_back(Type const part)
Definition: message.hpp:299
void move(Object *part)
Definition: message.hpp:136
void add_raw(Type *part, size_t const data_size)
Definition: message.hpp:157
#define NOEXCEPT
Definition: compatibility.hpp:122
void push_back(void const *part, size_t const data_size)
Definition: message.hpp:293
void add_nocopy_const(const Type *part, size_t const data_size, zmq_free_fn *ffn=nullptr, void *hint=nullptr)
Add a no-copy frame where pointed-to data are const.
Definition: message.hpp:233
size_t read_cursor() const NOEXCEPT
Gets the read cursor.
Definition: message.hpp:336
std::function< void(void *)> release_function
callback to release user allocated data.
Definition: message.hpp:56
size_t _read_cursor
Definition: message.hpp:363
void extract(T &nextpart) const
Definition: message.hpp:108
parts_type _parts
Definition: message.hpp:362
void add(Type const part)
Definition: message.hpp:150
a zmq message with optional multipart support
Definition: message.hpp:43
#define ZMQPP_EXPORT
Definition: compatibility.hpp:39
static void deleter_callback(void *data)
Definition: message.hpp:372
signal
Signal is a 8 bytes integer.
Definition: signal.hpp:24
an internal frame wrapper for a single zmq message
Definition: frame.hpp:33