objective-c - 读取 9 位、10 位或 11 位(精确) block 中的数据并在 Objective-C/C 中转换为整数

标签 objective-c c binary integer nsdata

我正在读取以无间距的 9 位二进制形式保存的测量数据,例如

101001110 001011100 001101010 101010110 100001011 等

数据来自旧的测量设备,有时,我必须大块地阅读,例如10、11 或 12 位。我将始终知道要读取的整数大小,因为文件开头有一些文件信息。

但是在 iOS/Objective-C 中,我只知道如何将二进制数据缩小到 8 位字节的大小,例如Int8、int16 等。并将这些 8 位或 16 位 block 转换为整数。

我如何以按位预定义的步骤遍历 NSData 对象?

最佳答案

您必须编写自己的反序列化器。例如:

@interface CHBinaryStream

// init with an NSData from which values will be read
- (id)initWithData:(NSData *)data;

// e.g. readBits:9 will assemble 9 bits from the data stream,
// return them in the low 9 bits of an NSUInteger. If you
// ask for more bits than an NSUInteger can store then they'll
// just drop off the end. This will also advance the read pointer
// by 9 bits
- (NSUInteger)readBits:(int)numberOfBits;

@end

和:

@implementation CHBinaryStream
{
     NSData *sourceData;
     NSUInteger readPointer;
}

- (id)initWithData:(NSData *)data
{
    self = [super init];

    if(self)
    {
        sourceData = [data retain];
    }

    return self;
}

- (void)dealloc
{
    [sourceData release], sourceData = nil;
    [super dealloc];
}

- (NSUInteger)readBit
{
    // we'll just return a stream of 0s if we
    // go past the end of the source data
    if((readPointer >> 3) >= [sourceData length]) return 0;

    // otherwise we'll read the byte at:
    //
    //    sourceData >> 3
    //
    // and return the bit at:
    //
    //    sourceData & 7
    //
    // (where for our purposes, the 0th bit in a byte
    // is the most significant)
    uint8_t sourceByte = ((uint8_t *)[sourceData bytes])[sourceData >> 3];

    sourceByte <<= sourceData&7; // the bit we want is now where the MSB was
    sourceByte >>= 7;            // the bit we want is now in the LSB
    sourceByte &= 1;             // this clears all the other bits

    /*

         Alternative: (sourceByte >> ((sourceData & 7) ^ 7))&1;

    */

    // advance the read pointer, and then return the value
    readPointer++;

    return sourceByte;
}


- (NSUInteger)readBits:(int)numberOfBits
{
     NSUInteger result = 0;

     // shift in the required number of bits;
     // since we're going to get the most significant
     // bits first, we add incoming bits in the least
     // significant location and shift upward

     while(numberOfBits--)
         result = (result << 1) | [self readBit];

     return result;
}

@end

所有未经测试,但希望是正确的。请注意,我正在计算 NSUInteger 中的位数,在 iOS 下,内存中的位数是 32 位宽,因此它可以处理的最大文件大小为 512mb。如果您想达到 2 艾字节,您可以明确使用 64 位 long。

接下来要添加的显然是一个 bool 值 getter,用于判断流是否结束。

关于objective-c - 读取 9 位、10 位或 11 位(精确) block 中的数据并在 Objective-C/C 中转换为整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9423302/

相关文章:

iphone - 如何获取用户在键盘上点击的字符?

objective-c - 在 SpriteKit 中,SKCropNode 对 SKShapeNode 没有影响

c - 使用c中的线程对矩阵中的元素求和

algorithm - 在 int 中找到第 n 个 SET 位

objective-c - UIWebView:访问操作系统图形/资源?

ios - 在 iOS 上根据 URL 生成文件名?

c - 如何将 void* 转换为 int[][3]

c - C 字符串中的子字符串替换

java - 如何创建自定义二进制协议(protocol)服务器?

matlab - MATLAB 中的二进制数组