mirror of
https://github.com/zeromq/cppzmq.git
synced 2025-05-19 20:56:56 +02:00
Problem: zmq_addon.hpp not follow clang-format
This commit is contained in:
parent
5031278f18
commit
cd72eef3fd
496
zmq_addon.hpp
496
zmq_addon.hpp
@ -31,8 +31,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace zmq {
|
namespace zmq
|
||||||
|
{
|
||||||
#ifdef ZMQ_HAS_RVALUE_REFS
|
#ifdef ZMQ_HAS_RVALUE_REFS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -44,479 +44,399 @@ namespace zmq {
|
|||||||
*/
|
*/
|
||||||
class multipart_t
|
class multipart_t
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::deque<message_t> m_parts;
|
std::deque<message_t> m_parts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::deque<message_t>::iterator iterator;
|
typedef std::deque<message_t>::iterator iterator;
|
||||||
typedef std::deque<message_t>::const_iterator const_iterator;
|
typedef std::deque<message_t>::const_iterator const_iterator;
|
||||||
|
|
||||||
typedef std::deque<message_t>::reverse_iterator reverse_iterator;
|
typedef std::deque<message_t>::reverse_iterator reverse_iterator;
|
||||||
typedef std::deque<message_t>::const_reverse_iterator const_reverse_iterator;
|
typedef std::deque<message_t>::const_reverse_iterator
|
||||||
|
const_reverse_iterator;
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
multipart_t()
|
multipart_t () {}
|
||||||
{}
|
|
||||||
|
|
||||||
// Construct from socket receive
|
// Construct from socket receive
|
||||||
multipart_t(socket_t& socket)
|
multipart_t (socket_t &socket) { recv (socket); }
|
||||||
{
|
|
||||||
recv(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct from memory block
|
// Construct from memory block
|
||||||
multipart_t(const void *src, size_t size)
|
multipart_t (const void *src, size_t size) { addmem (src, size); }
|
||||||
{
|
|
||||||
addmem(src, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct from string
|
// Construct from string
|
||||||
multipart_t(const std::string& string)
|
multipart_t (const std::string &string) { addstr (string); }
|
||||||
{
|
|
||||||
addstr(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct from message part
|
// Construct from message part
|
||||||
multipart_t(message_t&& message)
|
multipart_t (message_t &&message) { add (std::move (message)); }
|
||||||
{
|
|
||||||
add(std::move(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move constructor
|
// Move constructor
|
||||||
multipart_t(multipart_t&& other)
|
multipart_t (multipart_t &&other) { m_parts = std::move (other.m_parts); }
|
||||||
{
|
|
||||||
m_parts = std::move(other.m_parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move assignment operator
|
// Move assignment operator
|
||||||
multipart_t& operator=(multipart_t&& other)
|
multipart_t &operator= (multipart_t &&other)
|
||||||
{
|
{
|
||||||
m_parts = std::move(other.m_parts);
|
m_parts = std::move (other.m_parts);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
virtual ~multipart_t()
|
virtual ~multipart_t () { clear (); }
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
message_t& operator[] (size_t n)
|
message_t &operator[] (size_t n) { return m_parts[n]; }
|
||||||
{
|
|
||||||
return m_parts[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
const message_t& operator[] (size_t n) const
|
const message_t &operator[] (size_t n) const { return m_parts[n]; }
|
||||||
{
|
|
||||||
return m_parts[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
message_t& at (size_t n)
|
message_t &at (size_t n) { return m_parts.at (n); }
|
||||||
{
|
|
||||||
return m_parts.at(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
const message_t& at (size_t n) const
|
const message_t &at (size_t n) const { return m_parts.at (n); }
|
||||||
{
|
|
||||||
return m_parts.at(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin()
|
iterator begin () { return m_parts.begin (); }
|
||||||
{
|
|
||||||
return m_parts.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const
|
const_iterator begin () const { return m_parts.begin (); }
|
||||||
{
|
|
||||||
return m_parts.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin() const
|
const_iterator cbegin () const { return m_parts.cbegin (); }
|
||||||
{
|
|
||||||
return m_parts.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_iterator rbegin()
|
reverse_iterator rbegin () { return m_parts.rbegin (); }
|
||||||
{
|
|
||||||
return m_parts.rbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reverse_iterator rbegin() const
|
const_reverse_iterator rbegin () const { return m_parts.rbegin (); }
|
||||||
{
|
|
||||||
return m_parts.rbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end()
|
iterator end () { return m_parts.end (); }
|
||||||
{
|
|
||||||
return m_parts.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const
|
const_iterator end () const { return m_parts.end (); }
|
||||||
{
|
|
||||||
return m_parts.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend() const
|
const_iterator cend () const { return m_parts.cend (); }
|
||||||
{
|
|
||||||
return m_parts.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_iterator rend()
|
reverse_iterator rend () { return m_parts.rend (); }
|
||||||
{
|
|
||||||
return m_parts.rend();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_reverse_iterator rend() const
|
const_reverse_iterator rend () const { return m_parts.rend (); }
|
||||||
{
|
|
||||||
return m_parts.rend();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete all parts
|
// Delete all parts
|
||||||
void clear()
|
void clear () { m_parts.clear (); }
|
||||||
{
|
|
||||||
m_parts.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get number of parts
|
// Get number of parts
|
||||||
size_t size() const
|
size_t size () const { return m_parts.size (); }
|
||||||
{
|
|
||||||
return m_parts.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if number of parts is zero
|
// Check if number of parts is zero
|
||||||
bool empty() const
|
bool empty () const { return m_parts.empty (); }
|
||||||
{
|
|
||||||
return m_parts.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive multipart message from socket
|
// Receive multipart message from socket
|
||||||
bool recv(socket_t& socket, int flags = 0)
|
bool recv (socket_t &socket, int flags = 0)
|
||||||
{
|
{
|
||||||
clear();
|
clear ();
|
||||||
bool more = true;
|
bool more = true;
|
||||||
while (more)
|
while (more) {
|
||||||
{
|
|
||||||
message_t message;
|
message_t message;
|
||||||
if (!socket.recv(&message, flags))
|
if (!socket.recv (&message, flags))
|
||||||
return false;
|
return false;
|
||||||
more = message.more();
|
more = message.more ();
|
||||||
add(std::move(message));
|
add (std::move (message));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send multipart message to socket
|
// Send multipart message to socket
|
||||||
bool send(socket_t& socket, int flags = 0)
|
bool send (socket_t &socket, int flags = 0)
|
||||||
{
|
{
|
||||||
flags &= ~(ZMQ_SNDMORE);
|
flags &= ~(ZMQ_SNDMORE);
|
||||||
bool more = size() > 0;
|
bool more = size () > 0;
|
||||||
while (more)
|
while (more) {
|
||||||
{
|
message_t message = pop ();
|
||||||
message_t message = pop();
|
more = size () > 0;
|
||||||
more = size() > 0;
|
if (!socket.send (message, (more ? ZMQ_SNDMORE : 0) | flags))
|
||||||
if (!socket.send(message, (more ? ZMQ_SNDMORE : 0) | flags))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
clear();
|
clear ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate other multipart to front
|
// Concatenate other multipart to front
|
||||||
void prepend(multipart_t&& other)
|
void prepend (multipart_t &&other)
|
||||||
{
|
{
|
||||||
while (!other.empty())
|
while (!other.empty ())
|
||||||
push(other.remove());
|
push (other.remove ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate other multipart to back
|
// Concatenate other multipart to back
|
||||||
void append(multipart_t&& other)
|
void append (multipart_t &&other)
|
||||||
{
|
{
|
||||||
while (!other.empty())
|
while (!other.empty ())
|
||||||
add(other.pop());
|
add (other.pop ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push memory block to front
|
// Push memory block to front
|
||||||
void pushmem(const void *src, size_t size)
|
void pushmem (const void *src, size_t size)
|
||||||
{
|
{
|
||||||
m_parts.push_front(message_t(src, size));
|
m_parts.push_front (message_t (src, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push memory block to back
|
// Push memory block to back
|
||||||
void addmem(const void *src, size_t size)
|
void addmem (const void *src, size_t size)
|
||||||
{
|
{
|
||||||
m_parts.push_back(message_t(src, size));
|
m_parts.push_back (message_t (src, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push string to front
|
// Push string to front
|
||||||
void pushstr(const std::string& string)
|
void pushstr (const std::string &string)
|
||||||
{
|
{
|
||||||
m_parts.push_front(message_t(string.data(), string.size()));
|
m_parts.push_front (message_t (string.data (), string.size ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push string to back
|
// Push string to back
|
||||||
void addstr(const std::string& string)
|
void addstr (const std::string &string)
|
||||||
{
|
{
|
||||||
m_parts.push_back(message_t(string.data(), string.size()));
|
m_parts.push_back (message_t (string.data (), string.size ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push type (fixed-size) to front
|
// Push type (fixed-size) to front
|
||||||
template<typename T>
|
template <typename T> void pushtyp (const T &type)
|
||||||
void pushtyp(const T& type)
|
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<T, std::string>::value, "Use pushstr() instead of pushtyp<std::string>()");
|
static_assert (!std::is_same<T, std::string>::value,
|
||||||
m_parts.push_front(message_t(&type, sizeof(type)));
|
"Use pushstr() instead of pushtyp<std::string>()");
|
||||||
|
m_parts.push_front (message_t (&type, sizeof (type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push type (fixed-size) to back
|
// Push type (fixed-size) to back
|
||||||
template<typename T>
|
template <typename T> void addtyp (const T &type)
|
||||||
void addtyp(const T& type)
|
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<T, std::string>::value, "Use addstr() instead of addtyp<std::string>()");
|
static_assert (!std::is_same<T, std::string>::value,
|
||||||
m_parts.push_back(message_t(&type, sizeof(type)));
|
"Use addstr() instead of addtyp<std::string>()");
|
||||||
|
m_parts.push_back (message_t (&type, sizeof (type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push message part to front
|
// Push message part to front
|
||||||
void push(message_t&& message)
|
void push (message_t &&message)
|
||||||
{
|
{
|
||||||
m_parts.push_front(std::move(message));
|
m_parts.push_front (std::move (message));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push message part to back
|
// Push message part to back
|
||||||
void add(message_t&& message)
|
void add (message_t &&message) { m_parts.push_back (std::move (message)); }
|
||||||
{
|
|
||||||
m_parts.push_back(std::move(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop string from front
|
// Pop string from front
|
||||||
std::string popstr()
|
std::string popstr ()
|
||||||
{
|
{
|
||||||
std::string string(m_parts.front().data<char>(), m_parts.front().size());
|
std::string string (m_parts.front ().data<char> (),
|
||||||
m_parts.pop_front();
|
m_parts.front ().size ());
|
||||||
|
m_parts.pop_front ();
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop type (fixed-size) from front
|
// Pop type (fixed-size) from front
|
||||||
template<typename T>
|
template <typename T> T poptyp ()
|
||||||
T poptyp()
|
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<T, std::string>::value, "Use popstr() instead of poptyp<std::string>()");
|
static_assert (!std::is_same<T, std::string>::value,
|
||||||
if (sizeof(T) != m_parts.front().size())
|
"Use popstr() instead of poptyp<std::string>()");
|
||||||
throw std::runtime_error("Invalid type, size does not match the message size");
|
if (sizeof (T) != m_parts.front ().size ())
|
||||||
T type = *m_parts.front().data<T>();
|
throw std::runtime_error (
|
||||||
m_parts.pop_front();
|
"Invalid type, size does not match the message size");
|
||||||
|
T type = *m_parts.front ().data<T> ();
|
||||||
|
m_parts.pop_front ();
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop message part from front
|
// Pop message part from front
|
||||||
message_t pop()
|
message_t pop ()
|
||||||
{
|
{
|
||||||
message_t message = std::move(m_parts.front());
|
message_t message = std::move (m_parts.front ());
|
||||||
m_parts.pop_front();
|
m_parts.pop_front ();
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop message part from back
|
// Pop message part from back
|
||||||
message_t remove()
|
message_t remove ()
|
||||||
{
|
{
|
||||||
message_t message = std::move(m_parts.back());
|
message_t message = std::move (m_parts.back ());
|
||||||
m_parts.pop_back();
|
m_parts.pop_back ();
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get pointer to a specific message part
|
// Get pointer to a specific message part
|
||||||
const message_t* peek(size_t index) const
|
const message_t *peek (size_t index) const { return &m_parts[index]; }
|
||||||
{
|
|
||||||
return &m_parts[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a string copy of a specific message part
|
// Get a string copy of a specific message part
|
||||||
std::string peekstr(size_t index) const
|
std::string peekstr (size_t index) const
|
||||||
{
|
{
|
||||||
std::string string(m_parts[index].data<char>(), m_parts[index].size());
|
std::string string (m_parts[index].data<char> (),
|
||||||
|
m_parts[index].size ());
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peek type (fixed-size) from front
|
// Peek type (fixed-size) from front
|
||||||
template<typename T>
|
template <typename T> T peektyp (size_t index) const
|
||||||
T peektyp(size_t index) const
|
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<T, std::string>::value, "Use peekstr() instead of peektyp<std::string>()");
|
static_assert (!std::is_same<T, std::string>::value,
|
||||||
if(sizeof(T) != m_parts[index].size())
|
"Use peekstr() instead of peektyp<std::string>()");
|
||||||
throw std::runtime_error("Invalid type, size does not match the message size");
|
if (sizeof (T) != m_parts[index].size ())
|
||||||
T type = *m_parts[index].data<T>();
|
throw std::runtime_error (
|
||||||
|
"Invalid type, size does not match the message size");
|
||||||
|
T type = *m_parts[index].data<T> ();
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create multipart from type (fixed-size)
|
// Create multipart from type (fixed-size)
|
||||||
template<typename T>
|
template <typename T> static multipart_t create (const T &type)
|
||||||
static multipart_t create(const T& type)
|
|
||||||
{
|
{
|
||||||
multipart_t multipart;
|
multipart_t multipart;
|
||||||
multipart.addtyp(type);
|
multipart.addtyp (type);
|
||||||
return multipart;
|
return multipart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy multipart
|
// Copy multipart
|
||||||
multipart_t clone() const
|
multipart_t clone () const
|
||||||
{
|
{
|
||||||
multipart_t multipart;
|
multipart_t multipart;
|
||||||
for (size_t i = 0; i < size(); i++)
|
for (size_t i = 0; i < size (); i++)
|
||||||
multipart.addmem(m_parts[i].data(), m_parts[i].size());
|
multipart.addmem (m_parts[i].data (), m_parts[i].size ());
|
||||||
return multipart;
|
return multipart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump content to string
|
// Dump content to string
|
||||||
std::string str() const
|
std::string str () const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for (size_t i = 0; i < m_parts.size(); i++)
|
for (size_t i = 0; i < m_parts.size (); i++) {
|
||||||
{
|
const unsigned char *data = m_parts[i].data<unsigned char> ();
|
||||||
const unsigned char* data = m_parts[i].data<unsigned char>();
|
size_t size = m_parts[i].size ();
|
||||||
size_t size = m_parts[i].size();
|
|
||||||
|
|
||||||
// Dump the message as text or binary
|
// Dump the message as text or binary
|
||||||
bool isText = true;
|
bool isText = true;
|
||||||
for (size_t j = 0; j < size; j++)
|
for (size_t j = 0; j < size; j++) {
|
||||||
{
|
if (data[j] < 32 || data[j] > 127) {
|
||||||
if (data[j] < 32 || data[j] > 127)
|
|
||||||
{
|
|
||||||
isText = false;
|
isText = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ss << "\n[" << std::dec << std::setw(3) << std::setfill('0') << size << "] ";
|
ss << "\n[" << std::dec << std::setw (3) << std::setfill ('0')
|
||||||
if (size >= 1000)
|
<< size << "] ";
|
||||||
{
|
if (size >= 1000) {
|
||||||
ss << "... (to big to print)";
|
ss << "... (to big to print)";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (size_t j = 0; j < size; j++)
|
for (size_t j = 0; j < size; j++) {
|
||||||
{
|
|
||||||
if (isText)
|
if (isText)
|
||||||
ss << static_cast<char>(data[j]);
|
ss << static_cast<char> (data[j]);
|
||||||
else
|
else
|
||||||
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(data[j]);
|
ss << std::hex << std::setw (2) << std::setfill ('0')
|
||||||
|
<< static_cast<short> (data[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if equal to other multipart
|
// Check if equal to other multipart
|
||||||
bool equal(const multipart_t* other) const
|
bool equal (const multipart_t *other) const
|
||||||
{
|
{
|
||||||
if (size() != other->size())
|
if (size () != other->size ())
|
||||||
return false;
|
return false;
|
||||||
for (size_t i = 0; i < size(); i++)
|
for (size_t i = 0; i < size (); i++)
|
||||||
if (*peek(i) != *other->peek(i))
|
if (*peek (i) != *other->peek (i))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Disable implicit copying (moving is more efficient)
|
// Disable implicit copying (moving is more efficient)
|
||||||
multipart_t(const multipart_t& other) ZMQ_DELETED_FUNCTION;
|
multipart_t (const multipart_t &other) ZMQ_DELETED_FUNCTION;
|
||||||
void operator=(const multipart_t& other) ZMQ_DELETED_FUNCTION;
|
void operator= (const multipart_t &other) ZMQ_DELETED_FUNCTION;
|
||||||
}; // class multipart_t
|
}; // class multipart_t
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const multipart_t& msg)
|
inline std::ostream &operator<< (std::ostream &os, const multipart_t &msg)
|
||||||
{
|
{
|
||||||
return os << msg.str();
|
return os << msg.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ZMQ_HAS_RVALUE_REFS
|
#endif // ZMQ_HAS_RVALUE_REFS
|
||||||
|
|
||||||
#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) \
|
||||||
class active_poller_t
|
&& defined(ZMQ_HAVE_POLLER)
|
||||||
|
class active_poller_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
active_poller_t () = default;
|
||||||
|
~active_poller_t () = default;
|
||||||
|
|
||||||
|
active_poller_t (const active_poller_t &) = delete;
|
||||||
|
active_poller_t &operator= (const active_poller_t &) = delete;
|
||||||
|
|
||||||
|
active_poller_t (active_poller_t &&src) = default;
|
||||||
|
active_poller_t &operator= (active_poller_t &&src) = default;
|
||||||
|
|
||||||
|
using handler_t = std::function<void(short)>;
|
||||||
|
|
||||||
|
void add (zmq::socket_t &socket, short events, handler_t handler)
|
||||||
{
|
{
|
||||||
public:
|
auto it = decltype (handlers)::iterator{};
|
||||||
active_poller_t () = default;
|
auto inserted = bool{};
|
||||||
~active_poller_t () = default;
|
std::tie (it, inserted) =
|
||||||
|
handlers.emplace (static_cast<void *> (socket),
|
||||||
active_poller_t(const active_poller_t&) = delete;
|
std::make_shared<handler_t> (std::move (handler)));
|
||||||
active_poller_t &operator=(const active_poller_t&) = delete;
|
try {
|
||||||
|
base_poller.add (socket, events,
|
||||||
active_poller_t(active_poller_t&& src) = default;
|
inserted && *(it->second) ? it->second.get ()
|
||||||
active_poller_t &operator=(active_poller_t&& src) = default;
|
: nullptr);
|
||||||
|
need_rebuild |= inserted;
|
||||||
using handler_t = std::function<void(short)>;
|
}
|
||||||
|
catch (const zmq::error_t &) {
|
||||||
void add (zmq::socket_t &socket, short events, handler_t handler)
|
// rollback
|
||||||
{
|
if (inserted) {
|
||||||
auto it = decltype (handlers)::iterator {};
|
handlers.erase (static_cast<void *> (socket));
|
||||||
auto inserted = bool {};
|
|
||||||
std::tie(it, inserted) = handlers.emplace (static_cast<void*>(socket), std::make_shared<handler_t> (std::move (handler)));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
base_poller.add (socket, events, inserted && *(it->second) ? it->second.get() : nullptr);
|
|
||||||
need_rebuild |= inserted;
|
|
||||||
}
|
}
|
||||||
catch (const zmq::error_t&)
|
throw;
|
||||||
{
|
}
|
||||||
// rollback
|
}
|
||||||
if (inserted)
|
|
||||||
{
|
void remove (zmq::socket_t &socket)
|
||||||
handlers.erase (static_cast<void*>(socket));
|
{
|
||||||
}
|
base_poller.remove (socket);
|
||||||
throw;
|
handlers.erase (static_cast<void *> (socket));
|
||||||
|
need_rebuild = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modify (zmq::socket_t &socket, short events)
|
||||||
|
{
|
||||||
|
base_poller.modify (socket, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wait (std::chrono::milliseconds timeout)
|
||||||
|
{
|
||||||
|
if (need_rebuild) {
|
||||||
|
poller_events.resize (handlers.size ());
|
||||||
|
poller_handlers.clear ();
|
||||||
|
poller_handlers.reserve (handlers.size ());
|
||||||
|
for (const auto &handler : handlers) {
|
||||||
|
poller_handlers.push_back (handler.second);
|
||||||
}
|
}
|
||||||
|
need_rebuild = false;
|
||||||
}
|
}
|
||||||
|
const int count = base_poller.wait_all (poller_events, timeout);
|
||||||
void remove (zmq::socket_t &socket)
|
if (count != 0) {
|
||||||
{
|
std::for_each (poller_events.begin (),
|
||||||
base_poller.remove (socket);
|
poller_events.begin () + count,
|
||||||
handlers.erase (static_cast<void*>(socket));
|
[](zmq_poller_event_t &event) {
|
||||||
need_rebuild = true;
|
if (event.user_data != NULL)
|
||||||
|
(*reinterpret_cast<handler_t *> (
|
||||||
|
event.user_data)) (event.events);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void modify (zmq::socket_t &socket, short events)
|
bool empty () const { return handlers.empty (); }
|
||||||
{
|
|
||||||
base_poller.modify (socket, events);
|
|
||||||
}
|
|
||||||
|
|
||||||
int wait (std::chrono::milliseconds timeout)
|
size_t size () const { return handlers.size (); }
|
||||||
{
|
|
||||||
if (need_rebuild) {
|
|
||||||
poller_events.resize (handlers.size ());
|
|
||||||
poller_handlers.clear ();
|
|
||||||
poller_handlers.reserve (handlers.size ());
|
|
||||||
for (const auto &handler : handlers) {
|
|
||||||
poller_handlers.push_back (handler.second);
|
|
||||||
}
|
|
||||||
need_rebuild = false;
|
|
||||||
}
|
|
||||||
const int count = base_poller.wait_all (poller_events, timeout);
|
|
||||||
if (count != 0) {
|
|
||||||
std::for_each (poller_events.begin (), poller_events.begin () + count,
|
|
||||||
[](zmq_poller_event_t& event) {
|
|
||||||
if (event.user_data != NULL)
|
|
||||||
(*reinterpret_cast<handler_t*> (event.user_data)) (event.events);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty () const
|
private:
|
||||||
{
|
bool need_rebuild{false};
|
||||||
return handlers.empty ();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size () const
|
poller_t<handler_t> base_poller{};
|
||||||
{
|
std::unordered_map<void *, std::shared_ptr<handler_t>> handlers{};
|
||||||
return handlers.size ();
|
std::vector<zmq_poller_event_t> poller_events{};
|
||||||
}
|
std::vector<std::shared_ptr<handler_t>> poller_handlers{};
|
||||||
|
}; // class active_poller_t
|
||||||
private:
|
|
||||||
bool need_rebuild {false};
|
|
||||||
|
|
||||||
poller_t<handler_t> base_poller {};
|
|
||||||
std::unordered_map<void*, std::shared_ptr<handler_t>> handlers {};
|
|
||||||
std::vector<zmq_poller_event_t> poller_events {};
|
|
||||||
std::vector<std::shared_ptr<handler_t>> poller_handlers {};
|
|
||||||
}; // class active_poller_t
|
|
||||||
#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
||||||
|
|
||||||
|
|
||||||
} // namespace zmq
|
} // namespace zmq
|
||||||
|
|
||||||
#endif // __ZMQ_ADDON_HPP_INCLUDED__
|
#endif // __ZMQ_ADDON_HPP_INCLUDED__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user