独自のデシリアライザを作成する必要があります。たとえば、次のように
@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のビットを数えていることに注目してください。NSUIntegerはメモリから32ビット幅でiOS上にあるため、対処できる最大ファイルサイズは512MBです。 2エクサバイトに移動したい場合は、64ビットのlong longを明示的に使用できます。
次に明らかに追加されるのは、ストリームが終了したかどうかを示すブールゲッターです。
[bithacksページ](http://graphics.stanford.edu/~seander/bithacks.html)のルーチンのほとんどは通常のサイズの数字用に設計されていますが、近い将来、平均的なプログラマーよりも多くのコードを必要とし、このガイドはおそらくあなたの心を暖かくします。 – sarnold
ビットシフトと慎重にあなたがどこにいるのかを追跡する以外に簡単な方法はありません –
これは質問に値するだけではありません。つまり、C言語ではファイル全体を(通常は8ビット長の)文字全体の倍数としてしか読み込むことができないので、あまりできることはありません。 –