Skip to content

Commit 8bace31

Browse files
cacharleCharles Cabergs
andauthored
Update zmq::message_t::str with max_size (#665)
* Update zmq::message_t::str with an argument to set the maximum message size to put in a debug string * Fix std::min on Windows and move byte variable to a lower scope --------- Co-authored-by: Charles Cabergs <charles.cabergs@intellis.ch>
1 parent 3bcbd9d commit 8bace31

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

tests/message.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,24 @@ TEST_CASE("message to string", "[message]")
196196
#endif
197197
}
198198

199+
TEST_CASE("message to debug string", "[message]")
200+
{
201+
const zmq::message_t a;
202+
const zmq::message_t b("Foo", 3);
203+
const zmq::message_t c("ascii\x01\x02\x03%%%\x04\x05\x06###", 17);
204+
const zmq::message_t d("\x01\x02\x03|||", 6);
205+
CHECK(a.str() == "zmq::message_t [size 000] ()");
206+
CHECK(b.str() == "zmq::message_t [size 003] (Foo)");
207+
CHECK(c.str() == "zmq::message_t [size 017] (ascii 010203 %%% 040506 ###)");
208+
CHECK(d.str() == "zmq::message_t [size 006] (010203 |||)");
209+
// With max_size
210+
CHECK(a.str(100) == "zmq::message_t [size 000] ()");
211+
CHECK(b.str(2) == "zmq::message_t [size 003] (Fo... too big to print)");
212+
CHECK(c.str(10)
213+
== "zmq::message_t [size 017] (ascii 010203 %%... too big to print)");
214+
CHECK(d.str(2) == "zmq::message_t [size 006] (0102... too big to print)");
215+
}
216+
199217
#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
200218
TEST_CASE("message routing id persists", "[message]")
201219
{

zmq.hpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -691,39 +691,40 @@ class message_t
691691
* Use to_string() or to_string_view() for
692692
* interpreting the message as a string.
693693
*/
694-
std::string str() const
694+
std::string str(size_t max_size = 1000) const
695695
{
696696
// Partly mutuated from the same method in zmq::multipart_t
697697
std::stringstream os;
698698

699699
const unsigned char *msg_data = this->data<unsigned char>();
700-
unsigned char byte;
701-
size_t size = this->size();
700+
size_t size_to_print = (std::min)(this->size(), max_size);
702701
int is_ascii[2] = {0, 0};
702+
// Set is_ascii for the first character
703+
if (size_to_print > 0)
704+
is_ascii[0] = (*msg_data >= 32 && *msg_data < 127);
703705

704706
os << "zmq::message_t [size " << std::dec << std::setw(3)
705-
<< std::setfill('0') << size << "] (";
706-
// Totally arbitrary
707-
if (size >= 1000) {
708-
os << "... too big to print)";
709-
} else {
710-
while (size--) {
711-
byte = *msg_data++;
712-
713-
is_ascii[1] = (byte >= 32 && byte < 127);
714-
if (is_ascii[1] != is_ascii[0])
715-
os << " "; // Separate text/non text
716-
717-
if (is_ascii[1]) {
718-
os << byte;
719-
} else {
720-
os << std::hex << std::uppercase << std::setw(2)
721-
<< std::setfill('0') << static_cast<short>(byte);
722-
}
723-
is_ascii[0] = is_ascii[1];
707+
<< std::setfill('0') << this->size() << "] (";
708+
while (size_to_print--) {
709+
const unsigned char byte = *msg_data++;
710+
711+
is_ascii[1] = (byte >= 32 && byte < 127);
712+
if (is_ascii[1] != is_ascii[0])
713+
os << " "; // Separate text/non text
714+
715+
if (is_ascii[1]) {
716+
os << byte;
717+
} else {
718+
os << std::hex << std::uppercase << std::setw(2) << std::setfill('0')
719+
<< static_cast<short>(byte);
724720
}
725-
os << ")";
721+
is_ascii[0] = is_ascii[1];
726722
}
723+
// Elide the rest if the message is too large
724+
if (max_size < this->size())
725+
os << "... too big to print)";
726+
else
727+
os << ")";
727728
return os.str();
728729
}
729730

0 commit comments

Comments
 (0)