【问题标题】: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;

我正在解析的大多数其他特征都是单一类型,uint8uint32,等等。

如何遍历字节并将每个单独的特征解析为原生类型或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

标签: ios core-bluetooth


【解决方案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

【讨论】:

    猜你喜欢
    • 2011-01-20
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2016-07-23
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    相关资源
    最近更新 更多