| 276 | #endif |
| 277 | > |
| 278 | message_t encode(const Range &parts) |
| 279 | { |
| 280 | size_t mmsg_size = 0; |
| 281 | |
| 282 | // First pass check sizes |
| 283 | for (const auto &part : parts) { |
| 284 | const size_t part_size = part.size(); |
| 285 | if (part_size > (std::numeric_limits<std::uint32_t>::max)()) { |
| 286 | // Size value must fit into uint32_t. |
| 287 | throw std::range_error("Invalid size, message part too large"); |
| 288 | } |
| 289 | const size_t count_size = |
| 290 | part_size < (std::numeric_limits<std::uint8_t>::max)() ? 1 : 5; |
| 291 | mmsg_size += part_size + count_size; |
| 292 | } |
| 293 | |
| 294 | message_t encoded(mmsg_size); |
| 295 | unsigned char *buf = encoded.data<unsigned char>(); |
| 296 | for (const auto &part : parts) { |
| 297 | const uint32_t part_size = static_cast<uint32_t>(part.size()); |
| 298 | const unsigned char *part_data = |
| 299 | static_cast<const unsigned char *>(part.data()); |
| 300 | |
| 301 | if (part_size < (std::numeric_limits<std::uint8_t>::max)()) { |
| 302 | // small part |
| 303 | *buf++ = static_cast<unsigned char>(part_size); |
| 304 | } else { |
| 305 | // big part |
| 306 | *buf++ = (std::numeric_limits<uint8_t>::max)(); |
| 307 | detail::write_network_order(buf, part_size); |
| 308 | buf += sizeof(part_size); |
| 309 | } |
| 310 | std::memcpy(buf, part_data, part_size); |
| 311 | buf += part_size; |
| 312 | } |
| 313 | |
| 314 | assert(static_cast<size_t>(buf - encoded.data<unsigned char>()) == mmsg_size); |
| 315 | return encoded; |
| 316 | } |
| 317 | |
| 318 | /* Decode an encoded message to multiple parts. |
| 319 |
no test coverage detected