Я реализовал сериализацию для dynamic_bitset раньше: Как сериализовать boost::dynamic_bitset?< /а>
Вы можете использовать этот или аналогичный метод, основанный на тех же интерфейсах:
template <typename Block, typename Alloc>
std::string to_binary_string(boost::dynamic_bitset<Block, Alloc> const& bs) {
uint32_t const num_bits = bs.size();
auto const num_blocks = div_roundup(num_bits, sizeof(Block)*CHAR_BIT);
// prepare zeroed output buffer
std::string buf(sizeof(num_bits) + num_blocks * sizeof(Block), '\0');
// write size prefix
std::memcpy(buf.data(), &num_bits, sizeof(num_bits));
// write block data
if (num_bits > 0) { // mustn't pass nullptr to src argument of memcpy
auto b = reinterpret_cast<Block*>(buf.data() + sizeof(num_bits));
to_block_range(bs, b);
}
return buf;
}
Который вы могли бы отправить как:
std::string buf = to_binary_string(my_bitset);
int ret = sendto(sock, buf.data(), buf.size(), flags, reinterpret_cast<SOCKADDR*>(&address), sizeof(address));
Аналогичный код десериализации:
template <typename Block, typename Alloc>
void from_bytes(std::string_view buf, boost::dynamic_bitset<Block, Alloc>& bs) {
// read the size prefix
uint32_t num_bits;
if (buf.size() < sizeof(num_bits)) {
throw std::length_error("from_bytes");
}
std::memcpy(&num_bits, buf.data(), sizeof(num_bits));
// shift buf to only cover the actual bit data
buf = buf.substr(sizeof(num_bits));
// read the bits as blocks
bs.resize(num_bits);
if (buf.size() % sizeof(Block) != 0) {
throw std::length_error("from_bytes");
}
auto b = reinterpret_cast<Block const*>(buf.data());
auto e = reinterpret_cast<Block const*>(buf.data() + buf.size());
size_t const num_blocks = std::distance(b, e);
// sanity checks block count vs num_bits
if (num_blocks != div_roundup(num_bits, sizeof(Block)*CHAR_BIT)) {
throw std::length_error("from_bytes"); // num_blocks doesn't match num_bits
}
from_block_range(b, e, bs);
bs.resize(num_bits);
}
Живая демонстрация
Отказ от ответственности:
- Переносимость здесь НЕ рассматривается. Если вы отправляете данные между системами, использующими другой собственный порядок байтов, поведение не указано, даже несмотря на то, что были приняты меры, чтобы не ВЗРЫВ, данные будут неправильными даже в крайне маловероятном случае, если размеры будут складываться.
- Точно так же не дается никаких гарантий, если десериализованный тип не полностью соответствует сериализованному типу с точки зрения типа блока.
Кроме того, программа тестирует крайние случаи и работает без ошибок в ASAN/UBSAN.
Жить на Coliru
#include <boost/dynamic_bitset.hpp>
#include <climits> // CHAR_BIT
#include <string>
#include <string_view>
// demo output
#include <iostream>
static inline size_t div_roundup(size_t p, size_t q) {
// quick&dirty, see https://stackoverflow.com/a/926806/85371
return (p+q-1)/q;
}
template <typename Block, typename Alloc>
std::string to_binary_string(boost::dynamic_bitset<Block, Alloc> const& bs) {
uint32_t const num_bits = bs.size();
auto const num_blocks = div_roundup(num_bits, sizeof(Block)*CHAR_BIT);
// prepare zeroed output buffer
std::string buf(sizeof(num_bits) + num_blocks * sizeof(Block), '\0');
// write size prefix
std::memcpy(buf.data(), &num_bits, sizeof(num_bits));
// write block data
if (num_bits > 0) { // mustn't pass nullptr to src argument of memcpy
auto b = reinterpret_cast<Block*>(buf.data() + sizeof(num_bits));
to_block_range(bs, b);
}
return buf;
}
template <typename Block, typename Alloc>
void from_bytes(std::string_view buf, boost::dynamic_bitset<Block, Alloc>& bs) {
// read the size prefix
uint32_t num_bits;
if (buf.size() < sizeof(num_bits)) {
throw std::length_error("from_bytes");
}
std::memcpy(&num_bits, buf.data(), sizeof(num_bits));
// shift buf to only cover the actual bit data
buf = buf.substr(sizeof(num_bits));
// read the bits as blocks
bs.resize(num_bits);
if (buf.size() % sizeof(Block) != 0) {
throw std::length_error("from_bytes");
}
auto b = reinterpret_cast<Block const*>(buf.data());
auto e = reinterpret_cast<Block const*>(buf.data() + buf.size());
size_t const num_blocks = std::distance(b, e);
// sanity checks block count vs num_bits
if (num_blocks != div_roundup(num_bits, sizeof(Block)*CHAR_BIT)) {
throw std::length_error("from_bytes"); // num_blocks doesn't match num_bits
}
from_block_range(b, e, bs);
bs.resize(num_bits);
}
int main() {
::srand(::time(0)); // extremely lazy bad random, sue me
for (auto bits = 0; bits < 128; ++bits) {
boost::dynamic_bitset<> my_bitset(bits), roundtrip;
for (size_t bit = 0; bit < my_bitset.size(); ++bit)
my_bitset.set(bit, rand()%2);
from_bytes(to_binary_string(my_bitset), roundtrip);
std::cout << "{" << roundtrip << "} " << (roundtrip == my_bitset? "OK":"ERROR") << std::endl;
}
}
Печать:
{} OK
{0} OK
{11} OK
{001} OK
{0010} OK
{01000} OK
{110011} OK
{0101011} OK
{01101101} OK
{101011011} OK
{1011100010} OK
{11100100110} OK
{110010010000} OK
{0011100110110} OK
{11100110110001} OK
{111101110011011} OK
{1011101100011011} OK
{10101000000110111} OK
{000000110100111111} OK
{0110001110100001011} OK
{11111111010010010110} OK
{010011100110111000011} OK
{0110011101111000111000} OK
{10011100110001001110101} OK
{011001001100011111010011} OK
{1101010010110100000100101} OK
{01101111001100100010111110} OK
{010101111001011111100011000} OK
{0101111001111001000001011011} OK
{10011101100111110110110001010} OK
{000001110000100011000011101000} OK
{1101010001101101111001001110000} OK
{11111010100111110010101111110010} OK
{110010101001101110000001011101110} OK
{1010100100010000011011011010000111} OK
{11101101111011011010110101101010000} OK
{110000101010100111010111011110100010} OK
{1000111110000001111010110000001111010} OK
{00010010011001111101101110101111000000} OK
{000000011000001100101000111110000111101} OK
{1000111111000000000111101110111101100010} OK
{01001110000011011100111110100100010111011} OK
{001000011101111001110111110000110100011001} OK
{0011010001000110100101000010110000101101001} OK
{01110111010111101000011110110011011110110101} OK
{111001000011011110001100000111001000001101010} OK
{1110001101010100101110100111001010100111111001} OK
{00110110011111110001110111110101101010100000110} OK
{101000100110100111001000110111010101101011000011} OK
{0011111001111000011010110110111110111011001101000} OK
{00011100110101100011000001010000111001011001111111} OK
{100101100001101111011001000101110100111110000100001} OK
{1110101000000100001111100111101101111100100011111111} OK
{00001010100111101001000100010111101101100101000001110} OK
{110101000110000011000100000001100100111101001100110011} OK
{1001111110001011100010011110001011010111101010101100100} OK
{00101001010011101000100110011011110101100110000110100010} OK
{010101000111011001001010011001010110111110101011001100100} OK
{0101100010000001010001110011001100000001011101101010110000} OK
{01000111001101100011000010010010111010010010111101101001010} OK
{000111101101111000011101101101101101100001011110111000001000} OK
{0111101011101011101000011001010000011001010111001001111000011} OK
{01000100010000000110001110110010110100001000001011110000010011} OK
{110100101010111101010010011100110000110100001010110100110001011} OK
{0111110001111011011001110000101100111011010000000101111010000111} OK
{01101000000101000000010010010100010101000110100011001010011011011} OK
{110111111011010011011001001011000100010000100001001000000111110011} OK
{0000111000100111101000000001111000011100000101010100001101111101111} OK
{11100101011110110110101100100100110110110110000000000101000000000011} OK
{111011000011111101100101001010010010101110001001100110111100101011101} OK
{1001110011100111010010110011010111111001100110010011010100101000010010} OK
{01011111001100011100000000011100000111010111001111100001100110001111110} OK
{010010111000101000111100000000010011111110010110011110000000000000001100} OK
{1101010011010110010100000100100110100100100110011100011010000001000001011} OK
{10100101001110110001011010010101100100110100011011001000010110100001101010} OK
{101010100011101100111000111001011011010111000101101011111011000001010111110} OK
{1011011101011011000101101101000110011001001001110101010010001010111000101011} OK
{01100101111100011110101000001010111101011011100101111000101110011011110011100} OK
{111100111010011100010111101010110101110000100111011001001111001100001011111110} OK
{0000010110001101001001110010011011010111100010100001111010100000100000101010010} OK
{10010100010000110101000000101001011011001001000110110110110001000001001000011011} OK
{011011101100001101001110111110000111010111010011001100100010011111110000101101000} OK
{0011001100110110111111101010011111010001000001110001010000101110111100100010111101} OK
{10001101001110001000001110110011111010010111100101011100111110010100010111100001010} OK
{111100011111110011011001001111101111110001010100010000001101000000101001111110011000} OK
{1001100110101000000110001000101010100101110100011100100010111111010101101001110000011} OK
{11000111100001000001001010010011010101100100101100001100101110010100000000000111100000} OK
{011011101010011001000000101101100011010110001000111010100001111000111001101011110111110} OK
{1011100111101110001111011101111010011100111111111110011010010000111101100000110111110000} OK
{11010010100011011010011111101011100101010100110100101001010011100011100001001000010001100} OK
{101100101110110110010010010001000010101100101010000110000100101111110100010111010111010000} OK
{1001100111111100000101011010100111101010000110010100100111011001010101111010100000000110011} OK
{11001000001101011000100011101111000001110011000100010011011011110010110001111001000101000010} OK
{010101110110011011001001111010100001101010110101001101010100110111011101001110111011111111001} OK
{0000001100010100101010000011000000100110011001011111101110100111011110100011011101001011001111} OK
{11101001010111000101001110011001010000000110010110011010100001000010011010010010010110110110100} OK
{100001001010100100000100111100101100000111111010110010101101000110010110010110011111110010111010} OK
{0110011101101011110011100101100110111110011110110001100101011000101110110001011110100000001010101} OK
{11111011101101010010010000101110000111011011001010001000000111101110110001000101110100110101001100} OK
{101001001001010101110010000100001000001101111111010000000110100111110001111010100100001001100100100} OK
{1010011111100001100101101110111001110011110100000100100100110011101110001000010000100001011101001101} OK
{10101011111010101101011101110010101111010001100011111000110011111011101110101110011011010111110011010} OK
{101001011011011011111101011110110000010001000011001011111100011000001100111100001000101111101000110100} OK
{1100001111000101010001010010000110011001111111011101100011111010100011110011011001001110010100111101010} OK
{01110111101110010010110110011011100101001010011010110010000011100111111101010110110001000111101011001011} OK
{111110001010000011111101001011100010111001001110001101001011100010111001011001111110001110111000010001010} OK
{1000110001111101001001100010011101011011000000001010111001111001100001001000101111001011010000011100100110} OK
{01101100101011110001001001101001110100111100111101000100010111101011000101101110101011010100011111110101111} OK
{100011010110010100001100010011111100101010011010110101001010000100011100011110000110111101000011011110010111} OK
{0001110100111110010010100101000111111101101110010011100110111101111001111111100101100000101110011011000001101} OK
{10000101011100100101100111111000010100011100010101111000001101010011111010011011011000110011000100110100101000} OK
{100110110011000000010000100011100010010101110000111010010101011000110101111101110011011101001011001101010001010} OK
{1001010100011011000111111111111001011010000001110100011100001101000001000010101000111110110010100101101111111111} OK
{00111000110111101110100111000110101111111101101100011111111110101010101001000000110000111101101111010011100011011} OK
{111100000100010001011010111001111111010111001101000100010011010110100111011010111101001110010001001111100110110010} OK
{1111110110110111110000001110010010100011000101001001111010001001111101111100000011000101001001001101000110000001100} OK
{11110101001111001100101001010100101110100011000101110001101101101110111101010101111011010100000110100011111011010101} OK
{100111000001000011100001011000001100100010101011110110001100010100001011111011000011100110011001101110011111101000101} OK
{1110110110010100001000101001001110100000110010110011110001111111110011111010000010111101001000110010011111001111101000} OK
{00000101100100000111110000100101010100101000011000111010110110111100111101111110110101100011101101011000000001001110111} OK
{010111011011000010001010010100010110001001101101101101001011010001000010010000000111011100100110101011001000001011011000} OK
{0011011110010110010111101101111100111110000010111101010001101111101101101001001000101101101001110000110000000110100010010} OK
{00001001010011101011011010010000000011000110011100000101111000100101111110101111100100011110100101011101101111100011100101} OK
{001011011110110000011010101000001001100100011001000100110100100111100101100010111101001010101100100100011010111010000101100} OK
{1111110110100111101011110100111011000001001111111010100011110001100100010010110110111110111100001011101000000100100000100100} OK
{01110000101110010101010110100001010010101010001111110100010111000011101000111010101111001011100111000011111011110011101011100} OK
{001100001010111010111001111011011000100100110010110001010000001110000001000110010101101000111110010101001010101100010111100011} OK
{1100011010110110001110101000110011110110010011010101110001010111110010000110011111110101111010110001010100110010000101001110011} OK
person
sehe
schedule
26.01.2021
0
и1
, если это соответствует требованиям. - person PaulMcKenzie   schedule 26.01.2021dynamic_bitset
меньше 8 бит, вы все равно будете тратить пропускную способность на отправку неиспользуемых битов. Таким образом, вы также можете преобразовать данныеdynamic_bitset
в переносимый формат, например, в массивuintX[]
. Вы сами сказали, что не знаете, использует ли другая сторона такжеdynamic_bitset
, поэтому вы не можете просто отправить необработанные данные битового набора как есть, их необходимо сериализовать в форму, которую другая сторона может затем десериализовать во что угодно оно хочет. - person Remy Lebeau   schedule 26.01.2021