#include #include #ifdef ZMQ_CPP11 TEST_CASE("multipart codec empty", "[codec_multipart]") { using namespace zmq; multipart_t mmsg; message_t msg = mmsg.encode(); CHECK(msg.size() == 0); multipart_t mmsg2; mmsg2.decode_append(msg); CHECK(mmsg2.size() == 0); } TEST_CASE("multipart codec small", "[codec_multipart]") { using namespace zmq; multipart_t mmsg; mmsg.addstr("Hello World"); message_t msg = mmsg.encode(); CHECK(msg.size() == 1 + 11); // small size packing mmsg.addstr("Second frame"); msg = mmsg.encode(); CHECK(msg.size() == 1 + 11 + 1 + 12); multipart_t mmsg2; mmsg2.decode_append(msg); CHECK(mmsg2.size() == 2); std::string part0 = mmsg2[0].to_string(); CHECK(part0 == "Hello World"); CHECK(mmsg2[1].to_string() == "Second frame"); } TEST_CASE("multipart codec big", "[codec_multipart]") { using namespace zmq; message_t big(495); // large size packing big.data()[0] = 'X'; multipart_t mmsg; mmsg.pushmem(big.data(), big.size()); message_t msg = mmsg.encode(); CHECK(msg.size() == 5 + 495); CHECK(msg.data()[0] == std::numeric_limits::max()); CHECK(msg.data()[5] == 'X'); CHECK(mmsg.size() == 1); mmsg.decode_append(msg); CHECK(mmsg.size() == 2); CHECK(mmsg[0].data()[0] == 'X'); } TEST_CASE("multipart codec decode bad data overflow", "[codec_multipart]") { using namespace zmq; char bad_data[3] = {5, 'h', 'i'}; message_t wrong_size(bad_data, 3); CHECK(wrong_size.size() == 3); CHECK(wrong_size.data()[0] == 5); CHECK_THROWS_AS( multipart_t::decode(wrong_size), const std::out_of_range&); } TEST_CASE("multipart codec decode bad data extra data", "[codec_multipart]") { using namespace zmq; char bad_data[3] = {1, 'h', 'i'}; message_t wrong_size(bad_data, 3); CHECK(wrong_size.size() == 3); CHECK(wrong_size.data()[0] == 1); CHECK_THROWS_AS( multipart_t::decode(wrong_size), const std::out_of_range&); } // After exercising it, this test is disabled over concern of running // on hosts which lack enough free memory to allow the absurdly large // message part to be allocated. #if 0 TEST_CASE("multipart codec encode too big", "[codec_multipart]") { using namespace zmq; const size_t too_big_size = 1L + std::numeric_limits::max(); CHECK(too_big_size > std::numeric_limits::max()); char* too_big_data = new char[too_big_size]; multipart_t mmsg(too_big_data, too_big_size); delete [] too_big_data; CHECK(mmsg.size() == 1); CHECK(mmsg[0].size() > std::numeric_limits::max()); CHECK_THROWS_AS( mmsg.encode(), std::range_error); } #endif TEST_CASE("multipart codec free function with vector of message_t", "[codec_multipart]") { using namespace zmq; std::vector parts; parts.emplace_back("Hello", 5); parts.emplace_back("World",5); auto msg = encode(parts); CHECK(msg.size() == 1 + 5 + 1 + 5 ); CHECK(msg.data()[0] == 5); CHECK(msg.data()[1] == 'H'); CHECK(msg.data()[6] == 5); CHECK(msg.data()[7] == 'W'); std::vector parts2; decode(msg, std::back_inserter(parts2)); CHECK(parts.size() == 2); CHECK(parts[0].size() == 5); CHECK(parts[1].size() == 5); } TEST_CASE("multipart codec free function with vector of const_buffer", "[codec_multipart]") { using namespace zmq; std::vector parts; parts.emplace_back("Hello", 5); parts.emplace_back("World",5); auto msg = encode(parts); CHECK(msg.size() == 1 + 5 + 1 + 5 ); CHECK(msg.data()[0] == 5); CHECK(msg.data()[1] == 'H'); CHECK(msg.data()[6] == 5); CHECK(msg.data()[7] == 'W'); std::vector parts2; decode(msg, std::back_inserter(parts2)); CHECK(parts.size() == 2); CHECK(parts[0].size() == 5); CHECK(parts[1].size() == 5); } TEST_CASE("multipart codec free function with vector of mutable_buffer", "[codec_multipart]") { using namespace zmq; std::vector parts; char hello[6] = "Hello"; parts.emplace_back(hello, 5); char world[6] = "World"; parts.emplace_back(world,5); auto msg = encode(parts); CHECK(msg.size() == 1 + 5 + 1 + 5 ); CHECK(msg.data()[0] == 5); CHECK(msg.data()[1] == 'H'); CHECK(msg.data()[6] == 5); CHECK(msg.data()[7] == 'W'); std::vector parts2; decode(msg, std::back_inserter(parts2)); CHECK(parts.size() == 2); CHECK(parts[0].size() == 5); CHECK(parts[1].size() == 5); } TEST_CASE("multipart codec free function with multipart_t", "[codec_multipart]") { using namespace zmq; multipart_t mmsg; mmsg.addstr("Hello"); mmsg.addstr("World"); auto msg = encode(mmsg); CHECK(msg.size() == 1 + 5 + 1 + 5); CHECK(msg.data()[0] == 5); CHECK(msg.data()[1] == 'H'); CHECK(msg.data()[6] == 5); CHECK(msg.data()[7] == 'W'); multipart_t mmsg2; decode(msg, std::back_inserter(mmsg2)); CHECK(mmsg2.size() == 2); CHECK(mmsg2[0].size() == 5); CHECK(mmsg2[1].size() == 5); } TEST_CASE("multipart codec static method decode to multipart_t", "[codec_multipart]") { using namespace zmq; multipart_t mmsg; mmsg.addstr("Hello"); mmsg.addstr("World"); auto msg = encode(mmsg); auto mmsg2 = multipart_t::decode(msg); CHECK(mmsg2.size() == 2); CHECK(mmsg2[0].size() == 5); CHECK(mmsg2[1].size() == 5); } #endif