遍历字节数组以解析出各个长度
Posted
技术标签:
【中文标题】遍历字节数组以解析出各个长度【英文标题】:Iterate over byte array to parse out individual lengths 【发布时间】:2015-02-27 20:15:31 【问题描述】:我正在通过核心蓝牙 (BLE) 从硬件设备读取数据。我正在阅读的特征之一是将结构压缩为单个值。编程到板上的结构如下所示:
typedef struct
uint8 id;
uint32 dur;
uint16 dis;
record;
我正在解析的大多数其他特征都是单一类型,uint8
、uint32
,等等。
如何遍历字节并将每个单独的特征解析为原生类型或NSString
?有没有办法遍历 NSData
对象的字节或子串?
NSData *data = [characteristic value]; // characteristic is of type CBCharacteristic
NSUInteger len = data.length;
Byte *bytes = (Byte *)[data bytes];
for (Byte in bytes) // no fast enumeration here, but the general intention is to iterate byte by byte
// TODO: parse out uint8
// TODO: parse out uint32
// TODO: parse out uint16
【问题讨论】:
如果结构始终是固定布局,那么只需直接访问字节 - [data bytes][0] 将是您的 id。 [data bytes[1]]-[data bytes[4] will be dur and bytes 5 & 6 will be dis 【参考方案1】:您可以执行这样的操作来从数据中创建结构的实例。
typedef struct
uint8 id;
uint32 dur;
uint16 dis;
record;
@implementation YourClass (DataRetrieval)
- (void)process:(CBCharacteristic *)characteristic
record r;
[[characteristic value] getBytes:&r length:sizeof(r)];
// r.id
// r.dur
// r.dis
@end
【讨论】:
结构存在于我正在连接的板子或设备上。它作为单个数据对象被推送到蓝牙上。该数据不会自动解析为 NSObject 或结构,映射必须手动完成,这就是我尝试迭代数据对象的原因。 如果你打算解析它,你必须知道你得到的数据的格式,对吧?只需在代码中定义一个与该格式匹配的结构。 也许他缺少的知识是他在示例中使用的结构将在 Objective-C 中按原样工作。 @ilrugel 答案有点不清楚,但在 Objective-C 中,您也可以使用 C 结构。只需在 ios 应用程序的代码中定义相同的结构record
并像在 dan 的回答中一样使用它:在 NSData
的实例上调用 getBytes:length
后,record
结构中的所有字段都将被分配正确的值.【参考方案2】:
而不是遍历您的数据,如果您想提取单个值,您可以使用 Characteristic NSData 的 subDataWithRange。
类似...
//create test data as an example.
unsigned char bytes[STRUCT_SIZE] = 0x01, 0x00, 0x0, 0x00, 0x02, 0x00, 0x03;
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
//assume that you have a packed structure and endianess is correct
//[0] = id
//[1] = dur
//[2] = dur
//[3] = dur
//[4] = dur
//[5] = dis
//[6] = dis
assert(STRUCT_SIZE == [data length]);
uint8_t idu = *( uint8_t*)[[data subdataWithRange:NSMakeRange(0, 1)] bytes];
uint32_t dur = *(uint32_t*)[[data subdataWithRange:NSMakeRange(1, 4)] bytes];
uint16_t dis = *(uint16_t*)[[data subdataWithRange:NSMakeRange(5, 2)] bytes];
assert(1 == idu);
assert(2 == dur);
assert(3 == dis);
approach is here的一个很好的描述
还有endianness is here的方法
我也不确定你是不是doing any Structure Packing
【讨论】:
以上是关于遍历字节数组以解析出各个长度的主要内容,如果未能解决你的问题,请参考以下文章
图中是把二十个字节的数组分成正数组和负数组,并分别计算两个数组中数据的个数的汇编程序。请画出程序流