Rom*_*dgz 4 c++ parsing bit-manipulation
我正在寻找在C++中解析二进制消息的任何示例库.大多数人要求读取二进制文件或在套接字中接收的数据,但我只需要解码一组二进制消息.有人提到了boost :: spirit,但我找不到合适的例子来满足我的需求.
例如:9A690C12E077033811FFDFFEF07F042C1CE0B704381E00B1FEFFF78004A92440
其中前8位是前同步码,接下来是6位msg ID(0到63之间的整数),接下来的212位是数据,最后24位是CRC24.
所以在这种情况下,msg 26,我必须从212个数据位获取这些数据:
编辑:我需要在位级操作,因此memcpy不是一个好的解决方案,因为它复制了许多字节.要获得第一个4位整数值,我应该从一个字节获得2位,从下一个字节获得另外2位,移位每一对并组成.我要求的是一种更优雅的方法来提取值,因为我有大约20种不同的消息,并希望达到一个通用的解决方案来解析它们的位级别.
等等.
你知道os可以轻松实现这个吗?
我还发现了其他使用static_cast的Q/A. 我用Google搜索,并且对于推荐这种方法的每个人,还有另一个关于端序的警告.由于我已经有了我的消息,我不知道这样的警告是否适用于我,或者只是用于套接字通信.
编辑:提升:dynamic_bitset看起来很有希望.任何使用它的帮助?
如果找不到用于解析数据的通用库,请使用位域获取数据并将memcpy()转换为变量struct
.请参阅链接Bitfields.这将更加简化您的应用程序.
不要忘记包装结构.
例:
#pragma pack
include "order32.h"
struct yourfields{
#if O32_HOST_ORDER == O32_BIG_ENDIAN
unsigned int preamble:8;
unsigned int msgid:6;
unsigned data:212;
unsigned crc:24;
#else
unsigned crc:24;
unsigned data:212;
unsigned int msgid:6;
unsigned int preamble:8;
#endif
}/*__attribute__((packed)) for gcc*/;
Run Code Online (Sandbox Code Playgroud)
您可以执行一些编译时检查以确定您的计算机是使用LITTLE ENDIAN还是BIG ENDIAN格式.之后将其定义为PREPROCESSOR SYMBOL ::
//order32.h
#ifndef ORDER32_H
#define ORDER32_H
#include <limits.h>
#include <stdint.h>
#if CHAR_BIT != 8
#error "unsupported char size"
#endif
enum
{
O32_LITTLE_ENDIAN = 0x03020100ul,
O32_BIG_ENDIAN = 0x00010203ul,
O32_PDP_ENDIAN = 0x01000302ul
};
static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
{ { 0, 1, 2, 3 } };
#define O32_HOST_ORDER (o32_host_order.value)
#endif
Run Code Online (Sandbox Code Playgroud)
由于由克里斯托夫编写@ 这里
使用位域及其输出的示例程序:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <memory.h>
using namespace std;
struct bitfields{
unsigned opcode:5;
unsigned info:3;
}__attribute__((packed));
struct bitfields opcodes;
/* info: 3bits; opcode: 5bits;*/
/* 001 10001 => 0x31*/
/* 010 10010 => 0x52*/
void set_data(unsigned char data)
{
memcpy(&opcodes,&data,sizeof(data));
}
void print_data()
{
cout << opcodes.opcode << ' ' << opcodes.info << endl;
}
int main(int argc, char *argv[])
{
set_data(0x31);
print_data(); //must print 17 1 on my little-endian machine
set_data(0x52);
print_data(); //must print 18 2
cout << sizeof(opcodes); //must print 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2475 次 |
最近记录: |