我正在解析二进制标头(std::vector<unsigned char>
),并且需要提取四个无符号整数。
有时(对于其他标头)我有时还需要提取unsigned short
,因此最好使用通用解决方案。
如何将std :: vector的切片转换为整数?
这是我尝试过的:
class PacketHeader {
public:
static const unsigned short LENGTH = 16;
PacketHeader(std::vector<unsigned char> &binary_data) {
this->timestamp_seconds = ntohs(*reinterpret_cast<const unsigned int *>(&binary_data[0]));
this->timestamp_ms_or_ns = ntohs(*reinterpret_cast<const unsigned int *>(&binary_data[4]));
this->packet_data_length = ntohs(*reinterpret_cast<const unsigned int *>(&binary_data[8]));
this->untruncated_packet_data_length = ntohs(*reinterpret_cast<const unsigned int *>(&binary_data[12]));
}
unsigned int get_timestamp_seconds();
unsigned int get_timestamp_ms_or_ns();
unsigned int get_packet_data_length();
unsigned int get_untruncated_packet_data_length();
private:
unsigned int timestamp_seconds;
unsigned int timestamp_ms_or_ns;
unsigned int packet_data_length;
unsigned int untruncated_packet_data_length;
};
答案 0 :(得分:0)
当然,在发布此问题后,我找到了可行的解决方案。
这是我从here中找到的内容:
template <typename T>
T extract(const vector<unsigned char> &v, int pos)
{
T value;
memcpy(&value, &v[pos], sizeof(T));
return value;
}
答案 1 :(得分:0)
创建一个Serialiser / Deserialiser以自动将数据打包到字节数组中。在下面,我迅速介绍了一个序列化器,该序列化器仅序列化整数类型。您可以将其扩展到字符串,向量,其他对象(使用递归)。
using Buffer = std::vector<int>;
/*!
* Serialise all primitive data types (Intergrals: 8, 16, 32, 64)
*/
template <typename T>
void serialise(Buffer& buffer, uint32_t& offset, const T& data)
{
uint32_t size = sizeof(data); // Get size for memcpy
buffer.resize(buffer.size()+size); // Ensure data will fit
memcpy( &buffer[offset], &data, sizeof(data) ); // Copy data (use ntohs aswell)
offset += size; // Increase offset for next item
}
/*!
* Primitive Serialiser class which should be applied to elements in a visitor-
* pattern type construct. Fills buffer with packed binary data of elements.
*/
class Serialiser
{
public:
Buffer& buffer; // resulting byte buffer (just a std::vector<uint8_t>)
uint32_t offset; // offset use internally
public:
Serialiser(Buffer& _buffer) : buffer(_buffer), offset(0)
{}
// Serialise singular data type
template <typename T>
operator() (const T& data)
{
serialise(buffer, offset, data);
}
};
现在可以使用它!
struct PacketHeader
{
private:
uint32_t timestamp_seconds;
uint32_t timestamp_ms_or_ns;
public:
PacketHeader()=default;
// .. Extra constructors if you want?
private:
template<typename SER>
void serialise(SER& ser)
{
ser(timestamp_seconds);
ser(timestamp_ms_or_ns);
}
};
int main()
{
// Create Packet Struct with data?
PacketHeader packet(...);
Buffer buffer;
Serialiser serialiser(buffer);
// Serialise the packet INTO the buffer
packet.serialise(serialiser);
// DONE! Read data out
// .. print bytes of buffer
return 0;
}
因此,Serialiser类通过PacketHeader :: serialise方法将其()运算符应用于数据包类中的每个成员变量。将运算符应用到的每种方法,都会将该变量复制到std :: vector(缓冲区)中。
要反序列化,您只需创建一个反序列化器类即可,它执行反向操作,packetHeader类不需要更改。