Iterate over byte array to parse out individual lengths

霸气de小男生 提交于 2019-12-25 04:04:48

问题


I am reading data off of a hardware device through Core Bluetooth (BLE). One of the charecteristics I am reading is a struct compressed down to a single value. The struct as programmed to the board looks like this:

typedef struct
{
  uint8          id;
  uint32        dur;
  uint16        dis;
} record;

Most of the other characteristics I am parsing are of a single type, uint8, uint32, so on.

How can I loop through the bytes and parse each individual characteristic either to native type or an NSString? Is there a way to iterate over the bytes or substring the NSData object?

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
    }

回答1:


You can do something like this to create an instance of your struct from the data.

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



回答2:


Instead of iterating across your data, and if you want to pull out individual values you use subDataWithRange of the Characteristic NSData.

Something like...

    //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);

A good description of the approach is here

And an approach for endianness is here

I am also not sure if you are doing any Structure Packing



来源:https://stackoverflow.com/questions/28773508/iterate-over-byte-array-to-parse-out-individual-lengths

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!