从 std::vector<无符号字符>切片中提取 int?
Extracting an int from slice of std::vector<unsigned char>?
我正在解析一个二进制标头(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;
};
当然,在我发布这个问题之后,我找到了一个有效的解决方案。
这是我从这里找到的:
template <typename T>
T extract(const vector<unsigned char> &v, int pos)
{
T value;
memcpy(&value, &v[pos], sizeof(T));
return value;
}
创建一个序列化器/反序列化器以自动将数据打包到字节数组中。下面我快速开发了一个序列化器,它只序列化整数类型。您可以将其扩展到字符串、向量和其他对象(使用递归(。
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(缓冲区(中。
要反序列化,您只需创建一个反序列化器类来执行反向 memcpy,而 packetHeader 类不需要更改。
相关文章:
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 如何设置一个范围来提取我想要获得的信息
- 如何优雅地切片对象
- 视觉工作室项目.提取源文件夹名称
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 避免矢量中的对象切片<Base><shared_ptr>
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- 在C++中使用重载提取运算符时出现问题
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 无法从 std::string 中提取C++ Unicode 符号
- 如何从也包含C++字母的文本文件中提取某些数字?
- 如何从适合一定范围的数字中提取数字?
- C++从通用引用中提取实际类型
- 从运行服务的应用程序代码中提取窗口句柄