Вы должны написать свой собственный десериализатор.Например:
@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, который из памяти имеет 32-битную ширину под iOS, поэтому максимальный размер файла, с которым он может справиться, составляет 512 МБ.Вы можете явно использовать длину 64 бита, если хотите перейти к 2 экзабайтам.
Очевидным следующим шагом, который нужно добавить, будет логический метод получения завершения потока.