http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TEnum.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TEnum.swift b/lib/cocoa/src/TEnum.swift new file mode 100644 index 0000000..562a53a --- /dev/null +++ b/lib/cocoa/src/TEnum.swift @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + +public protocol TEnum : TSerializable { + +} + +public extension TEnum { + + public static var thriftType : TType { return TType.I32 } + +}
http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TError.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TError.h b/lib/cocoa/src/TError.h new file mode 100644 index 0000000..abb72c7 --- /dev/null +++ b/lib/cocoa/src/TError.h @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#import <Foundation/Foundation.h> + + +extern NSString *TErrorDomain; http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TError.m ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TError.m b/lib/cocoa/src/TError.m new file mode 100644 index 0000000..df7f92d --- /dev/null +++ b/lib/cocoa/src/TError.m @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#import "TError.h" + + +NSString *TErrorDomain = @"TErrorDomain"; http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TException.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TException.h b/lib/cocoa/src/TException.h deleted file mode 100644 index e56f4fa..0000000 --- a/lib/cocoa/src/TException.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#import <Foundation/Foundation.h> - -@interface TException : NSException { -} - -+ (id) exceptionWithName: (NSString *) name; - -+ (id) exceptionWithName: (NSString *) name - reason: (NSString *) reason; - -+ (id) exceptionWithName: (NSString *) name - reason: (NSString *) reason - error: (NSError *) error; - -@end http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TException.m ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TException.m b/lib/cocoa/src/TException.m deleted file mode 100644 index 0160e3b..0000000 --- a/lib/cocoa/src/TException.m +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#import "TException.h" -#import "TObjective-C.h" - -@implementation TException - -+ (id) exceptionWithName: (NSString *) name -{ - return [self exceptionWithName: name reason: @"unknown" error: nil]; -} - - -+ (id) exceptionWithName: (NSString *) name - reason: (NSString *) reason -{ - return [self exceptionWithName: name reason: reason error: nil]; -} - - -+ (id) exceptionWithName: (NSString *) name - reason: (NSString *) reason - error: (NSError *) error -{ - NSDictionary * userInfo = nil; - if (error != nil) { - userInfo = [NSDictionary dictionaryWithObject: error forKey: @"error"]; - } - - return [super exceptionWithName: name - reason: reason - userInfo: userInfo]; -} - - -- (NSString *) description -{ - NSMutableString * result = [NSMutableString stringWithString: [self name]]; - [result appendFormat: @": %@", [self reason]]; - if ([self userInfo] != nil) { - [result appendFormat: @"\n userInfo = %@", [self userInfo]]; - } - - return result; -} - - -@end http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TList.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TList.swift b/lib/cocoa/src/TList.swift new file mode 100644 index 0000000..005bd81 --- /dev/null +++ b/lib/cocoa/src/TList.swift @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + + +public struct TList<Element : TSerializable> : MutableCollectionType, Hashable, ArrayLiteralConvertible, TSerializable { + + public static var thriftType : TType { return .LIST } + + typealias Storage = Array<Element> + + public typealias Index = Storage.Index + + private var storage = Storage() + + public var startIndex : Index { + return storage.startIndex + } + + public var endIndex : Index { + return storage.endIndex + } + + public subscript (position: Index) -> Element { + get { + return storage[position] + } + set { + storage[position] = newValue + } + } + + public var hashValue : Int { + let prime = 31 + var result = 1 + for element in storage { + result = prime * result + element.hashValue + } + return result + } + + public init(arrayLiteral elements: Element...) { + self.storage = Storage(storage) + } + + public init() { + self.storage = Storage() + } + + public mutating func append(newElement: Element) { + self.storage.append(newElement) + } + + public mutating func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newstorage: C) { + self.storage.appendContentsOf(newstorage) + } + + public mutating func insert(newElement: Element, atIndex index: Int) { + self.storage.insert(newElement, atIndex: index) + } + + public mutating func insertContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C, at index: Int) { + self.storage.insertContentsOf(newElements, at: index) + } + + public mutating func removeAll(keepCapacity keepCapacity: Bool = true) { + self.storage.removeAll(keepCapacity: keepCapacity) + } + + public mutating func removeAtIndex(index: Index) { + self.storage.removeAtIndex(index) + } + + public mutating func removeFirst(n: Int = 0) { + self.storage.removeFirst(n) + } + + public mutating func removeLast() -> Element { + return self.storage.removeLast() + } + + public mutating func removeRange(subRange: Range<Index>) { + self.storage.removeRange(subRange) + } + + public mutating func reserveCapacity(minimumCapacity: Int) { + self.storage.reserveCapacity(minimumCapacity) + } + + public static func readValueFromProtocol(proto: TProtocol) throws -> TList { + let (elementType, size) = try proto.readListBegin() + if elementType != Element.thriftType { + throw NSError( + domain: TProtocolErrorDomain, + code: Int(TProtocolError.InvalidData.rawValue), + userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: TProtocolExtendedError.UnexpectedType.rawValue)]) + } + var list = TList() + for _ in 0..<size { + let element = try Element.readValueFromProtocol(proto) + list.storage.append(element) + } + try proto.readListEnd() + return list + } + + public static func writeValue(value: TList, toProtocol proto: TProtocol) throws { + try proto.writeListBeginWithElementType(Element.thriftType, size: value.count) + for element in value.storage { + try Element.writeValue(element, toProtocol: proto) + } + try proto.writeListEnd() + } +} + +extension TList : CustomStringConvertible, CustomDebugStringConvertible { + + public var description : String { + return storage.description + } + + public var debugDescription : String { + return storage.debugDescription + } + +} + +public func ==<Element>(lhs: TList<Element>, rhs: TList<Element>) -> Bool { + return lhs.storage == rhs.storage +} http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TMap.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TMap.swift b/lib/cocoa/src/TMap.swift new file mode 100644 index 0000000..e96e747 --- /dev/null +++ b/lib/cocoa/src/TMap.swift @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + +public struct TMap<Key : TSerializable, Value : TSerializable> : CollectionType, DictionaryLiteralConvertible, TSerializable { + + public static var thriftType : TType { return .MAP } + + typealias Storage = Dictionary<Key, Value> + + public typealias Index = Storage.Index + + public typealias Element = Storage.Element + + private var storage : Storage + + public var startIndex : Index { + return storage.startIndex + } + + public var endIndex: Index { + return storage.endIndex + } + + public var keys: LazyMapCollection<[Key : Value], Key> { + return storage.keys + } + + public var values: LazyMapCollection<[Key : Value], Value> { + return storage.values + } + + public init() { + storage = Storage() + } + + public init(dictionaryLiteral elements: (Key, Value)...) { + storage = Storage() + for (key, value) in elements { + storage[key] = value + } + } + + public init(minimumCapacity: Int) { + storage = Storage(minimumCapacity: minimumCapacity) + } + + public subscript (position: Index) -> Element { + get { + return storage[position] + } + } + + public func indexForKey(key: Key) -> Index? { + return storage.indexForKey(key) + } + + public subscript (key: Key) -> Value? { + get { + return storage[key] + } + set { + storage[key] = newValue + } + } + + public mutating func updateValue(value: Value, forKey key: Key) -> Value? { + return updateValue(value, forKey: key) + } + + public mutating func removeAtIndex(index: DictionaryIndex<Key, Value>) -> (Key, Value) { + return removeAtIndex(index) + } + + public mutating func removeValueForKey(key: Key) -> Value? { + return storage.removeValueForKey(key) + } + + public mutating func removeAll(keepCapacity keepCapacity: Bool = false) { + storage.removeAll(keepCapacity: keepCapacity) + } + + public var hashValue : Int { + let prime = 31 + var result = 1 + for (key, value) in storage { + result = prime * result + key.hashValue + result = prime * result + value.hashValue + } + return result + } + + public static func readValueFromProtocol(proto: TProtocol) throws -> TMap { + let (keyType, valueType, size) = try proto.readMapBegin() + if keyType != Key.thriftType || valueType != Value.thriftType { + throw NSError( + domain: TProtocolErrorDomain, + code: Int(TProtocolError.InvalidData.rawValue), + userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: TProtocolExtendedError.UnexpectedType.rawValue)]) + } + var map = TMap() + for _ in 0..<size { + let key = try Key.readValueFromProtocol(proto) + let value = try Value.readValueFromProtocol(proto) + map.storage[key] = value + } + try proto.readMapEnd() + return map + } + + public static func writeValue(value: TMap, toProtocol proto: TProtocol) throws { + try proto.writeMapBeginWithKeyType(Key.thriftType, valueType: Value.thriftType, size: value.count) + for (key, value) in value.storage { + try Key.writeValue(key, toProtocol: proto) + try Value.writeValue(value, toProtocol: proto) + } + try proto.writeMapEnd() + } + +} + + +extension TMap : CustomStringConvertible, CustomDebugStringConvertible { + + public var description : String { + return storage.description + } + + public var debugDescription : String { + return storage.debugDescription + } + +} + +public func ==<Key, Value>(lhs: TMap<Key,Value>, rhs: TMap<Key, Value>) -> Bool { + if lhs.count != rhs.count { + return false + } + return lhs.storage == rhs.storage +} http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TObjective-C.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TObjective-C.h b/lib/cocoa/src/TObjective-C.h deleted file mode 100644 index 9c0831d..0000000 --- a/lib/cocoa/src/TObjective-C.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * TObjective-C.h is for supporting coexistence of both the ARC (Automatic - * Reference Counting) mode and the Non-ARC mode of Objective-C - * in the same source code. - * - * 2011/11/14 HIRANO Satoshi (AIST, Japan) - * - * Before: - * - * var = [aObject retain]; - * [aObject release]; - * [aObject autorelease]; - * [super dealloc]; - * CFFunction(obj); - * - * ARC and Non-ARC compatible: - * - * #import "TObjective-C.h" - * var = [aObject retain_stub]; - * [aObject release_stub]; - * [aObject autorelease_stub]; - * [super dealloc_stub]; - * CFFunction(bridge_stub obj); - * - * Don't use retain_stub for @property(retain). - * Use NSAutoreleasePool like this: - * #if __has_feature(objc_arc) - * @autoreleasepool { - * // code - * } - * #else - * NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init... - * // code - * [pool release]; - * #endif - */ - - -#if !defined(retain_stub) -#if __has_feature(objc_arc) -#define retain_stub self -#define autorelease_stub self -#define release_stub self -#define dealloc_stub self -#define bridge_stub __bridge -#else -#define retain_stub retain -#define autorelease_stub autorelease -#define release_stub release -#define dealloc_stub dealloc -#define bridge_stub -#endif -#endif http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TProcessor.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TProcessor.h b/lib/cocoa/src/TProcessor.h index 980be94..20c72e2 100644 --- a/lib/cocoa/src/TProcessor.h +++ b/lib/cocoa/src/TProcessor.h @@ -20,10 +20,16 @@ #import <Foundation/Foundation.h> #import "TProtocol.h" +NS_ASSUME_NONNULL_BEGIN + @protocol TProcessor <NSObject> -- (BOOL) processOnInputProtocol: (id <TProtocol>) inProtocol - outputProtocol: (id <TProtocol>) outProtocol; +-(BOOL) processOnInputProtocol:(id <TProtocol>)inProtocol + outputProtocol:(id <TProtocol>)outProtocol + error:(NSError **)error; @end + + +NS_ASSUME_NONNULL_END http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TProcessorFactory.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TProcessorFactory.h b/lib/cocoa/src/TProcessorFactory.h index 29d12b3..85020a5 100644 --- a/lib/cocoa/src/TProcessorFactory.h +++ b/lib/cocoa/src/TProcessorFactory.h @@ -20,8 +20,14 @@ #import <Foundation/Foundation.h> #import "TProcessor.h" +NS_ASSUME_NONNULL_BEGIN + + @protocol TProcessorFactory <NSObject> -- (id<TProcessor>) processorForTransport: (id<TTransport>) transport; +-(id<TProcessor>) processorForTransport:(id<TTransport>)transport; @end + + +NS_ASSUME_NONNULL_END http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TProtocol.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TProtocol.swift b/lib/cocoa/src/TProtocol.swift new file mode 100644 index 0000000..1775849 --- /dev/null +++ b/lib/cocoa/src/TProtocol.swift @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + +public extension TProtocol { + + public func readMessageBegin() throws -> (String, TMessageType, Int) { + + var name : NSString? + var type : Int32 = -1 + var sequenceID : Int32 = -1 + + try readMessageBeginReturningName(&name, type: &type, sequenceID: &sequenceID) + + return (name as String!, TMessageType(rawValue: type)!, Int(sequenceID)) + } + + public func writeMessageBeginWithName(name: String, type: TMessageType, sequenceID: Int) throws { + try writeMessageBeginWithName(name, type: type.rawValue, sequenceID: Int32(sequenceID)) + } + + public func readStructBegin() throws -> (String?) { + + var name : NSString? = nil + + try readStructBeginReturningName(&name) + + return (name as String?) + } + + public func readFieldBegin() throws -> (String?, TType, Int) { + + var name : NSString? = nil + var type : Int32 = -1 + var fieldID : Int32 = -1 + + try readFieldBeginReturningName(&name, type: &type, fieldID: &fieldID) + + return (name as String?, TType(rawValue: type)!, Int(fieldID)) + } + + public func writeFieldBeginWithName(name: String, type: TType, fieldID: Int) throws { + try writeFieldBeginWithName(name, type: type.rawValue, fieldID: Int32(fieldID)) + } + + public func readMapBegin() throws -> (TType, TType, Int32) { + + var keyType : Int32 = -1 + var valueType : Int32 = -1 + var size : Int32 = 0 + + try readMapBeginReturningKeyType(&keyType, valueType: &valueType, size: &size) + + return (TType(rawValue: keyType)!, TType(rawValue: valueType)!, size) + } + + public func writeMapBeginWithKeyType(keyType: TType, valueType: TType, size: Int) throws { + try writeMapBeginWithKeyType(keyType.rawValue, valueType: valueType.rawValue, size: Int32(size)) + } + + public func readSetBegin() throws -> (TType, Int32) { + + var elementType : Int32 = -1 + var size : Int32 = 0 + + try readSetBeginReturningElementType(&elementType, size: &size) + + return (TType(rawValue: elementType)!, size) + } + + public func writeSetBeginWithElementType(elementType: TType, size: Int) throws { + try writeSetBeginWithElementType(elementType.rawValue, size: Int32(size)) + } + + public func readListBegin() throws -> (TType, Int32) { + + var elementType : Int32 = -1 + var size : Int32 = 0 + + try readListBeginReturningElementType(&elementType, size: &size) + + return (TType(rawValue: elementType)!, size) + } + + public func writeListBeginWithElementType(elementType: TType, size: Int) throws { + try writeListBeginWithElementType(elementType.rawValue, size: Int32(size)) + } + + public func writeFieldValue<T: TSerializable>(value: T, name: String, type: TType, id: Int32) throws { + try writeFieldBeginWithName(name, type: type.rawValue, fieldID: id) + try writeValue(value) + try writeFieldEnd() + } + + public func readValue<T: TSerializable>() throws -> T { + return try T.readValueFromProtocol(self) + } + + public func writeValue<T: TSerializable>(value: T) throws { + try T.writeValue(value, toProtocol: self) + } + + public func readResultMessageBegin() throws { + + let (_, type, _) = try readMessageBegin(); + + if type == .EXCEPTION { + let x = try readException() + throw x + } + + return + } + + public func validateValue(value: Any?, named name: String) throws { + + if value == nil { + throw NSError( + domain: TProtocolErrorDomain, + code: Int(TProtocolError.Unknown.rawValue), + userInfo: [TProtocolErrorFieldNameKey: name]) + } + + } + + public func readException() throws -> ErrorType { + + var reason : String? + var type = TApplicationError.Unknown + + try readStructBegin() + + fields: while (true) { + + let (_, fieldType, fieldID) = try readFieldBegin() + + switch (fieldID, fieldType) { + case (_, .STOP): + break fields + + case (1, .STRING): + reason = try readValue() as String + + case (2, .I32): + let typeVal = try readValue() as Int32 + if let tmp = TApplicationError(rawValue: typeVal) { + type = tmp + } + + case let (_, unknownType): + try skipType(unknownType) + } + + try readFieldEnd() + } + + try readStructEnd() + + return NSError(type:type, reason:reason ?? "") + } + + public func writeExceptionForMessageName(name: String, sequenceID: Int, ex: NSError) throws { + try writeMessageBeginWithName(name, type: .EXCEPTION, sequenceID: sequenceID) + try ex.write(self) + try writeMessageEnd() + } + + public func skipType(type: TType) throws { + try TProtocolUtil.skipType(type.rawValue, onProtocol: self) + } + +} http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TSerializable.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TSerializable.swift b/lib/cocoa/src/TSerializable.swift new file mode 100644 index 0000000..3fdfd41 --- /dev/null +++ b/lib/cocoa/src/TSerializable.swift @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + +public protocol TSerializable : Hashable { + + static var thriftType : TType { get } + + init() + + static func readValueFromProtocol(proto: TProtocol) throws -> Self + + static func writeValue(value: Self, toProtocol proto: TProtocol) throws + +} + + + +infix operator ?== {} + +public func ?==<T: TSerializable>(lhs: T?, rhs: T?) -> Bool { + if let l = lhs, r = rhs { + return l == r + } + return lhs == rhs +} + +public func ?==<T: TSerializable>(lhs: T, rhs: T) -> Bool { + return lhs == rhs +} + + + +extension Bool : TSerializable { + + public static let thriftType = TType.BOOL + + public static func readValueFromProtocol(proto: TProtocol) throws -> Bool { + var value : ObjCBool = false + try proto.readBool(&value) + return value.boolValue + } + + public static func writeValue(value: Bool, toProtocol proto: TProtocol) throws { + try proto.writeBool(value) + } + +} + +extension Int8 : TSerializable { + + public static let thriftType = TType.BYTE + + public static func readValueFromProtocol(proto: TProtocol) throws -> Int8 { + var value = UInt8() + try proto.readByte(&value) + return Int8(value) + } + + public static func writeValue(value: Int8, toProtocol proto: TProtocol) throws { + try proto.writeByte(UInt8(value)) + } + +} + +extension Int16 : TSerializable { + + public static let thriftType = TType.I16 + + public static func readValueFromProtocol(proto: TProtocol) throws -> Int16 { + var value = Int16() + try proto.readI16(&value) + return value + } + + public static func writeValue(value: Int16, toProtocol proto: TProtocol) throws { + try proto.writeI16(value) + } + +} + +extension Int : TSerializable { + + public static let thriftType = TType.I32 + + public static func readValueFromProtocol(proto: TProtocol) throws -> Int { + var value = Int32() + try proto.readI32(&value) + return Int(value) + } + + public static func writeValue(value: Int, toProtocol proto: TProtocol) throws { + try proto.writeI32(Int32(value)) + } + +} + +extension Int32 : TSerializable { + + public static let thriftType = TType.I32 + + public static func readValueFromProtocol(proto: TProtocol) throws -> Int32 { + var value = Int32() + try proto.readI32(&value) + return value + } + + public static func writeValue(value: Int32, toProtocol proto: TProtocol) throws { + try proto.writeI32(value) + } + +} + +extension Int64 : TSerializable { + + public static let thriftType = TType.I64 + + public static func readValueFromProtocol(proto: TProtocol) throws -> Int64 { + var value = Int64() + try proto.readI64(&value) + return value + } + + public static func writeValue(value: Int64, toProtocol proto: TProtocol) throws { + try proto.writeI64(value) + } + +} + +extension Double : TSerializable { + + public static let thriftType = TType.DOUBLE + + public static func readValueFromProtocol(proto: TProtocol) throws -> Double { + var value = Double() + try proto.readDouble(&value) + return value + } + + public static func writeValue(value: Double, toProtocol proto: TProtocol) throws { + try proto.writeDouble(value) + } + +} + +extension String : TSerializable { + + public static let thriftType = TType.STRING + + public static func readValueFromProtocol(proto: TProtocol) throws -> String { + var value : NSString? + try proto.readString(&value) + return value as! String + } + + public static func writeValue(value: String, toProtocol proto: TProtocol) throws { + try proto.writeString(value) + } + +} http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TSet.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TSet.swift b/lib/cocoa/src/TSet.swift new file mode 100644 index 0000000..85833e5 --- /dev/null +++ b/lib/cocoa/src/TSet.swift @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + +public struct TSet<Element : TSerializable> : CollectionType, ArrayLiteralConvertible, TSerializable { + + public static var thriftType : TType { return .SET } + + public typealias Index = Storage.Index + + typealias Storage = Set<Element> + + private var storage : Storage + + public init() { + storage = Storage() + } + + public init(arrayLiteral elements: Element...) { + storage = Storage(elements) + } + + public init<S : SequenceType where S.Generator.Element == Element>(_ sequence: S) { + storage = Storage(sequence) + } + + public var startIndex : Index { return storage.startIndex } + + public var endIndex : Index { return storage.endIndex } + + public mutating func insert(member: Element) { + return storage.insert(member) + } + + public mutating func remove(element: Element) -> Element? { + return storage.remove(element) + } + + public mutating func removeAll(keepCapacity keepCapacity: Bool = false) { + return storage.removeAll(keepCapacity: keepCapacity) + } + + public mutating func removeAtIndex(index: SetIndex<Element>) -> Element { + return storage.removeAtIndex(index) + } + + public subscript (position: SetIndex<Element>) -> Element { + return storage[position] + } + + public func union(other: TSet) -> TSet { + return TSet(storage.union(other)) + } + + public func intersect(other: TSet) -> TSet { + return TSet(storage.intersect(other)) + } + + public func exclusiveOr(other: TSet) -> TSet { + return TSet(storage.exclusiveOr(other)) + } + + public func subtract(other: TSet) -> TSet { + return TSet(storage.subtract(other)) + } + + public mutating func intersectInPlace(other: TSet) { + storage.intersectInPlace(other) + } + + public mutating func exclusiveOrInPlace(other: TSet) { + storage.exclusiveOrInPlace(other) + } + + public mutating func subtractInPlace(other: TSet) { + storage.subtractInPlace(other) + } + + public func isSubsetOf(other: TSet) -> Bool { + return storage.isSubsetOf(other) + } + + public func isDisjointWith(other: TSet) -> Bool { + return storage.isDisjointWith(other) + } + + public func isSupersetOf(other: TSet) -> Bool { + return storage.isSupersetOf(other) + } + + public var isEmpty: Bool { return storage.isEmpty } + + public var hashValue : Int { + let prime = 31 + var result = 1 + for element in storage { + result = prime * result + element.hashValue + } + return result + } + + public static func readValueFromProtocol(proto: TProtocol) throws -> TSet { + let (elementType, size) = try proto.readSetBegin() + if elementType != Element.thriftType { + throw NSError( + domain: TProtocolErrorDomain, + code: Int(TProtocolError.InvalidData.rawValue), + userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: elementType.rawValue)]) + } + var set = TSet() + for _ in 0..<size { + let element = try Element.readValueFromProtocol(proto) + set.storage.insert(element) + } + try proto.readSetEnd() + return set + } + + public static func writeValue(value: TSet, toProtocol proto: TProtocol) throws { + try proto.writeSetBeginWithElementType(Element.thriftType, size: value.count) + for element in value.storage { + try Element.writeValue(element, toProtocol: proto) + } + try proto.writeSetEnd() + } + +} + +extension TSet : CustomStringConvertible, CustomDebugStringConvertible { + + public var description : String { + return storage.description + } + + public var debugDescription : String { + return storage.debugDescription + } + +} + +public func ==<Element>(lhs: TSet<Element>, rhs: TSet<Element>) -> Bool { + return lhs.storage == rhs.storage +} http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TSharedProcessorFactory.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TSharedProcessorFactory.h b/lib/cocoa/src/TSharedProcessorFactory.h index cf4a462..c75fad1 100644 --- a/lib/cocoa/src/TSharedProcessorFactory.h +++ b/lib/cocoa/src/TSharedProcessorFactory.h @@ -20,8 +20,9 @@ #import <Foundation/Foundation.h> #import "TProcessorFactory.h" -@interface TSharedProcessorFactory : NSObject <TProcessorFactory> { - id<TProcessor> mSharedProcessor; -} -- (id) initWithSharedProcessor: (id<TProcessor>) sharedProcessor; + +@interface TSharedProcessorFactory : NSObject <TProcessorFactory> + +-(id) initWithSharedProcessor:(id<TProcessor>)sharedProcessor; + @end http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TSharedProcessorFactory.m ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TSharedProcessorFactory.m b/lib/cocoa/src/TSharedProcessorFactory.m index a0007c0..3d55f47 100644 --- a/lib/cocoa/src/TSharedProcessorFactory.m +++ b/lib/cocoa/src/TSharedProcessorFactory.m @@ -19,34 +19,31 @@ #import "TSharedProcessorFactory.h" -#import "TObjective-C.h" + + +@interface TSharedProcessorFactory () + +@property(strong, nonatomic) id<TProcessor> sharedProcessor; + +@end @implementation TSharedProcessorFactory -- (id) initWithSharedProcessor: (id<TProcessor>) sharedProcessor +-(id) initWithSharedProcessor:(id<TProcessor>)sharedProcessor { self = [super init]; - if (!self) { - return nil; + if (self) { + _sharedProcessor = sharedProcessor; } - - mSharedProcessor = [sharedProcessor retain_stub]; - return self; -} - -- (void) dealloc -{ - [mSharedProcessor release_stub]; - [super dealloc_stub]; + return self; } - -- (id<TProcessor>) processorForTransport: (id<TTransport>) transport +-(id<TProcessor>) processorForTransport:(id<TTransport>)transport { - return [[mSharedProcessor retain_stub] autorelease_stub]; + return _sharedProcessor; } @end http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/TStruct.swift ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TStruct.swift b/lib/cocoa/src/TStruct.swift new file mode 100644 index 0000000..cea72e7 --- /dev/null +++ b/lib/cocoa/src/TStruct.swift @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Foundation + + +public protocol TStruct : TSerializable { +} + + +public extension TStruct { + + public static var thriftType : TType { return TType.STRUCT } + +} http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/protocol/TBase.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/protocol/TBase.h b/lib/cocoa/src/protocol/TBase.h index 33037ef..b31061e 100644 --- a/lib/cocoa/src/protocol/TBase.h +++ b/lib/cocoa/src/protocol/TBase.h @@ -26,16 +26,21 @@ /** * De-serialize object from the given input protocol * - * @param input protocol used for reading + * @param input protocol used for reading */ -- (void) read: (id <TProtocol>) inProtocol; +-(BOOL) read:(id <TProtocol>)inProtocol error:(NSError **)error; /** * Serialize object to the given protocol * * @param buf output protocol used for writing */ -- (void) write: (id <TProtocol>) outProtocol; +-(BOOL) write:(id <TProtocol>)outProtocol error:(NSError **)error; -@end +/** + * Validate required fields + */ +-(BOOL) validate:(NSError *__autoreleasing *)__thriftError; + +@end http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/protocol/TBinaryProtocol.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.h b/lib/cocoa/src/protocol/TBinaryProtocol.h index 9a73730..bb90fad 100644 --- a/lib/cocoa/src/protocol/TBinaryProtocol.h +++ b/lib/cocoa/src/protocol/TBinaryProtocol.h @@ -21,31 +21,29 @@ #import "TTransport.h" #import "TProtocolFactory.h" +NS_ASSUME_NONNULL_BEGIN -@interface TBinaryProtocol : NSObject <TProtocol> { - id <TTransport> mTransport; - BOOL mStrictRead; - BOOL mStrictWrite; - int32_t mMessageSizeLimit; -} -- (id) initWithTransport: (id <TTransport>) transport; +@interface TBinaryProtocol : NSObject <TProtocol> -- (id) initWithTransport: (id <TTransport>) transport - strictRead: (BOOL) strictRead - strictWrite: (BOOL) strictWrite; +@property (assign, nonatomic) UInt32 messageSizeLimit; -- (int32_t) messageSizeLimit; -- (void) setMessageSizeLimit: (int32_t) sizeLimit; +-(id) initWithTransport:(id <TTransport>)transport; -@end +-(id) initWithTransport:(id <TTransport>)transport + strictRead:(BOOL)strictRead + strictWrite:(BOOL)strictWrite; + +@end; -@interface TBinaryProtocolFactory : NSObject <TProtocolFactory> { -} +@interface TBinaryProtocolFactory : NSObject <TProtocolFactory> -+ (TBinaryProtocolFactory *) sharedFactory; ++(TBinaryProtocolFactory *) sharedFactory; -- (TBinaryProtocol *) newProtocolOnTransport: (id <TTransport>) transport; +-(TBinaryProtocol *) newProtocolOnTransport:(id <TTransport>)transport; @end + + +NS_ASSUME_NONNULL_END \ No newline at end of file http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/protocol/TBinaryProtocol.m ---------------------------------------------------------------------- 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 @@ static TBinaryProtocolFactory * gSharedFactory = nil; 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 -{ - return mMessageSizeLimit; -} - - -- (void) setMessageSizeLimit: (int32_t) sizeLimit +-(id <TTransport>) transport { - mMessageSizeLimit = sizeLimit; + return _transport; } - -- (void) dealloc +-(NSString *) readStringBody:(int)size error:(NSError **)error { - [mTransport release_stub]; - [super dealloc_stub]; -} + NSMutableData *data = [NSMutableData dataWithLength:size]; + if (!data) { + PROTOCOL_ERROR(nil, Unknown, @"Unable to allocate %d bytes", size); + } + if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) { + PROTOCOL_TRANSPORT_ERROR(nil, error, @"Transport read failed"); + } -- (id <TTransport>) transport -{ - return mTransport; + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } -- (NSString *) readStringBody: (int) rawSize +-(BOOL) readMessageBeginReturningName:(NSString **)name + type:(SInt32 *)type + sequenceID:(SInt32 *)sequenceID + error:(NSError *__autoreleasing *)error { - 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]];; + SInt32 size; + if (![self readI32:&size error:error]) { + return NO; } - [mTransport readAll: (uint8_t *) buffer offset: 0 length: size]; - buffer[size] = 0; - NSString * result = [NSString stringWithUTF8String: buffer]; - free(buffer); - return result; -} - + ; -- (void) readMessageBeginReturningName: (NSString **) name - type: (int *) type - sequenceID: (int *) sequenceID -{ - int32_t size = [self readI32]; 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]; - if (name != NULL) { + NSString *messageName; + if (![self readString:&messageName error:error]) { + return NO; + } + if (name != nil) { *name = messageName; } - int seqID = [self readI32]; - if (sequenceID != NULL) { - *sequenceID = seqID; + } + else { + + if (_strictRead) { + PROTOCOL_ERROR(NO, InvalidData, @"Missing message version, old client?"); } - } else { - if (mStrictRead) { - @throw [TProtocolException exceptionWithName: @"TProtocolException" - reason: @"Missing version in readMessageBegin, old client?"]; + + if (_messageSizeLimit > 0 && size > _messageSizeLimit) { + PROTOCOL_ERROR(NO, SizeLimit, @"Message exceeeds size limit of %d", (int)size); } - 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 error:error]; + if (!messageName) { + return NO; } - NSString * messageName = [self readStringBody: size]; + if (name != NULL) { *name = messageName; } - int messageType = [self readByte]; + + UInt8 messageType; + if (![self readByte:&messageType error:error]) { + return NO; + } + 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 {} +-(BOOL) readMessageEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (void) readStructBeginReturningName: (NSString **) name +-(BOOL) readStructBeginReturningName:(NSString *__autoreleasing *)name error:(NSError *__autoreleasing *)error { - if (name != NULL) { - *name = nil; - } + return YES; } -- (void) readStructEnd {} +-(BOOL) readStructEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (void) readFieldBeginReturningName: (NSString **) name - type: (int *) fieldType - fieldID: (int *) fieldID +-(BOOL) readFieldBeginReturningName:(NSString *__autoreleasing *)name + type:(SInt32 *)fieldType + fieldID:(SInt32 *)fieldID + error:(NSError *__autoreleasing *)error { - if (name != NULL) { + 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 {} +-(BOOL) readFieldEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (int32_t) readI32 +-(BOOL) readString:(NSString *__autoreleasing *)value error:(NSError *__autoreleasing *)error { - uint8_t i32rd[4]; - [mTransport readAll: i32rd offset: 0 length: 4]; - return - ((i32rd[0] & 0xff) << 24) | - ((i32rd[1] & 0xff) << 16) | - ((i32rd[2] & 0xff) << 8) | - ((i32rd[3] & 0xff)); + 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; } -- (NSString *) readString +-(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error { - int32_t size = [self readI32]; - return [self readStringBody: size]; + UInt8 byte; + if (![self readByte:&byte error:error]) { + return NO; + } + + *value = byte == 1; + + return YES; } -- (BOOL) readBool +-(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error { - return [self readByte] == 1; + 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; } -- (uint8_t) readByte + +-(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error { - uint8_t myByte; - [mTransport readAll: &myByte offset: 0 length: 1]; - return myByte; + 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; } -- (short) readI16 + +-(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error { - uint8_t buff[2]; - [mTransport readAll: buff offset: 0 length: 2]; - return (short) - (((buff[0] & 0xff) << 8) | - ((buff[1] & 0xff))); + 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; } -- (int64_t) readI64 + +-(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error { - 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)); + 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; } -- (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; + } + + NSMutableData *data = [NSMutableData dataWithLength:size]; + if (!data) { + PROTOCOL_ERROR(NO, Unknown, @"Unable to allocate %d bytes", (int)size); } - [mTransport readAll: buff offset: 0 length: binarySize]; - return [NSData dataWithBytesNoCopy: buff length: binarySize]; + + 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 {} +-(BOOL) readMapEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (void) readSetBeginReturningElementType: (int *) elementType - size: (int *) size + +-(BOOL) readSetBeginReturningElementType:(SInt32 *)elementType + size:(SInt32 *)size + error:(NSError *__autoreleasing *)error { - int et = [self readByte]; - int s = [self readI32]; + 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 {} +-(BOOL) readSetEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (void) readListBeginReturningElementType: (int *) elementType - size: (int *) size +-(BOOL) readListBeginReturningElementType:(SInt32 *)elementType + size:(SInt32 *)size + error:(NSError *__autoreleasing *)error { - int et = [self readByte]; - int s = [self readI32]; + 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; +} + + +-(BOOL) readListEnd:(NSError *__autoreleasing *)error +{ + return YES; } -- (void) readListEnd {} + +-(BOOL) writeMessageBeginWithName:(NSString *)name + type:(SInt32)messageType + sequenceID:(SInt32)sequenceID + error:(NSError *__autoreleasing *)error +{ + 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) writeByte: (uint8_t) value +-(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error { - [mTransport write: &value offset: 0 length: 1]; + _currentMessageName = nil; + return YES; } -- (void) writeMessageBeginWithName: (NSString *) name - type: (int) messageType - sequenceID: (int) sequenceID +-(BOOL) writeStructBeginWithName:(NSString *)name + 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]; - } + return YES; } -- (void) writeMessageEnd {} +-(BOOL) writeStructEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (void) writeStructBeginWithName: (NSString *) name {} +-(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; + } -- (void) writeStructEnd {} + return YES; +} -- (void) writeFieldBeginWithName: (NSString *) name - type: (int) fieldType - fieldID: (int) fieldID +-(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error { - [self writeByte: CheckedCastIntToUInt8(fieldType)]; - [self writeI16: CheckedCastIntToUInt8(fieldID)]; + return [self writeByte:(value ? 1 : 0) error:error]; } -- (void) writeI32: (int32_t) value +-(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error { - uint8_t 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]; + if (![_transport write:&value offset:0 length:1 error:error]) { + PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed"); + } + return YES; } -- (void) writeI16: (short) value + +-(BOOL) writeI16:(short)value error:(NSError *__autoreleasing *)error { - uint8_t buff[2]; + UInt8 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: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; + + 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 @@ static TBinaryProtocolFactory * gSharedFactory = nil; 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; + } + + if (![_transport write:data.bytes offset:0 length:(UInt32)data.length error:error]) { + PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed"); + } + + return YES; } -- (void) writeFieldStop + +-(BOOL) writeFieldStop:(NSError *__autoreleasing *)error { - [self writeByte: TType_STOP]; + if (![self writeByte:TTypeSTOP error:error]) { + return NO; + } + + return YES; } -- (void) writeFieldEnd {} +-(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error +{ + return YES; +} -- (void) writeMapBeginWithKeyType: (int) keyType - valueType: (int) valueType - size: (int) size +-(BOOL) writeMapBeginWithKeyType:(SInt32)keyType + valueType:(SInt32)valueType + size:(SInt32)size + error:(NSError *__autoreleasing *)error { - [self writeByte: CheckedCastIntToUInt8(keyType)]; - [self writeByte: CheckedCastIntToUInt8(valueType)]; - [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) writeMapEnd {} - -- (void) writeSetBeginWithElementType: (int) elementType - size: (int) size +-(BOOL) writeMapEnd:(NSError *__autoreleasing *)error { - [self writeByte: CheckedCastIntToUInt8(elementType)]; - [self writeI32: size]; + return YES; } -- (void) writeSetEnd {} +-(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; +} -- (void) writeListBeginWithElementType: (int) elementType - size: (int) size + +-(BOOL) writeSetEnd:(NSError *__autoreleasing *)error { - [self writeByte: CheckedCastIntToUInt8(elementType)]; - [self writeI32: size]; + return YES; } -- (void) writeListEnd {} + +-(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; +} -- (void) writeBool: (BOOL) value +-(BOOL) writeListEnd:(NSError *__autoreleasing *)error { - [self writeByte: (value ? 1 : 0)]; + return YES; } @end http://git-wip-us.apache.org/repos/asf/thrift/blob/56e5b9b0/lib/cocoa/src/protocol/TCompactProtocol.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/protocol/TCompactProtocol.h b/lib/cocoa/src/protocol/TCompactProtocol.h index 3c9195c..3f6accc 100644 --- a/lib/cocoa/src/protocol/TCompactProtocol.h +++ b/lib/cocoa/src/protocol/TCompactProtocol.h @@ -21,16 +21,22 @@ #import "TTransport.h" #import "TProtocolFactory.h" +NS_ASSUME_NONNULL_BEGIN + + @interface TCompactProtocol : NSObject <TProtocol> -- (id) initWithTransport: (id <TTransport>) transport; +-(id) initWithTransport:(id <TTransport>)transport; @end @interface TCompactProtocolFactory : NSObject <TProtocolFactory> -+ (TCompactProtocolFactory *) sharedFactory; ++(TCompactProtocolFactory *) sharedFactory; -- (TCompactProtocol *) newProtocolOnTransport: (id <TTransport>) transport; +-(TCompactProtocol *) newProtocolOnTransport:(id <TTransport>)transport; @end + + +NS_ASSUME_NONNULL_END \ No newline at end of file
