Created
November 19, 2013 22:42
-
-
Save nevyn/7553896 to your computer and use it in GitHub Desktop.
Simple helpers for working with common data types on NSData-backed input and output streams.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
/** @category TCInputStream | |
@abstract Reads Big Endian data in convenient sizes | |
*/ | |
@interface NSInputStream (TCInputStream) | |
- (int8_t)readByte; | |
- (uint16_t)readShort; | |
- (uint32_t)readInt; | |
- (uint64_t)readLongLong; | |
- (NSString*)readUTF8StringWithLengthSize:(size_t)lengthSize; | |
- (NSData*)readBytes:(size_t)byteCount; | |
@end | |
/** @category TCOutputStream | |
@abstract Writes Big Endian data in convenient sizes | |
*/ | |
@interface NSOutputStream (TCOutputStream) | |
- (void)writeByte:(uint8_t)number; | |
- (void)writeShort:(uint16_t)number; | |
- (void)writeInt:(uint32_t)number; | |
- (void)writeLongLong:(uint64_t)number; | |
- (void)writeUTF8String:(NSString*)string withLengthSize:(size_t)lengthSize; | |
- (void)writeData:(NSData*)data; | |
- (NSData*)tc_data; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "TCStream.h" | |
@implementation NSInputStream (TCInputStream) | |
- (int8_t)readByte | |
{ | |
uint16_t number; | |
size_t lengthRead = [self read:(uint8_t*)&number maxLength:1]; | |
NSAssert(lengthRead == 1, @"Missing data in stream"); | |
return number; | |
} | |
- (uint16_t)readShort | |
{ | |
uint16_t number; | |
size_t lengthRead = [self read:(uint8_t*)&number maxLength:2]; | |
NSAssert(lengthRead == 2, @"Missing data in stream"); | |
return NSSwapBigShortToHost(number); | |
} | |
- (uint32_t)readInt | |
{ | |
uint32_t number; | |
size_t lengthRead = [self read:(uint8_t*)&number maxLength:4]; | |
NSAssert(lengthRead == 4, @"Missing data in stream"); | |
return NSSwapBigIntToHost(number); | |
} | |
- (uint64_t)readLongLong | |
{ | |
uint64_t number; | |
size_t lengthRead = [self read:(uint8_t*)&number maxLength:8]; | |
NSAssert(lengthRead == 8, @"Missing data in stream"); | |
return NSSwapBigLongLongToHost(number); | |
} | |
- (NSString*)readUTF8StringWithLengthSize:(size_t)lengthSize | |
{ | |
NSAssert(lengthSize == 1 || lengthSize == 2 || lengthSize == 4, @"Invalid lengthSize"); | |
uint32_t length = lengthSize == 1 ? [self readByte] : | |
lengthSize == 2 ? [self readShort] : | |
/*lengthSize == 4 ?*/[self readInt]; | |
NSData *stringData = [self readBytes:length]; | |
return [[NSString alloc] initWithData:stringData encoding:NSUTF8StringEncoding]; | |
} | |
- (NSData*)readBytes:(size_t)byteCount | |
{ | |
NSMutableData *data = [NSMutableData dataWithLength:byteCount]; | |
size_t lengthRead = [self read:data.mutableBytes maxLength:byteCount]; | |
NSAssert(lengthRead == byteCount, @"Missing data in stream"); | |
return data; | |
} | |
@end | |
@implementation NSOutputStream (TCOutputStream) | |
- (void)writeByte:(uint8_t)number | |
{ | |
size_t lengthWritten = [self write:(uint8_t*)&number maxLength:1]; | |
NSAssert(lengthWritten == 1, @"Stream ended too early"); | |
} | |
- (void)writeShort:(uint16_t)number | |
{ | |
number = NSSwapHostShortToBig(number); | |
size_t lengthWritten = [self write:(uint8_t*)&number maxLength:2]; | |
NSAssert(lengthWritten == 2, @"Stream ended too early"); | |
} | |
- (void)writeInt:(uint32_t)number | |
{ | |
number = NSSwapHostIntToBig(number); | |
size_t lengthWritten = [self write:(uint8_t*)&number maxLength:4]; | |
NSAssert(lengthWritten == 4, @"Stream ended too early. %@ %@", self, [self streamError]); | |
} | |
- (void)writeLongLong:(uint64_t)number | |
{ | |
number = NSSwapHostLongLongToBig(number); | |
size_t lengthWritten = [self write:(uint8_t*)&number maxLength:8]; | |
NSAssert(lengthWritten == 8, @"Stream ended too early"); | |
} | |
- (void)writeUTF8String:(NSString*)string withLengthSize:(size_t)lengthSize | |
{ | |
NSAssert(lengthSize == 1 || lengthSize == 2 || lengthSize == 4, @"Invalid lengthSize"); | |
NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding]; | |
uint32_t length = (uint32_t)stringData.length; | |
if(lengthSize == 1) [self writeByte:length]; | |
else if(lengthSize == 2) [self writeShort:length]; | |
else if(lengthSize == 4) [self writeInt:length]; | |
size_t lengthWritten = [self write:stringData.bytes maxLength:length]; | |
NSAssert(length == lengthWritten, @"Stream ended too early"); | |
} | |
- (void)writeData:(NSData*)data | |
{ | |
[self write:data.bytes maxLength:data.length]; | |
} | |
- (NSData*)tc_data | |
{ | |
return [self propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment