THRIFT-2905 Cocoa compiler should have option to produce "modern" Objective-C
Client: Cocoa (ObjectiveC & Swift)
Author: Kevin Wooten <kevin@wooten.com>
This closes #539
diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.m b/lib/cocoa/src/protocol/TBinaryProtocol.m
index 847c723..1f9e57a 100644
--- a/lib/cocoa/src/protocol/TBinaryProtocol.m
+++ b/lib/cocoa/src/protocol/TBinaryProtocol.m
@@ -18,63 +18,20 @@
*/
#import "TBinaryProtocol.h"
-#import "TProtocolException.h"
-#import "TObjective-C.h"
+#import "TProtocolError.h"
-/* In the modern protocol, version is stored in the high half of an int32.
- * The low half contains type info. */
-static const uint16_t VERSION_1 = 0x8001;
-NS_INLINE size_t
-CheckedCastInt32ToSizeT(int32_t size)
-{
- if (size < 0) {
- NSString *reason = [NSString stringWithFormat:
- @"%s: refusing to read data with negative size: %"PRId32,
- __func__, size];
- @throw [TProtocolException
- exceptionWithName: @"TProtocolException"
- reason: reason];
- }
- size_t checkedSize = (size_t)size;
- return checkedSize;
-}
+static SInt32 VERSION_1 = 0x80010000;
+static SInt32 VERSION_MASK = 0xffff0000;
-NS_INLINE int32_t
-CheckedCastSizeTToInt32(size_t size)
-{
- if (size > INT32_MAX) {
- NSString *reason = [NSString stringWithFormat:
- @"%s: data size exceeds values representable by a 32-bit signed integer: %zu",
- __func__, size];
- @throw [TProtocolException
- exceptionWithName: @"TProtocolException"
- reason: reason];
- }
- int32_t checkedSize = (int32_t)size;
- return checkedSize;
-}
-NS_INLINE uint8_t
-CheckedCastIntToUInt8(int size)
-{
- if (size > UINT8_MAX) {
- NSString *reason = [NSString stringWithFormat:
- @"%s: data size exceeds values representable by a 8-bit unsigned integer: %d",
- __func__, size];
- @throw [TProtocolException
- exceptionWithName: @"TProtocolException"
- reason: reason];
- }
- uint8_t checkedSize = (uint8_t)size;
- return checkedSize;
-}
+static TBinaryProtocolFactory *gSharedFactory = nil;
-static TBinaryProtocolFactory * gSharedFactory = nil;
@implementation TBinaryProtocolFactory
-+ (TBinaryProtocolFactory *) sharedFactory {
++(TBinaryProtocolFactory *) sharedFactory
+{
if (gSharedFactory == nil) {
gSharedFactory = [[TBinaryProtocolFactory alloc] init];
}
@@ -82,363 +39,553 @@
return gSharedFactory;
}
-- (TBinaryProtocol *) newProtocolOnTransport: (id <TTransport>) transport {
- return [[TBinaryProtocol alloc] initWithTransport: transport];
+-(NSString *) protocolName
+{
+ return @"binary";
+}
+
+-(TBinaryProtocol *) newProtocolOnTransport:(id <TTransport>)transport
+{
+ return [[TBinaryProtocol alloc] initWithTransport:transport];
}
@end
+@interface TBinaryProtocol ()
+
+@property(strong, nonatomic) id <TTransport> transport;
+
+@property(assign, nonatomic) BOOL strictRead;
+@property(assign, nonatomic) BOOL strictWrite;
+
+@property(strong, nonatomic) NSString *currentMessageName;
+@property(strong, nonatomic) NSString *currentFieldName;
+
+@end
+
@implementation TBinaryProtocol
-- (id) initWithTransport: (id <TTransport>) transport
+-(id) initWithTransport:(id <TTransport>)aTransport
{
- return [self initWithTransport: transport strictRead: NO strictWrite: YES];
+ return [self initWithTransport:aTransport strictRead:NO strictWrite:YES];
}
-- (id) initWithTransport: (id <TTransport>) transport
- strictRead: (BOOL) strictRead
- strictWrite: (BOOL) strictWrite
+-(id) initWithTransport:(id <TTransport>)transport
+ strictRead:(BOOL)strictRead
+ strictWrite:(BOOL)strictWrite
{
self = [super init];
- mTransport = [transport retain_stub];
- mStrictRead = strictRead;
- mStrictWrite = strictWrite;
+ if (self) {
+ _transport = transport;
+ _strictRead = strictRead;
+ _strictWrite = strictWrite;
+ }
return self;
}
-
-- (int32_t) messageSizeLimit
+-(id <TTransport>) transport
{
- return mMessageSizeLimit;
+ return _transport;
}
-
-- (void) setMessageSizeLimit: (int32_t) sizeLimit
+-(NSString *) readStringBody:(int)size error:(NSError **)error
{
- mMessageSizeLimit = sizeLimit;
-}
-
-
-- (void) dealloc
-{
- [mTransport release_stub];
- [super dealloc_stub];
-}
-
-
-- (id <TTransport>) transport
-{
- return mTransport;
-}
-
-
-- (NSString *) readStringBody: (int) rawSize
-{
- size_t size = CheckedCastInt32ToSizeT(rawSize);
- char * buffer = malloc(size+1);
- if (!buffer) {
- @throw [TProtocolException exceptionWithName: @"TProtocolException"
- reason: [NSString stringWithFormat: @"Unable to allocate memory in %s, size: %zu",
- __PRETTY_FUNCTION__,
- size]];;
+ NSMutableData *data = [NSMutableData dataWithLength:size];
+ if (!data) {
+ PROTOCOL_ERROR(nil, Unknown, @"Unable to allocate %d bytes", size);
}
- [mTransport readAll: (uint8_t *) buffer offset: 0 length: size];
- buffer[size] = 0;
- NSString * result = [NSString stringWithUTF8String: buffer];
- free(buffer);
- return result;
+
+ if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(nil, error, @"Transport read failed");
+ }
+
+ return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
-- (void) readMessageBeginReturningName: (NSString **) name
- type: (int *) type
- sequenceID: (int *) sequenceID
+-(BOOL) readMessageBeginReturningName:(NSString **)name
+ type:(SInt32 *)type
+ sequenceID:(SInt32 *)sequenceID
+ error:(NSError *__autoreleasing *)error
{
- int32_t size = [self readI32];
+ SInt32 size;
+ if (![self readI32:&size error:error]) {
+ return NO;
+ }
+ ;
+
if (size < 0) {
- /* Version (unsigned) is stored in the high halfword. */
- uint16_t version = (size >> 16) & 0xFFFF;
+ int version = size & VERSION_MASK;
if (version != VERSION_1) {
- NSString *reason = [NSString stringWithFormat:
- @"%s: Expected version %"PRIu16", instead found: %"PRIu16,
- __func__, VERSION_1, version];
- @throw [TProtocolException exceptionWithName: @"TProtocolException"
- reason: reason];
+ PROTOCOL_ERROR(NO, BadVersion, @"Bad message version");
}
if (type != NULL) {
*type = size & 0x00FF;
}
- NSString * messageName = [self readString];
+ NSString *messageName;
+ if (![self readString:&messageName error:error]) {
+ return NO;
+ }
+ if (name != nil) {
+ *name = messageName;
+ }
+ }
+ else {
+
+ if (_strictRead) {
+ PROTOCOL_ERROR(NO, InvalidData, @"Missing message version, old client?");
+ }
+
+ if (_messageSizeLimit > 0 && size > _messageSizeLimit) {
+ PROTOCOL_ERROR(NO, SizeLimit, @"Message exceeeds size limit of %d", (int)size);
+ }
+
+ NSString *messageName = [self readStringBody:size error:error];
+ if (!messageName) {
+ return NO;
+ }
+
if (name != NULL) {
*name = messageName;
}
- int seqID = [self readI32];
- if (sequenceID != NULL) {
- *sequenceID = seqID;
+
+ UInt8 messageType;
+ if (![self readByte:&messageType error:error]) {
+ return NO;
}
- } else {
- if (mStrictRead) {
- @throw [TProtocolException exceptionWithName: @"TProtocolException"
- reason: @"Missing version in readMessageBegin, old client?"];
- }
- if ([self messageSizeLimit] > 0 && size > [self messageSizeLimit]) {
- @throw [TProtocolException exceptionWithName: @"TProtocolException"
- reason: [NSString stringWithFormat: @"Message too big. Size limit is: %d Message size is: %d",
- mMessageSizeLimit,
- size]];
- }
- NSString * messageName = [self readStringBody: size];
- if (name != NULL) {
- *name = messageName;
- }
- int messageType = [self readByte];
+
if (type != NULL) {
*type = messageType;
}
- int seqID = [self readI32];
- if (sequenceID != NULL) {
- *sequenceID = seqID;
- }
}
+
+ SInt32 seqID;
+ if (![self readI32:&seqID error:error]) {
+ return NO;
+ }
+ if (sequenceID != NULL) {
+ *sequenceID = seqID;
+ }
+
+ return YES;
}
-- (void) readMessageEnd {}
-
-
-- (void) readStructBeginReturningName: (NSString **) name
+-(BOOL) readMessageEnd:(NSError *__autoreleasing *)error
{
- if (name != NULL) {
- *name = nil;
- }
+ return YES;
}
-- (void) readStructEnd {}
-
-
-- (void) readFieldBeginReturningName: (NSString **) name
- type: (int *) fieldType
- fieldID: (int *) fieldID
+-(BOOL) readStructBeginReturningName:(NSString *__autoreleasing *)name error:(NSError *__autoreleasing *)error
{
- if (name != NULL) {
+ return YES;
+}
+
+
+-(BOOL) readStructEnd:(NSError *__autoreleasing *)error
+{
+ return YES;
+}
+
+
+-(BOOL) readFieldBeginReturningName:(NSString *__autoreleasing *)name
+ type:(SInt32 *)fieldType
+ fieldID:(SInt32 *)fieldID
+ error:(NSError *__autoreleasing *)error
+{
+ if (name != nil) {
*name = nil;
}
- int ft = [self readByte];
+
+ UInt8 ft;
+ if (![self readByte:&ft error:error]) {
+ return NO;
+ }
if (fieldType != NULL) {
*fieldType = ft;
}
- if (ft != TType_STOP) {
- int fid = [self readI16];
+ if (ft != TTypeSTOP) {
+ SInt16 fid;
+ if (![self readI16:&fid error:error]) {
+ return NO;
+ }
if (fieldID != NULL) {
*fieldID = fid;
}
}
+ return YES;
}
-- (void) readFieldEnd {}
-
-
-- (int32_t) readI32
+-(BOOL) readFieldEnd:(NSError *__autoreleasing *)error
{
- uint8_t i32rd[4];
- [mTransport readAll: i32rd offset: 0 length: 4];
- return
+ return YES;
+}
+
+
+-(BOOL) readString:(NSString *__autoreleasing *)value error:(NSError *__autoreleasing *)error
+{
+ SInt32 size;
+ if (![self readI32:&size error:error]) {
+ return NO;
+ }
+
+ NSString *string = [self readStringBody:size error:error];
+ if (!string) {
+ return NO;
+ }
+
+ *value = string;
+
+ return YES;
+}
+
+
+-(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error
+{
+ UInt8 byte;
+ if (![self readByte:&byte error:error]) {
+ return NO;
+ }
+
+ *value = byte == 1;
+
+ return YES;
+}
+
+
+-(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error
+{
+ UInt8 buff[1];
+ if (![_transport readAll:buff offset:0 length:1 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
+ }
+
+ *value = buff[0];
+
+ return YES;
+}
+
+
+-(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error
+{
+ UInt8 buff[2];
+ if (![_transport readAll:buff offset:0 length:2 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
+ }
+
+ *value =
+ ((SInt16)(buff[0] & 0xff) << 8) |
+ ((SInt16)(buff[1] & 0xff));
+
+ return YES;
+}
+
+
+-(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error
+{
+ UInt8 i32rd[4];
+ if (![_transport readAll:i32rd offset:0 length:4 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
+ }
+
+ *value =
((i32rd[0] & 0xff) << 24) |
((i32rd[1] & 0xff) << 16) |
((i32rd[2] & 0xff) << 8) |
((i32rd[3] & 0xff));
+
+ return YES;
}
-- (NSString *) readString
+-(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error
{
- int32_t size = [self readI32];
- return [self readStringBody: size];
+ UInt8 buff[8];
+ if (![_transport readAll:buff offset:0 length:8 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
+ }
+
+ *value =
+ ((SInt64)(buff[0] & 0xff) << 56) |
+ ((SInt64)(buff[1] & 0xff) << 48) |
+ ((SInt64)(buff[2] & 0xff) << 40) |
+ ((SInt64)(buff[3] & 0xff) << 32) |
+ ((SInt64)(buff[4] & 0xff) << 24) |
+ ((SInt64)(buff[5] & 0xff) << 16) |
+ ((SInt64)(buff[6] & 0xff) << 8) |
+ ((SInt64)(buff[7] & 0xff));
+
+ return YES;
}
-- (BOOL) readBool
-{
- return [self readByte] == 1;
-}
-
-- (uint8_t) readByte
-{
- uint8_t myByte;
- [mTransport readAll: &myByte offset: 0 length: 1];
- return myByte;
-}
-
-- (short) readI16
-{
- uint8_t buff[2];
- [mTransport readAll: buff offset: 0 length: 2];
- return (short)
- (((buff[0] & 0xff) << 8) |
- ((buff[1] & 0xff)));
-}
-
-- (int64_t) readI64
-{
- uint8_t i64rd[8];
- [mTransport readAll: i64rd offset: 0 length: 8];
- return
- ((int64_t)(i64rd[0] & 0xff) << 56) |
- ((int64_t)(i64rd[1] & 0xff) << 48) |
- ((int64_t)(i64rd[2] & 0xff) << 40) |
- ((int64_t)(i64rd[3] & 0xff) << 32) |
- ((int64_t)(i64rd[4] & 0xff) << 24) |
- ((int64_t)(i64rd[5] & 0xff) << 16) |
- ((int64_t)(i64rd[6] & 0xff) << 8) |
- ((int64_t)(i64rd[7] & 0xff));
-}
-
-- (double) readDouble
+-(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error
{
// FIXME - will this get us into trouble on PowerPC?
- int64_t ieee754 = [self readI64];
- return *((double *) &ieee754);
+ return [self readI64:(SInt64 *)value error:error];
}
-- (NSData *) readBinary
+-(BOOL) readBinary:(NSData *__autoreleasing *)value error:(NSError *__autoreleasing *)error
{
- int32_t size = [self readI32];
- size_t binarySize = CheckedCastInt32ToSizeT(size);
- uint8_t * buff = malloc(binarySize);
- if (buff == NULL) {
- @throw [TProtocolException
- exceptionWithName: @"TProtocolException"
- reason: [NSString stringWithFormat: @"Out of memory. Unable to allocate %d bytes trying to read binary data.",
- size]];
+ SInt32 size;
+ if (![self readI32:&size error:error]) {
+ return NO;
}
- [mTransport readAll: buff offset: 0 length: binarySize];
- return [NSData dataWithBytesNoCopy: buff length: binarySize];
+
+ NSMutableData *data = [NSMutableData dataWithLength:size];
+ if (!data) {
+ PROTOCOL_ERROR(NO, Unknown, @"Unable to allocate %d bytes", (int)size);
+ }
+
+ if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
+ }
+
+ *value = data;
+
+ return YES;
}
-- (void) readMapBeginReturningKeyType: (int *) keyType
- valueType: (int *) valueType
- size: (int *) size
+-(BOOL) readMapBeginReturningKeyType:(SInt32 *)keyType
+ valueType:(SInt32 *)valueType
+ size:(SInt32 *)size
+ error:(NSError *__autoreleasing *)error
{
- int kt = [self readByte];
- int vt = [self readByte];
- int s = [self readI32];
+ UInt8 kt;
+ if (![self readByte:&kt error:error]) {
+ return NO;
+ }
+
+ UInt8 vt;
+ if (![self readByte:&vt error:error]) {
+ return NO;
+ }
+
+ SInt32 s;
+ if (![self readI32:&s error:error]) {
+ return NO;
+ }
+
if (keyType != NULL) {
*keyType = kt;
}
+
if (valueType != NULL) {
*valueType = vt;
}
+
if (size != NULL) {
*size = s;
}
+
+ return YES;
}
-- (void) readMapEnd {}
-
-- (void) readSetBeginReturningElementType: (int *) elementType
- size: (int *) size
+-(BOOL) readMapEnd:(NSError *__autoreleasing *)error
{
- int et = [self readByte];
- int s = [self readI32];
+ return YES;
+}
+
+
+-(BOOL) readSetBeginReturningElementType:(SInt32 *)elementType
+ size:(SInt32 *)size
+ error:(NSError *__autoreleasing *)error
+{
+ UInt8 et;
+ if (![self readByte:&et error:error]) {
+ return NO;
+ }
+
+ SInt32 s;
+ if (![self readI32:&s error:error]) {
+ return NO;
+ }
+
if (elementType != NULL) {
*elementType = et;
}
+
if (size != NULL) {
*size = s;
}
+
+ return YES;
}
-- (void) readSetEnd {}
-
-
-- (void) readListBeginReturningElementType: (int *) elementType
- size: (int *) size
+-(BOOL) readSetEnd:(NSError *__autoreleasing *)error
{
- int et = [self readByte];
- int s = [self readI32];
+ return YES;
+}
+
+
+-(BOOL) readListBeginReturningElementType:(SInt32 *)elementType
+ size:(SInt32 *)size
+ error:(NSError *__autoreleasing *)error
+{
+ UInt8 et;
+ if (![self readByte:&et error:error]) {
+ return NO;
+ }
+
+ SInt32 s;
+ if (![self readI32:&s error:error]) {
+ return NO;
+ }
+
if (elementType != NULL) {
*elementType = et;
}
+
if (size != NULL) {
*size = s;
}
+
+ return YES;
}
-- (void) readListEnd {}
-
-
-- (void) writeByte: (uint8_t) value
+-(BOOL) readListEnd:(NSError *__autoreleasing *)error
{
- [mTransport write: &value offset: 0 length: 1];
+ return YES;
}
-- (void) writeMessageBeginWithName: (NSString *) name
- type: (int) messageType
- sequenceID: (int) sequenceID
+
+-(BOOL) writeMessageBeginWithName:(NSString *)name
+ type:(SInt32)messageType
+ sequenceID:(SInt32)sequenceID
+ error:(NSError *__autoreleasing *)error
{
- if (mStrictWrite) {
- int version = (VERSION_1 << 16) | messageType;
- [self writeI32: version];
- [self writeString: name];
- [self writeI32: sequenceID];
- } else {
- [self writeString: name];
- [self writeByte: CheckedCastIntToUInt8(messageType)];
- [self writeI32: sequenceID];
+ if (_strictWrite) {
+
+ int version = VERSION_1 | messageType;
+
+ if (![self writeI32:version error:error]) {
+ return NO;
+ }
+
+ if (![self writeString:name error:error]) {
+ return NO;
+ }
+
+ if (![self writeI32:sequenceID error:error]) {
+ return NO;
+ }
}
+ else {
+
+ if (![self writeString:name error:error]) {
+ return NO;
+ }
+
+ if (![self writeByte:messageType error:error]) {
+ return NO;
+ }
+
+ if (![self writeI32:sequenceID error:error]) {
+ return NO;
+ }
+ }
+
+ _currentMessageName = name;
+
+ return YES;
}
-- (void) writeMessageEnd {}
-
-
-- (void) writeStructBeginWithName: (NSString *) name {}
-
-
-- (void) writeStructEnd {}
-
-
-- (void) writeFieldBeginWithName: (NSString *) name
- type: (int) fieldType
- fieldID: (int) fieldID
+-(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error
{
- [self writeByte: CheckedCastIntToUInt8(fieldType)];
- [self writeI16: CheckedCastIntToUInt8(fieldID)];
+ _currentMessageName = nil;
+ return YES;
}
-- (void) writeI32: (int32_t) value
+-(BOOL) writeStructBeginWithName:(NSString *)name
+ error:(NSError *__autoreleasing *)error
{
- uint8_t buff[4];
+ return YES;
+}
+
+
+-(BOOL) writeStructEnd:(NSError *__autoreleasing *)error
+{
+ return YES;
+}
+
+
+-(BOOL) writeFieldBeginWithName:(NSString *)name
+ type:(SInt32)fieldType
+ fieldID:(SInt32)fieldID
+ error:(NSError *__autoreleasing *)error
+{
+ if (![self writeByte:fieldType error:error]) {
+ return NO;
+ }
+
+ if (![self writeI16:fieldID error:error]) {
+ return NO;
+ }
+
+ return YES;
+}
+
+
+-(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error
+{
+ return [self writeByte:(value ? 1 : 0) error:error];
+}
+
+
+-(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error
+{
+ if (![_transport write:&value offset:0 length:1 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
+ }
+ return YES;
+}
+
+
+-(BOOL) writeI16:(short)value error:(NSError *__autoreleasing *)error
+{
+ UInt8 buff[2];
+ buff[0] = 0xff & (value >> 8);
+ buff[1] = 0xff & value;
+
+ if (![_transport write:buff offset:0 length:2 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
+ }
+
+ return YES;
+}
+
+
+-(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error
+{
+ UInt8 buff[4];
buff[0] = 0xFF & (value >> 24);
buff[1] = 0xFF & (value >> 16);
buff[2] = 0xFF & (value >> 8);
buff[3] = 0xFF & value;
- [mTransport write: buff offset: 0 length: 4];
-}
-- (void) writeI16: (short) value
-{
- uint8_t buff[2];
- buff[0] = 0xff & (value >> 8);
- buff[1] = 0xff & value;
- [mTransport write: buff offset: 0 length: 2];
+ if (![_transport write:buff offset:0 length:4 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
+ }
+
+ return YES;
}
-- (void) writeI64: (int64_t) value
+-(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error
{
- uint8_t buff[8];
+ UInt8 buff[8];
buff[0] = 0xFF & (value >> 56);
buff[1] = 0xFF & (value >> 48);
buff[2] = 0xFF & (value >> 40);
@@ -447,84 +594,147 @@
buff[5] = 0xFF & (value >> 16);
buff[6] = 0xFF & (value >> 8);
buff[7] = 0xFF & value;
- [mTransport write: buff offset: 0 length: 8];
+
+ if (![_transport write:buff offset:0 length:8 error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
+ }
+
+ return YES;
}
-- (void) writeDouble: (double) value
+
+-(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error
{
- // spit out IEEE 754 bits - FIXME - will this get us in trouble on
- // PowerPC?
- [self writeI64: *((int64_t *) &value)];
+ // FIXME - will this get us in trouble on PowerPC?
+ if (![self writeI64:*(SInt64 *)&value error:error]) {
+ return NO;
+ }
+
+ return YES;
}
-- (void) writeString: (NSString *) value
+-(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error
{
if (value != nil) {
- const char * utf8Bytes = [value UTF8String];
- size_t length = strlen(utf8Bytes);
- int32_t size = CheckedCastSizeTToInt32(length);
- [self writeI32: size];
- [mTransport write: (uint8_t *) utf8Bytes offset: 0 length: length];
- } else {
+
+ const char *utf8Bytes = [value UTF8String];
+
+ SInt32 length = (SInt32)strlen(utf8Bytes);
+ if (![self writeI32:length error:error]) {
+ return NO;
+ }
+
+ if (![_transport write:(UInt8 *)utf8Bytes offset:0 length:(int)length error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
+ }
+
+ }
+ else {
+
// instead of crashing when we get null, let's write out a zero
// length string
- [self writeI32: 0];
+ if (![self writeI32:0 error:error]) {
+ return NO;
+ }
+
}
+
+ return YES;
}
-- (void) writeBinary: (NSData *) data
+-(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error
{
- int32_t size = CheckedCastSizeTToInt32([data length]);
- [self writeI32: size];
- [mTransport write: [data bytes] offset: 0 length: [data length]];
-}
+ if (![self writeI32:(SInt32)data.length error:error]) {
+ return NO;
+ }
-- (void) writeFieldStop
-{
- [self writeByte: TType_STOP];
+ if (![_transport write:data.bytes offset:0 length:(UInt32)data.length error:error]) {
+ PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
+ }
+
+ return YES;
}
-- (void) writeFieldEnd {}
-
-
-- (void) writeMapBeginWithKeyType: (int) keyType
- valueType: (int) valueType
- size: (int) size
+-(BOOL) writeFieldStop:(NSError *__autoreleasing *)error
{
- [self writeByte: CheckedCastIntToUInt8(keyType)];
- [self writeByte: CheckedCastIntToUInt8(valueType)];
- [self writeI32: size];
+ if (![self writeByte:TTypeSTOP error:error]) {
+ return NO;
+ }
+
+ return YES;
}
-- (void) writeMapEnd {}
-
-- (void) writeSetBeginWithElementType: (int) elementType
- size: (int) size
+-(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error
{
- [self writeByte: CheckedCastIntToUInt8(elementType)];
- [self writeI32: size];
+ return YES;
}
-- (void) writeSetEnd {}
-
-- (void) writeListBeginWithElementType: (int) elementType
- size: (int) size
+-(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
+ valueType:(SInt32)valueType
+ size:(SInt32)size
+ error:(NSError *__autoreleasing *)error
{
- [self writeByte: CheckedCastIntToUInt8(elementType)];
- [self writeI32: size];
+ if (![self writeByte:keyType error:error]) {
+ return NO;
+ }
+ if (![self writeByte:valueType error:error]) {
+ return NO;
+ }
+ if (![self writeI32:(int)size error:error]) {
+ return NO;
+ }
+ return YES;
}
-- (void) writeListEnd {}
-
-- (void) writeBool: (BOOL) value
+-(BOOL) writeMapEnd:(NSError *__autoreleasing *)error
{
- [self writeByte: (value ? 1 : 0)];
+ return YES;
+}
+
+
+-(BOOL) writeSetBeginWithElementType:(SInt32)elementType
+ size:(SInt32)size
+ error:(NSError *__autoreleasing *)error
+{
+ if (![self writeByte:elementType error:error]) {
+ return NO;
+ }
+ if (![self writeI32:size error:error]) {
+ return NO;
+ }
+ return YES;
+}
+
+
+-(BOOL) writeSetEnd:(NSError *__autoreleasing *)error
+{
+ return YES;
+}
+
+
+-(BOOL) writeListBeginWithElementType:(SInt32)elementType
+ size:(SInt32)size
+ error:(NSError *__autoreleasing *)error
+{
+ if (![self writeByte:elementType error:error]) {
+ return NO;
+ }
+ if (![self writeI32:size error:error]) {
+ return NO;
+ }
+ return YES;
+}
+
+
+-(BOOL) writeListEnd:(NSError *__autoreleasing *)error
+{
+ return YES;
}
@end