поток данных в байтовый массив

Я должен признать, что я немного запутался в данный момент, поэтому извините, если вопрос не совсем ясен или тривиален (на самом деле я надеюсь, что это последний) ….

Я отправляю массив байтов по сети и хотел бы сделать что-то вроде этого на стороне отправителя:

size_t max_size = 100;
uint8_t buffer[size];
idontknowwhat_t x{buffer};
uint16_t size = 11;                 // total number of bytes in the buffer
uint16_t id_a,id_b,id_c;            // some ids
uint8_t  a,b,c;                     // some data
x << size << id_a << a << id_b << b << id_c << c;
someMethodToSend(buffer,size);

и на стороне получателя что-то вроде этого:

size_t max_size = 100;
uint8_t buffer[size];
someMethodToReceive(buffer);
idontknowwhat_t x{buffer};
uint16_t size;
x >> size;
for (uint16_t i=0; i<size-2; i++) {
uint16_t id;
uint8_t data;
x >> id >> data;
std::cout << id << " " << data;
}

Так что моя цель в основном состоит в том, чтобы избежать уродливых приведений и ручного увеличения указателя при возможности иметь uint8_t а также uint16_t (и, возможно, также uint32_t) в буфере. Данные, которые я помещаю в буфер здесь, являются лишь примером, и я знаю, что мне нужно позаботиться о порядке байтов при отправке по сети (и было бы хорошо, если бы мне пришлось делать это «вручную»).

Есть ли что-то, что я могу использовать вместо моей гипотетической idontknowwhat_t ?

0

Решение

Вы не можете избежать уродливых бросков, но, по крайней мере, можете скрыть их в idontknowwhat_t класса operator>> а также operator<< функции. А используя шаблоны, вы можете ограничить количество приведений в коде до минимума.

class idontknowwhat_t
{
uint8_t* _data;

public:
idontknowwhat_t(uint8_t* buffer)
: _data(buffer)
{}

template<typename insert_type>
idontknowwhat_t& operator<<(insert_type value)
{
*reinterpret_cast<insert_type*>(_data) = value;
_data += sizeof(insert_type);
return *this;
}
template<typename extract_type>
idontknowwhat_t& operator>>(extract_type& value)
{
value = *reinterpret_cast<extract_type*>(_data);
_data += sizeof(extract_type);
return *this;
}
};

Я думаю, что это на самом деле будет работать непосредственно с вашим кодом. В этом примере idontknowwhat_t класс не владеет буфером и просто хранит необработанный указатель на следующий бит данных, которые он ожидает прочитать или записать. В реальных целях я бы рекомендовал idontknowwhat_t Класс управления буферной памятью.

Кроме того, ни один из кодов на этой странице на самом деле не заботится о порядке байтов данных, что определенно idontknowwhat_t ответственность класса Eсть форсированная библиотека для этого. Я не документирую использование этой библиотеки здесь, так как думаю, что это отвлекает от реальных вопросов.

1

Другие решения

Ты пытался станд :: список? Вы можете сгруппировать элементы по типам и поместить их в списки с соответствующим типом. Затем вы можете создать std :: list из std :: lists.

0