Kylin/AsioZeroMQ/Message.cpp
2023-07-21 14:07:27 +08:00

86 lines
2.4 KiB
C++

#include "Message.h"
#include <boost/assert.hpp>
#include <iomanip>
#include <sstream>
namespace ZeroMQ {
Message::Message() noexcept { zmq_msg_init(&m_message); }
Message::~Message() noexcept {
int rc = zmq_msg_close(&m_message);
BOOST_ASSERT_MSG(rc == 0, "init failed.");
}
Message::Message(Message &&rhs) noexcept : m_message(rhs.m_message) {
int rc = zmq_msg_init(&rhs.m_message);
BOOST_ASSERT(rc == 0);
}
Message &Message::operator=(Message &&rhs) noexcept {
std::swap(m_message, rhs.m_message);
return *this;
}
bool Message::operator==(const Message &other) const noexcept {
const size_t my_size = size();
return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size);
}
bool Message::operator!=(const Message &other) const noexcept { return !(*this == other); }
Message::Message(const void *dataSrc, size_t size) {
int rc = zmq_msg_init_size(&m_message, size);
if (rc != 0) throw makeErrorCode();
if (size) {
// this constructor allows (nullptr, 0), memcpy with a null pointer is UB
memcpy(data(), dataSrc, size);
}
}
void Message::copy(Message &message) {
int rc = zmq_msg_copy(&m_message, message.handle());
if (rc != 0) throw makeErrorCode();
}
std::string Message::dump() const {
// Partly mutuated from the same method in zmq::multipart_t
std::ostringstream os;
const unsigned char *msg_data = this->data<unsigned char>();
unsigned char byte;
size_t size = this->size();
int is_ascii[2] = {0, 0};
os << "Message [size " << std::dec << std::setw(3) << std::setfill('0') << size << "] (";
// Totally arbitrary
if (size >= 1000) {
os << "... too big to print)";
} else {
while (size--) {
byte = *msg_data++;
is_ascii[1] = (byte >= 32 && byte < 127);
if (is_ascii[1] != is_ascii[0]) os << " "; // Separate text/non text
if (is_ascii[1]) {
os << byte;
} else {
os << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<short>(byte);
}
is_ascii[0] = is_ascii[1];
}
os << ")";
}
return os.str();
}
} // namespace ZeroMQ
namespace std {
ostream &operator<<(ostream &stream, const ZeroMQ::Message &message) {
stream << message.dump();
return stream;
}
} // namespace std