THRIFT-3773: Swift 3 changes, Squashed (#1084)

Client: swift
diff --git a/lib/swift/Sources/LinuxHelper.swift b/lib/swift/Sources/LinuxHelper.swift
new file mode 100644
index 0000000..66d92bb
--- /dev/null
+++ b/lib/swift/Sources/LinuxHelper.swift
@@ -0,0 +1,46 @@
+/*
+ * 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
+import CoreFoundation
+
+#if os(Linux)
+/// Extensions for Linux for incomplete Foundation API's.
+/// swift-corelibs-foundation is not yet 1:1 with OSX/iOS Foundation
+
+extension CFSocketError {
+  public static let success = kCFSocketSuccess
+}
+  
+extension UInt {
+  public static func &(lhs: UInt, rhs: Int) -> UInt {
+    let cast = unsafeBitCast(rhs, to: UInt.self)
+    return lhs & cast
+  }
+}
+
+#else
+extension CFStreamPropertyKey {
+  static let shouldCloseNativeSocket  = CFStreamPropertyKey(kCFStreamPropertyShouldCloseNativeSocket)
+  // Exists as Stream.PropertyKey.socketSecuritylevelKey but doesn't work with CFReadStreamSetProperty
+  static let socketSecurityLevel      = CFStreamPropertyKey(kCFStreamPropertySocketSecurityLevel)
+  static let SSLSettings              = CFStreamPropertyKey(kCFStreamPropertySSLSettings)
+}
+#endif
diff --git a/lib/swift/Sources/TApplicationError.swift b/lib/swift/Sources/TApplicationError.swift
new file mode 100644
index 0000000..bc39396
--- /dev/null
+++ b/lib/swift/Sources/TApplicationError.swift
@@ -0,0 +1,157 @@
+/*
+* 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.
+*/
+
+
+public struct TApplicationError : TError {
+  public enum Code : TErrorCode {
+    case unknown
+    case unknownMethod(methodName: String?)
+    case invalidMessageType
+    case wrongMethodName(methodName: String?)
+    case badSequenceId
+    case missingResult(methodName: String?)
+    case internalError
+    case protocolError
+    case invalidTransform
+    case invalidProtocol
+    case unsupportedClientType
+    
+    
+    /// Initialize a TApplicationError with a Thrift error code
+    /// Normally this would be achieved with RawRepresentable however
+    /// by doing this we can allow for associated properties on enum cases for
+    /// case specific context data in a Swifty, type-safe manner.
+    ///
+    /// - parameter thriftErrorCode: Integer TApplicationError(exception) error code.  
+    ///                              Default to 0 (.unknown)
+    public init(thriftErrorCode: Int) {
+      switch thriftErrorCode {
+      case 1:  self = .unknownMethod(methodName: nil)
+      case 2:  self = .invalidMessageType
+      case 3:  self = .wrongMethodName(methodName: nil)
+      case 4:  self = .badSequenceId
+      case 5:  self = .missingResult(methodName: nil)
+      case 6:  self = .internalError
+      case 7:  self = .protocolError
+      case 8:  self = .invalidProtocol
+      case 9:  self = .invalidTransform
+      case 10: self = .unsupportedClientType
+      default: self = .unknown
+      }
+    }
+    public var thriftErrorCode: Int {
+      switch self {
+      case .unknown:                return 0
+      case .unknownMethod:          return 1
+      case .invalidMessageType:     return 2
+      case .wrongMethodName:        return 3
+      case .badSequenceId:          return 4
+      case .missingResult:          return 5
+      case .internalError:          return 6
+      case .protocolError:          return 7
+      case .invalidProtocol:        return 8
+      case .invalidTransform:       return 9
+      case .unsupportedClientType:  return 10
+      }
+    }
+    
+    public var description: String {
+      /// Output "for #methodName" if method is not nil else empty
+      let methodUnwrap: (String?) -> String =  { method in
+        return "\(method == nil ? "" : " for \(method ?? "")")"
+      }
+      switch self {
+      case .unknown:                      return "Unknown TApplicationError"
+      case .unknownMethod(let method):    return "Unknown Method\(methodUnwrap(method))"
+      case .invalidMessageType:           return "Invalid Message Type"
+      case .wrongMethodName(let method):  return "Wrong Method Name\(methodUnwrap(method))"
+      case .badSequenceId:                return "Bad Sequence ID"
+      case .missingResult(let method):    return "Missing Result\(methodUnwrap(method))"
+      case .internalError:                return "Internal Error"
+      case .protocolError:                return "Protocol Error"
+      case .invalidProtocol:              return "Invalid Protocol"
+      case .invalidTransform:             return "Invalid Transform"
+      case .unsupportedClientType:        return "Unsupported Client Type"
+      }
+    }
+  }
+
+  public init() { }
+  
+  public init(thriftErrorCode code: Int, message: String? = nil) {
+    self.error = Code(thriftErrorCode: code)
+    self.message = message
+  }
+  
+  public var error: Code = .unknown
+  public var message: String? = nil
+  public static var defaultCase: Code { return .unknown }
+}
+
+extension TApplicationError : TSerializable {
+  public static var thriftType: TType { return .struct }
+  
+  public static func read(from proto: TProtocol) throws -> TApplicationError {
+    var errorCode: Int = 0
+    var message: String? = nil
+    _ = try proto.readStructBegin()
+    fields: while true {
+      let (_, fieldType, fieldID) = try proto.readFieldBegin()
+      
+      switch (fieldID, fieldType) {
+      case (_, .stop):
+        break fields
+      case (1, .string):
+        message = try proto.read()
+      case (2, .i32):
+        errorCode = Int(try proto.read() as Int32)
+      
+      case let (_, unknownType):
+        try proto.skip(type: unknownType)
+      }
+      
+      try proto.readFieldEnd()
+    }
+    try proto.readStructEnd()
+    return TApplicationError(thriftErrorCode: errorCode, message: message)
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.writeStructBegin(name: "TApplicationException")
+    
+    try proto.writeFieldBegin(name: "message", type: .string, fieldID: 1)
+    try proto.write(message ?? "")
+    try proto.writeFieldEnd()
+    
+    try proto.writeFieldBegin(name: "type", type: .i32, fieldID: 2)
+    let val = Int32(error.thriftErrorCode)
+    try proto.write(val)
+    try proto.writeFieldEnd()
+    try proto.writeFieldStop()
+    try proto.writeStructEnd()
+  }
+  
+  public var hashValue: Int {
+    return error.thriftErrorCode &+ (message?.hashValue ?? 0)
+  }
+}
+
+public func ==(lhs: TApplicationError, rhs: TApplicationError) -> Bool {
+  return lhs.error.thriftErrorCode == rhs.error.thriftErrorCode && lhs.message == rhs.message
+}
diff --git a/lib/swift/Sources/TBinary.swift b/lib/swift/Sources/TBinary.swift
new file mode 100644
index 0000000..4be5644
--- /dev/null
+++ b/lib/swift/Sources/TBinary.swift
@@ -0,0 +1,32 @@
+/*
+ * 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
+
+extension Data : TSerializable {
+  public static var thriftType: TType { return .string }
+  
+  public static func read(from proto: TProtocol) throws -> Data {
+    return try proto.read() as Data
+  }
+  
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
diff --git a/lib/swift/Sources/TBinaryProtocol.swift b/lib/swift/Sources/TBinaryProtocol.swift
new file mode 100644
index 0000000..47f3f28
--- /dev/null
+++ b/lib/swift/Sources/TBinaryProtocol.swift
@@ -0,0 +1,384 @@
+/*
+ * 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 TBinaryProtocolVersion {
+  static let version1    = Int32(bitPattern: 0x80010000)
+  static let versionMask = Int32(bitPattern: 0xffff0000)
+}
+
+public class TBinaryProtocol: TProtocol {
+  public var messageSizeLimit: UInt32  = 0
+  
+  public var transport: TTransport
+  
+  // class level properties for setting global config (useful for server in lieu of Factory design)
+  public static var strictRead: Bool = false
+  public static var strictWrite: Bool = true
+
+  private var strictRead: Bool
+  private var strictWrite: Bool
+  
+  var currentMessageName: String?
+  var currentFieldName: String?
+  
+  
+  public convenience init(transport: TTransport, strictRead: Bool, strictWrite: Bool) {
+    self.init(on: transport)
+    self.strictRead = strictRead
+    self.strictWrite = strictWrite
+  }
+  
+  public required init(on transport: TTransport) {
+    self.transport = transport
+    self.strictWrite = TBinaryProtocol.strictWrite
+    self.strictRead = TBinaryProtocol.strictRead
+  }
+  
+  func readStringBody(_ size: Int) throws -> String {
+    
+    var data = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport read failed")) {
+      data = try self.transport.readAll(size: size)
+    }
+    
+    return String(data: data, encoding: String.Encoding.utf8) ?? ""
+  }
+  
+  /// Mark: - TProtocol
+  
+  public func readMessageBegin() throws -> (String, TMessageType, Int32) {
+    let size: Int32 = try read()
+    var messageName = ""
+    var type = TMessageType.exception
+    
+    if size < 0 {
+      let version = size & TBinaryProtocolVersion.versionMask
+      if version != TBinaryProtocolVersion.version1 {
+        throw TProtocolError(error: .badVersion(expected: "\(TBinaryProtocolVersion.version1)",
+                                                got: "\(version)"))
+      }
+      type = TMessageType(rawValue: Int32(size) & 0x00FF) ?? type
+      messageName = try read()
+    } else {
+      if strictRead {
+        let errorMessage = "Missing message version, old client? Message Name: \(currentMessageName)"
+        throw TProtocolError(error: .invalidData,
+                             message: errorMessage)
+      }
+      if messageSizeLimit > 0 && size > Int32(messageSizeLimit) {
+        throw TProtocolError(error: .sizeLimit(limit: Int(messageSizeLimit), got: Int(size)))
+      }
+      
+      messageName = try readStringBody(Int(size))
+      type = TMessageType(rawValue: Int32(try read() as UInt8)) ?? type
+    }
+    
+    let seqID: Int32 = try read()
+    return (messageName, type, seqID)
+  }
+  
+  public func readMessageEnd() throws {
+    return
+  }
+  
+  public func readStructBegin() throws -> String {
+    return ""
+  }
+  
+  public func readStructEnd() throws {
+    return
+  }
+  
+  public func readFieldBegin() throws -> (String, TType, Int32) {
+    
+    let fieldType = TType(rawValue: Int32(try read() as UInt8)) ?? TType.stop
+    var fieldID: Int32 = 0
+    
+    if fieldType != .stop {
+      fieldID = Int32(try read() as Int16)
+    }
+    
+    return ("", fieldType, fieldID)
+  }
+  
+  public func readFieldEnd() throws {
+    return
+  }
+  
+  public func readMapBegin() throws -> (TType, TType, Int32) {
+    var raw = Int32(try read() as UInt8)
+    guard let keyType = TType(rawValue: raw) else {
+      throw TProtocolError(message: "Unknown value for keyType TType: \(raw)")
+    }
+    
+    raw = Int32(try read() as UInt8)
+    guard let valueType = TType(rawValue: raw) else {
+      throw TProtocolError(message: "Unknown value for valueType TType: \(raw)")
+    }
+    let size: Int32 = try read()
+    
+    return (keyType, valueType, size)
+  }
+  
+  public func readMapEnd() throws {
+    return
+  }
+  
+  public func readSetBegin() throws -> (TType, Int32) {
+    let raw = Int32(try read() as UInt8)
+    guard let elementType = TType(rawValue: raw) else {
+      throw TProtocolError(message: "Unknown value for elementType TType: \(raw)")
+    }
+    
+    let size: Int32 = try read()
+    
+    return (elementType, size)
+  }
+  
+  public func readSetEnd() throws {
+    return
+  }
+  
+  public func readListBegin() throws -> (TType, Int32) {
+    let raw = Int32(try read() as UInt8)
+    guard let elementType = TType(rawValue: raw) else {
+      throw TProtocolError(message: "Unknown value for elementType TType: \(raw)")
+    }
+    let size: Int32 = try read()
+    
+    return (elementType, size)
+  }
+  
+  public func readListEnd() throws {
+    return
+  }
+  
+  public func read() throws -> String {
+    let data: Data = try read()
+    guard let str = String.init(data: data, encoding: .utf8) else {
+      throw TProtocolError(error: .invalidData, message: "Couldn't encode UTF-8 from data read")
+    }
+    return str
+  }
+  
+  public func read() throws -> Bool {
+    return (try read() as UInt8) == 1
+  }
+  
+  public func read() throws -> UInt8 {
+    var buff = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      buff = try self.transport.readAll(size: 1)
+    }
+    return buff[0]
+  }
+  
+  public func read() throws -> Int16 {
+    var buff = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      buff = try self.transport.readAll(size: 2)
+    }
+    var ret = Int16(buff[0] & 0xff) << 8
+    ret |=    Int16(buff[1] & 0xff)
+    return ret
+  }
+  
+  public func read() throws -> Int32 {
+    var buff = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      buff = try self.transport.readAll(size: 4)
+    }
+    var ret = Int32(buff[0] & 0xff) << 24
+    ret |=    Int32(buff[1] & 0xff) << 16
+    ret |=    Int32(buff[2] & 0xff) << 8
+    ret |=    Int32(buff[3] & 0xff)
+    
+    return ret
+  }
+  
+  public func read() throws -> Int64 {
+    var buff = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      buff = try self.transport.readAll(size: 8)
+    }
+    var ret = Int64(buff[0] & 0xff) << 56
+    ret |=    Int64(buff[1] & 0xff) << 48
+    ret |=    Int64(buff[2] & 0xff) << 40
+    ret |=    Int64(buff[3] & 0xff) << 32
+    ret |=    Int64(buff[4] & 0xff) << 24
+    ret |=    Int64(buff[5] & 0xff) << 16
+    ret |=    Int64(buff[6] & 0xff) << 8
+    ret |=    Int64(buff[7] & 0xff)
+    
+    return ret
+  }
+  
+  public func read() throws -> Double {
+    let val = try read() as Int64
+    return unsafeBitCast(val, to: Double.self)
+  }
+  
+  public func read() throws -> Data {
+    let size = Int(try read() as Int32)
+    var data = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      data = try self.transport.readAll(size: size)
+    }
+    
+    return data
+  }
+  
+  // Write methods
+  
+  public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws {
+    if strictWrite {
+      let version = TBinaryProtocolVersion.version1 | Int32(messageType.rawValue)
+      try write(version)
+      try write(name)
+      try write(sequenceID)
+    } else {
+      try write(name)
+      try write(UInt8(messageType.rawValue))
+      try write(sequenceID)
+    }
+    currentMessageName = name
+  }
+  
+  public func writeMessageEnd() throws {
+    currentMessageName = nil
+  }
+  
+  public func writeStructBegin(name: String) throws {
+    return
+  }
+  
+  public func writeStructEnd() throws {
+    return
+  }
+  
+  public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws {
+    try write(UInt8(fieldType.rawValue))
+    try write(Int16(fieldID))
+  }
+  
+  public func writeFieldStop() throws {
+    try write(UInt8(TType.stop.rawValue))
+  }
+  
+  public func writeFieldEnd() throws {
+    return
+  }
+  
+  public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws {
+    try write(UInt8(keyType.rawValue))
+    try write(UInt8(valueType.rawValue))
+    try write(size)
+  }
+  
+  public func writeMapEnd() throws {
+    return
+  }
+  
+  public func writeSetBegin(elementType: TType, size: Int32) throws {
+    try write(UInt8(elementType.rawValue))
+    try write(size)
+  }
+  
+  public func writeSetEnd() throws {
+    return
+  }
+  
+  public func writeListBegin(elementType: TType, size: Int32) throws {
+    try write(UInt8(elementType.rawValue))
+    try write(size)
+  }
+  
+  public func writeListEnd() throws {
+    return
+  }
+  
+  public func write(_ value: String) throws {
+    try write(value.data(using: .utf8)!)
+  }
+  
+  public func write(_ value: Bool) throws {
+    let byteVal: UInt8 = value ? 1 : 0
+    try write(byteVal)
+  }
+  
+  public func write(_ value: UInt8) throws {
+    let buff = Data(bytes: [value])
+    
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
+      try self.transport.write(data: buff)
+    }
+  }
+  
+  public func write(_ value: Int16) throws {
+    var buff = Data()
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 8))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value))]))
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
+      try self.transport.write(data: buff)
+    }
+  }
+  
+  public func write(_ value: Int32) throws {
+    var buff = Data()
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 24))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 16))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 8))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value))]))
+    
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
+      try self.transport.write(data: buff)
+    }
+  }
+  
+  public func write(_ value: Int64) throws {
+    var buff = Data()
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 56))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 48))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 40))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 32))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 24))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 16))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value >> 8))]))
+    buff.append(Data(bytes: [UInt8(0xff & (value))]))
+    
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
+      try self.transport.write(data: buff)
+    }
+  }
+  
+  public func write(_ value: Double) throws {
+    // Notably unsafe, since Double and Int64 are the same size, this should work fine
+    try self.write(unsafeBitCast(value, to: Int64.self))
+  }
+  
+  public func write(_ data: Data) throws {
+    try write(Int32(data.count))
+    
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) {
+      try self.transport.write(data: data)
+    }
+  }
+}
diff --git a/lib/swift/Sources/TClient.swift b/lib/swift/Sources/TClient.swift
new file mode 100644
index 0000000..c404c9a
--- /dev/null
+++ b/lib/swift/Sources/TClient.swift
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+open class TClient {
+  public let inProtocol: TProtocol
+  public let outProtocol: TProtocol
+
+  public init(inoutProtocol: TProtocol) {
+    self.inProtocol = inoutProtocol
+    self.outProtocol = inoutProtocol
+  }
+
+  public init(inProtocol: TProtocol, outProtocol: TProtocol) {
+    self.inProtocol = inProtocol
+    self.outProtocol = outProtocol
+  }
+}
+
+
+open class TAsyncClient<Protocol: TProtocol, Factory: TAsyncTransportFactory> {
+  public var factory: Factory
+  public init(with protocol: Protocol.Type, factory: Factory) {
+    self.factory = factory
+  }
+}
+
+
+public enum TAsyncResult<T> {
+  case success(T)
+  case error(Swift.Error)
+  
+  public func value() throws -> T {
+    switch self {
+    case .success(let t): return t
+    case .error(let e): throw e
+    }
+  }
+}
diff --git a/lib/swift/Sources/TCompactProtocol.swift b/lib/swift/Sources/TCompactProtocol.swift
new file mode 100644
index 0000000..ac5b35a
--- /dev/null
+++ b/lib/swift/Sources/TCompactProtocol.swift
@@ -0,0 +1,575 @@
+/*
+* 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
+import CoreFoundation
+
+public enum TCType: UInt8 {
+  case stop          = 0x00
+  case boolean_TRUE  = 0x01
+  case boolean_FALSE = 0x02
+  case i8            = 0x03
+  case i16           = 0x04
+  case i32           = 0x05
+  case i64           = 0x06
+  case double        = 0x07
+  case binary        = 0x08
+  case list          = 0x09
+  case set           = 0x0A
+  case map           = 0x0B
+  case `struct`      = 0x0C
+  
+  public static let typeMask: UInt8 = 0xE0 // 1110 0000
+  public static let typeBits: UInt8 = 0x07 // 0000 0111
+  public static let typeShiftAmount = 5
+ 
+}
+
+
+public class TCompactProtocol: TProtocol {
+  public static let protocolID: UInt8  = 0x82
+  public static let version: UInt8     = 1
+  public static let versionMask: UInt8 = 0x1F // 0001 1111
+  
+  public var transport: TTransport
+  
+  var lastField: [UInt8] = []
+  var lastFieldId: UInt8 = 0
+  
+  var boolFieldName: String?
+  var boolFieldType: TType?
+  var boolFieldId: Int32?
+  var booleanValue: Bool?
+  
+  var currentMessageName: String?
+
+  public required init(on transport: TTransport) {
+    self.transport = transport
+  }
+
+  
+  /// Mark: - TCompactProtocol helpers
+  
+  func writebyteDirect(_ byte: UInt8) throws {
+    let byte = Data(bytes: [byte])
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) {
+      try self.transport.write(data: byte)
+    }
+  }
+  
+  func writeVarint32(_ val: UInt32) throws {
+    var val = val
+    var i32buf = [UInt8](repeating: 0, count: 5)
+    var idx = 0
+    while true {
+      if (val & ~0x7F) == 0 {
+        i32buf[idx] = UInt8(val)
+        idx += 1
+        break
+      } else {
+        i32buf[idx] = UInt8((val & 0x7F) | 0x80)
+        idx += 1
+        val >>= 7
+      }
+    }
+    
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) {
+      try self.transport.write(data: Data(bytes: i32buf[0..<idx]))
+    }
+  }
+  
+  func writeVarint64(_ val: UInt64) throws {
+    var val = val
+    var varint64out = [UInt8](repeating: 0, count: 10)
+    var idx = 0
+    while true {
+      if (val & ~0x7F) == 0{
+        varint64out[idx] = UInt8(val)
+        idx += 1
+        break
+      } else {
+        varint64out[idx] = UInt8(val & 0x7F) | 0x80
+        idx += 1
+        val >>= 7
+      }
+    }
+    
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) {
+      try self.transport.write(data: Data(bytes: varint64out[0..<idx]))
+    }
+  
+  }
+  
+  func writeCollectionBegin(_ elementType: TType, size: Int32) throws {
+    let ctype = compactType(elementType).rawValue
+    if size <= 14 {
+      try writebyteDirect(UInt8(size << 4) | ctype)
+    } else {
+      try writebyteDirect(0xF0 | ctype)
+      try writeVarint32(UInt32(size))
+    }
+  }
+  
+  func readBinary(_ size: Int) throws -> Data {
+    var result = Data()
+    if size != 0 {
+      try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+        result = try self.transport.readAll(size: size)
+      }
+    }
+    return result
+  }
+  
+  func readVarint32() throws -> UInt32 {
+    var result: UInt32 = 0
+    var shift: UInt32 = 0
+    while true {
+      let byte: UInt8 = try read()
+      
+      result |= UInt32(byte & 0x7F) << shift
+      if (byte & 0x80) == 0 {
+        break
+      }
+      
+      shift += 7
+    }
+    
+    return result
+  }
+  
+  func readVarint64() throws -> UInt64 {
+    var result: UInt64 = 0
+    var shift: UInt64 = 0
+    
+    while true {
+      let byte: UInt8 = try read()
+      
+      result |= UInt64(byte & 0x7F) << shift
+      if (byte & 0x80) == 0 {
+        break
+      }
+      
+      shift += 7
+    }
+    return result
+  }
+  
+
+  func ttype(_ compactTypeVal: UInt8) throws -> TType {
+    guard let compactType = TCType(rawValue: compactTypeVal) else {
+      throw TProtocolError(message: "Unknown TCType value: \(compactTypeVal)")
+    }
+    
+    switch compactType {
+    case .stop: return .stop;
+    case .boolean_FALSE, .boolean_TRUE: return .bool;
+    case .i8: return .i8;
+    case .i16: return .i16;
+    case .i32: return .i32;
+    case .i64: return .i64;
+    case .double: return .double;
+    case .binary: return .string;
+    case .list: return .list;
+    case .set: return .set;
+    case .map: return .map;
+    case .struct: return .struct;
+    }
+  }
+  
+  func compactType(_ ttype: TType) -> TCType {
+    switch ttype {
+    case .stop:   return .stop
+    case .void:   return .i8
+    case .bool:   return .boolean_FALSE
+    case .i8:   return .i8
+    case .double: return .double
+    case .i16:    return .i16
+    case .i32:    return .i32
+    case .i64:    return .i64
+    case .string: return .binary
+    case .struct: return .struct
+    case .map:    return .map
+    case .set:    return .set
+    case .list:   return .list
+    case .utf8:   return .binary
+    case .utf16:  return .binary
+    }
+  }
+  
+  /// ZigZag encoding maps signed integers to unsigned integers so that
+  /// numbers with a small absolute value (for instance, -1) have
+  /// a small varint encoded value too. It does this in a way that
+  /// "zig-zags" back and forth through the positive and negative integers,
+  /// so that -1 is encoded as 1, 1 is encoded as 2, -2 is encoded as 3, and so
+  ///
+  /// - parameter n: number to zigzag
+  ///
+  /// - returns: zigzaged UInt32
+  func i32ToZigZag(_ n : Int32) -> UInt32 {
+    return UInt32(n << 1) ^ UInt32(n >> 31)
+  }
+
+  func i64ToZigZag(_ n : Int64) -> UInt64 {
+    return UInt64(n << 1) ^ UInt64(n >> 63)
+  }
+
+  func zigZagToi32(_ n: UInt32) -> Int32 {
+    return Int32(n >> 1) ^ (-Int32(n & 1))
+  }
+  
+  func zigZagToi64(_ n: UInt64) -> Int64 {
+    return Int64(n >> 1) ^ (-Int64(n & 1))
+  }
+  
+  
+  
+  /// Mark: - TProtocol  
+  
+  public func readMessageBegin() throws -> (String, TMessageType, Int32) {
+    let protocolId: UInt8 = try read()
+    
+    if protocolId != TCompactProtocol.protocolID {
+      let expected = String(format:"%2X", TCompactProtocol.protocolID)
+      let got      = String(format:"%2X", protocolId)
+      throw TProtocolError(message: "Wrong Protocol ID \(got)",
+                           extendedError: .mismatchedProtocol(expected: expected, got: got))
+
+    }
+
+    let versionAndType: UInt8 = try read()
+    let version: UInt8 = versionAndType & TCompactProtocol.versionMask
+    if version != TCompactProtocol.version {
+      throw TProtocolError(error: .badVersion(expected: "\(TCompactProtocol.version)",
+                                              got:"\(version)"))
+
+    }
+    
+    let type = (versionAndType >> UInt8(TCType.typeShiftAmount)) & TCType.typeBits
+    guard let mtype = TMessageType(rawValue: Int32(type)) else {
+      throw TProtocolError(message: "Unknown TMessageType value: \(type)")
+    }
+    let sequenceId = try readVarint32()
+    let name: String = try read()
+    
+    return (name, mtype, Int32(sequenceId))
+  }
+  
+  public func readMessageEnd() throws { }
+  
+  public func readStructBegin() throws -> String {
+    lastField.append(lastFieldId)
+    lastFieldId = 0
+    return ""
+  }
+  
+  public func readStructEnd() throws {
+    lastFieldId = lastField.last ?? 0
+    lastField.removeLast()
+  }
+  
+  public func readFieldBegin() throws -> (String, TType, Int32) {
+    let byte: UInt8 = try read()
+    guard let type = TCType(rawValue: byte & 0x0F) else {
+      throw TProtocolError(message: "Unknown TCType \(byte & 0x0F)")
+    }
+    
+    // if it's a stop, then we can return immediately, as the struct is over
+    if type == .stop {
+      return ("", .stop, 0)
+    }
+    
+    var fieldId: Int16 = 0
+    
+    // mask off the 4MSB of the type header.  it could contain a field id delta
+    let modifier = (byte & 0xF0) >> 4
+    if modifier == 0 {
+      // not a delta.  look ahead for the zigzag varint field id
+      fieldId = try read()
+    } else {
+      // has a delta.  add the delta to the last Read field id.
+      fieldId = Int16(lastFieldId + modifier)
+    }
+    
+    let fieldType = try ttype(type.rawValue)
+    
+    // if this happens to be a boolean field, the value is encoded in the type
+    if type == .boolean_TRUE || type == .boolean_FALSE {
+      // save the boolean value in a special instance variable
+      booleanValue = type == .boolean_TRUE
+    }
+    
+    // push the new field onto the field stack so we can keep the deltas going
+    lastFieldId = UInt8(fieldId)
+    return ("", fieldType, Int32(fieldId))
+  }
+  
+  public func readFieldEnd() throws { }
+  
+  public func read() throws -> String {
+    let length = try readVarint32()
+    
+    var result: String
+    
+    if length != 0 {
+      let data = try readBinary(Int(length))
+      result = String(data: data, encoding: String.Encoding.utf8) ?? ""
+    } else {
+      result = ""
+    }
+    
+    return result
+  }
+  
+  public func read() throws -> Bool {
+    if let val = booleanValue {
+      self.booleanValue = nil
+      return val
+    } else {
+      let result = try read() as UInt8
+      return TCType(rawValue: result) == .boolean_TRUE
+    }
+  }
+  
+  public func read() throws -> UInt8 {
+    var buff: UInt8 = 0
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      buff = try self.transport.readAll(size: 1)[0]
+    }
+    return buff
+  }
+  
+  public func read() throws -> Int16 {
+    let v = try readVarint32()
+    return Int16(zigZagToi32(v))
+  }
+  
+  public func read() throws -> Int32 {
+    let v = try readVarint32()
+    return zigZagToi32(v)
+  }
+  
+  public func read() throws -> Int64 {
+    let v = try readVarint64()
+    return zigZagToi64(v)
+  }
+  
+  public func read() throws -> Double {
+    var buff = Data()
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) {
+      buff = try self.transport.readAll(size: 8)
+    }
+    
+    let i64: UInt64 = buff.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) -> UInt64 in
+      return UnsafePointer<UInt64>(OpaquePointer(ptr)).pointee
+    }
+    let bits = CFSwapInt64LittleToHost(i64)
+    return unsafeBitCast(bits, to: Double.self)
+  }
+  
+  public func read() throws -> Data {
+    let length = try readVarint32()
+    return try readBinary(Int(length))
+  }
+  
+  public func readMapBegin() throws -> (TType, TType, Int32) {
+    var keyAndValueType: UInt8 = 8
+    let size = try readVarint32()
+    if size != 0 {
+      keyAndValueType = try read()
+    }
+    
+    let keyType = try ttype(keyAndValueType >> 4)
+    let valueType = try ttype(keyAndValueType & 0xF)
+    
+    return (keyType, valueType, Int32(size))
+  }
+  
+  public func readMapEnd() throws { }
+  
+  public func readSetBegin() throws -> (TType, Int32) {
+    return try readListBegin()
+  }
+  
+  public func readSetEnd() throws { }
+  
+  public func readListBegin() throws -> (TType, Int32) {
+    let sizeAndType: UInt8 = try read()
+    var size: UInt32 = UInt32(sizeAndType >> 4) & 0x0f
+    if size == 15 {
+      size = try readVarint32()
+    }
+    let elementType = try ttype(sizeAndType & 0x0F)
+    
+    return (elementType, Int32(size))
+  }
+  
+  public func readListEnd() throws { }
+  
+  public func writeMessageBegin(name: String,
+                                type messageType: TMessageType,
+                                sequenceID: Int32) throws {
+    try writebyteDirect(TCompactProtocol.protocolID)
+    let nextByte: UInt8 = (TCompactProtocol.version & TCompactProtocol.versionMask) |
+                          (UInt8((UInt32(messageType.rawValue) << UInt32(TCType.typeShiftAmount))) &
+                          TCType.typeMask)
+    try writebyteDirect(nextByte)
+    try writeVarint32(UInt32(sequenceID))
+    try write(name)
+    
+    currentMessageName = name
+  }
+  
+  public func writeMessageEnd() throws {
+    currentMessageName = nil
+  }
+  
+  public func writeStructBegin(name: String) throws {
+    lastField.append(lastFieldId)
+    lastFieldId = 0
+  }
+  
+  public func writeStructEnd() throws {
+    lastFieldId = lastField.last ?? 0
+    lastField.removeLast()
+  }
+  
+  public func writeFieldBegin(name: String,
+                              type fieldType: TType,
+                              fieldID: Int32) throws {
+    if fieldType == .bool {
+      boolFieldName = name
+      boolFieldType = fieldType
+      boolFieldId = fieldID
+      return
+    } else {
+      try writeFieldBeginInternal(name: name,
+                                  type: fieldType,
+                                  fieldID: fieldID,
+                                  typeOverride: 0xFF)
+    }
+  }
+  
+  func writeFieldBeginInternal(name: String,
+                               type fieldType: TType,
+                               fieldID: Int32,
+                               typeOverride: UInt8) throws {
+    
+    let typeToWrite = typeOverride == 0xFF ? compactType(fieldType).rawValue : typeOverride
+    
+    // check if we can use delta encoding for the field id
+    let diff = UInt8(fieldID) - lastFieldId
+    if (UInt8(fieldID) > lastFieldId) && (diff <= 15) {
+      // Write them together
+      try writebyteDirect((UInt8(fieldID) - lastFieldId) << 4 | typeToWrite)
+      
+    } else {
+      // Write them separate
+      try writebyteDirect(typeToWrite)
+      try write(Int16(fieldID))
+    }
+    
+    lastFieldId = UInt8(fieldID)
+      
+  }
+  
+  public func writeFieldStop() throws {
+    try writebyteDirect(TCType.stop.rawValue)
+  }
+  
+  public func writeFieldEnd() throws { }
+  
+  public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws {
+    if size == 0 {
+      try writebyteDirect(0)
+    } else {
+      try writeVarint32(UInt32(size))
+      
+      let compactedTypes = compactType(keyType).rawValue << 4 | compactType(valueType).rawValue
+      try writebyteDirect(compactedTypes)
+    }
+  }
+  
+  public func writeMapEnd() throws { }
+  
+  public func writeSetBegin(elementType: TType, size: Int32) throws {
+    try writeCollectionBegin(elementType, size: size)
+  }
+  
+  public func writeSetEnd() throws { }
+  
+  public func writeListBegin(elementType: TType, size: Int32) throws {
+    try writeCollectionBegin(elementType, size: size)
+  }
+  
+  public func writeListEnd() throws { }
+  
+  public func write(_ value: String) throws {
+    try write(value.data(using: String.Encoding.utf8)!)
+  }
+  
+  public func write(_ value: Bool) throws {
+    if let boolFieldId = boolFieldId, let boolFieldType = boolFieldType,
+       let boolFieldName = boolFieldName {
+      
+      // we haven't written the field header yet
+      let compactType: TCType = value ? .boolean_TRUE : .boolean_FALSE
+      try writeFieldBeginInternal(name: boolFieldName, type: boolFieldType, fieldID: boolFieldId,
+                                  typeOverride: compactType.rawValue)
+      self.boolFieldId = nil
+      self.boolFieldType = nil
+      self.boolFieldName = nil
+    } else {
+      // we're not part of a field, so just write the value.
+      try writebyteDirect(value ? TCType.boolean_TRUE.rawValue : TCType.boolean_FALSE.rawValue)
+    }
+  }
+
+  public func write(_ value: UInt8) throws {
+    try writebyteDirect(value)
+  }
+
+  public func write(_ value: Int16) throws {
+    try writeVarint32(i32ToZigZag(Int32(value)))
+  }
+  
+  public func write(_ value: Int32) throws {
+    try writeVarint32(i32ToZigZag(value))
+  }
+  
+  public func write(_ value: Int64) throws {
+    try writeVarint64(i64ToZigZag(value))
+  }
+  
+  public func write(_ value: Double) throws {
+    var bits = CFSwapInt64HostToLittle(unsafeBitCast(value, to: UInt64.self))
+    let data = withUnsafePointer(to: &bits) {
+      return Data(bytes: UnsafePointer<UInt8>(OpaquePointer($0)), count: MemoryLayout<UInt64>.size)
+    }
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) {
+      try self.transport.write(data: data)
+    }
+  }
+  
+  public func write(_ data: Data) throws {
+    try writeVarint32(UInt32(data.count))
+    try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) {
+      try self.transport.write(data: data)
+    }
+  }
+}
diff --git a/lib/swift/Sources/TEnum.swift b/lib/swift/Sources/TEnum.swift
new file mode 100644
index 0000000..fedfdb1
--- /dev/null
+++ b/lib/swift/Sources/TEnum.swift
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+
+public protocol TEnum : TSerializable, Hashable {
+  var rawValue: Int32 { get }
+}
+
+extension TEnum {
+  public static var thriftType: TType { return .i32 }
+  public var hashValue: Int { return rawValue.hashValue }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(rawValue)
+  }
+}
diff --git a/lib/swift/Sources/TError.swift b/lib/swift/Sources/TError.swift
new file mode 100644
index 0000000..79edba6
--- /dev/null
+++ b/lib/swift/Sources/TError.swift
@@ -0,0 +1,77 @@
+/*
+* 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.
+*/
+
+
+/// TErrorCode
+///
+/// Protocol for TError conformers' enum's to conform to.
+/// Generic Int Thrift error code to allow error cases to have
+/// associated values.
+public protocol TErrorCode : CustomStringConvertible {
+  var thriftErrorCode: Int { get }
+}
+
+/// TError
+///
+/// Base protocol for all Thrift Error(Exception) types to conform to
+public protocol TError : Error, CustomStringConvertible {
+
+  /// Enum for error cases.  Can be typealiased to any conforming enum
+  /// or defined nested.
+  associatedtype Code: TErrorCode
+  
+  /// Error Case, value from internal enum
+  var error: Code { get set }
+  
+  /// Optional additional message
+  var message: String? { get set }
+  
+  /// Default error case for the error type, used for generic init()
+  static var defaultCase: Code { get }
+  
+  init()
+}
+
+extension TError {
+  /// Human readable description of error. Default provided for you in the
+  /// format \(Self.self): \(error.errorDescription) \n message
+  /// eg:
+  ///
+  ///     TApplicationError (1): Invalid Message Type
+  ///     An unknown Error has occured.
+  public var description: String {
+    var out = "\(Self.self) (\(error.thriftErrorCode)): " + error.description + "\n"
+    if let message = message {
+      out += "Message: \(message)"
+    }
+    return out
+  }
+
+  /// Simple default Initializer for TError's
+  ///
+  /// - parameter error:   ErrorCode value.  Default: defaultCase
+  /// - parameter message: Custom message with error.  Optional
+  ///
+  /// - returns: <#return value description#>
+  public init(error: Code, message: String? = nil) {
+    self.init()
+    self.error = error
+    self.message = message
+  }
+}
diff --git a/lib/swift/Sources/TFileHandleTransport.swift b/lib/swift/Sources/TFileHandleTransport.swift
new file mode 100644
index 0000000..f315fef
--- /dev/null
+++ b/lib/swift/Sources/TFileHandleTransport.swift
@@ -0,0 +1,56 @@
+/*
+* 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 class TFileHandleTransport: TTransport {
+  var inputFileHandle: FileHandle
+  var outputFileHandle: FileHandle
+  
+  public init(inputFileHandle: FileHandle, outputFileHandle: FileHandle) {
+    self.inputFileHandle = inputFileHandle
+    self.outputFileHandle = outputFileHandle
+  }
+  
+  public convenience init(fileHandle: FileHandle) {
+    self.init(inputFileHandle: fileHandle, outputFileHandle: fileHandle)
+  }
+  
+  public func read(size: Int) throws -> Data {
+    var data = Data()
+    while data.count < size {
+      let read = inputFileHandle.readData(ofLength: size - data.count)
+      data.append(read)
+      if read.count == 0 {
+        break
+      }
+    }
+    return data
+  }
+  
+  public func write(data: Data) throws {
+    outputFileHandle.write(data)
+  }
+  
+  public func flush() throws {
+    return
+  }
+}
+
+
diff --git a/lib/swift/Sources/TFileTransport.swift b/lib/swift/Sources/TFileTransport.swift
new file mode 100644
index 0000000..fe2253d
--- /dev/null
+++ b/lib/swift/Sources/TFileTransport.swift
@@ -0,0 +1,101 @@
+/*
+* 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
+
+#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
+  import Darwin
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+  import Glibc
+#endif
+
+/// TFileTransport
+/// Foundation-less Swift File transport.
+/// Uses C fopen/fread/fwrite,
+/// provided by Glibc in linux and Darwin on OSX/iOS
+public class TFileTransport: TTransport {
+  var fileHandle: UnsafeMutablePointer<FILE>? = nil
+  
+  public init (fileHandle: UnsafeMutablePointer<FILE>) {
+    self.fileHandle = fileHandle
+  }
+
+  public convenience init(filename: String) throws {
+    var fileHandle: UnsafeMutablePointer<FILE>?
+    filename.withCString({ cFilename in
+      "rw".withCString({ cMode in
+        fileHandle = fopen(cFilename, cMode)
+      })
+    })
+    if let fileHandle = fileHandle {
+      self.init(fileHandle: fileHandle)
+    } else {
+      throw TTransportError(error: .notOpen)
+    }
+  }
+  
+  deinit {
+    fclose(self.fileHandle)
+  }
+  
+  public func readAll(size: Int) throws -> Data {
+    let read = try self.read(size: size)
+    
+    if read.count != size {
+      throw TTransportError(error: .endOfFile)
+    }
+    return read
+  }
+  
+  public func read(size: Int) throws -> Data {
+    // set up read buffer, position 0
+    var read = Data(capacity: size)
+    var position = 0
+    
+    // read character buffer
+    var nextChar: UInt8 = 0
+    
+    // continue until we've read size bytes
+    while read.count < size {
+      if fread(&nextChar, 1, 1, self.fileHandle) == 1 {
+        read[position] = nextChar
+
+        // Increment output byte pointer
+        position += 1
+        
+      } else {
+        throw TTransportError(error: .endOfFile)
+      }
+    }
+    return read
+  }
+  
+  public func write(data: Data) throws {
+    let bytesWritten = data.withUnsafeBytes {
+      fwrite($0, 1, data.count, self.fileHandle)
+    }
+    if bytesWritten != data.count {
+      throw TTransportError(error: .unknown)
+    }
+  }
+  
+  public func flush() throws {
+    return
+  }
+}
diff --git a/lib/swift/Sources/TFramedTransport.swift b/lib/swift/Sources/TFramedTransport.swift
new file mode 100644
index 0000000..ca385d6
--- /dev/null
+++ b/lib/swift/Sources/TFramedTransport.swift
@@ -0,0 +1,123 @@
+/*
+* 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 class TFramedTransport: TTransport {
+  public static let headerSize    = 4
+  public static let initFrameSize = 1024
+  private static let defaultMaxLength = 16384000
+
+  public var transport: TTransport
+  private var writeBuffer = Data()
+
+  private var maxSize     = TFramedTransport.defaultMaxLength
+  private var remainingBytes = 0
+
+
+  public init(transport: TTransport, maxSize: Int) {
+    self.transport = transport
+    self.maxSize = maxSize
+  }
+
+  public convenience init(transport: TTransport) {
+    self.init(transport: transport, maxSize: TFramedTransport.defaultMaxLength)
+  }
+
+  func readHeader() throws {
+    let read = try transport.readAll(size: TFramedTransport.headerSize)
+    remainingBytes = Int(decodeFrameSize(data: read))
+  }
+
+  /// Mark: - TTransport
+
+  public func read(size: Int) throws -> Data {
+    while (remainingBytes <= 0) {
+        try readHeader()
+    }
+
+    let toRead = min(size, remainingBytes)
+
+    if toRead < 0 {
+        try close()
+        throw TTransportError(error: .negativeSize,
+                              message:  "Read a negative frame size (\(toRead))!")
+    }
+
+    if toRead > maxSize {
+        try close()
+        throw TTransportError(error: .sizeLimit(limit: maxSize, got: toRead))
+    }
+
+    return try transport.readAll(size: toRead)
+  }
+
+  public func flush() throws {
+    // copy buffer and reset
+    let buff = writeBuffer
+    writeBuffer = Data()
+
+    if buff.count - TFramedTransport.headerSize < 0 {
+      throw TTransportError(error: .unknown)
+    }
+
+    let frameSize = encodeFrameSize(size: UInt32(buff.count))
+
+    try transport.write(data: frameSize)
+    try transport.write(data: buff)
+    try transport.flush()
+  }
+
+  public func write(data: Data) throws {
+    writeBuffer.append(data)
+  }
+
+
+
+  private func encodeFrameSize(size: UInt32) -> Data {
+    var data = Data()
+    data.append(Data(bytes: [UInt8(0xff & (size >> 24))]))
+    data.append(Data(bytes: [UInt8(0xff & (size >> 16))]))
+    data.append(Data(bytes: [UInt8(0xff & (size >> 8))]))
+    data.append(Data(bytes: [UInt8(0xff & (size))]))
+
+    return data
+  }
+
+  private func decodeFrameSize(data: Data) -> UInt32 {
+    var size: UInt32
+    size  = (UInt32(data[0] & 0xff) << 24)
+    size |= (UInt32(data[1] & 0xff) << 16)
+    size |= (UInt32(data[2] & 0xff) <<  8)
+    size |= (UInt32(data[3] & 0xff))
+    return size
+  }
+
+  public func close() throws {
+    try transport.close()
+  }
+
+  public func open() throws {
+    try transport.open()
+  }
+
+  public func isOpen() throws -> Bool {
+    return try transport.isOpen()
+  }
+}
diff --git a/lib/swift/Sources/THTTPSessionTransport.swift b/lib/swift/Sources/THTTPSessionTransport.swift
new file mode 100644
index 0000000..3c0af8e
--- /dev/null
+++ b/lib/swift/Sources/THTTPSessionTransport.swift
@@ -0,0 +1,184 @@
+/*
+* 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
+import Dispatch
+
+
+public class THTTPSessionTransport: TAsyncTransport {
+  public class Factory : TAsyncTransportFactory {
+    public var responseValidate: ((HTTPURLResponse?, Data?) throws -> Void)?
+    
+    var session: URLSession
+    var url: URL
+    
+    public class func setupDefaultsForSessionConfiguration(_ config: URLSessionConfiguration, withProtocolName protocolName: String?) {
+      var thriftContentType = "application/x-thrift"
+      
+      if let protocolName = protocolName {
+        thriftContentType += "; p=\(protocolName)"
+      }
+      
+      config.requestCachePolicy = .reloadIgnoringLocalCacheData
+      config.urlCache = nil
+      
+      config.httpShouldUsePipelining  = true
+      config.httpShouldSetCookies     = true
+      config.httpAdditionalHeaders    = ["Content-Type": thriftContentType,
+                                         "Accept": thriftContentType,
+                                         "User-Agent": "Thrift/Swift (Session)"]
+      
+      
+    }
+    
+    public init(session: URLSession, url: URL) {
+      self.session = session
+      self.url = url
+    }
+    
+    public func newTransport() -> THTTPSessionTransport {
+      return THTTPSessionTransport(factory: self)
+    }
+    
+    func validateResponse(_ response: HTTPURLResponse?, data: Data?) throws {
+      try responseValidate?(response, data)
+    }
+    
+    func taskWithRequest(_ request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> ()) throws -> URLSessionTask {
+      
+      let newTask: URLSessionTask? = session.dataTask(with: request, completionHandler: completionHandler)
+      if let newTask = newTask {
+        return newTask
+      } else {
+        throw TTransportError(error: .unknown, message: "Failed to create session data task")
+      }
+    }    
+  }
+  
+  var factory: Factory
+  var requestData = Data()
+  var responseData = Data()
+  var responseDataOffset: Int = 0
+  
+  init(factory: Factory) {
+    self.factory = factory
+  }
+  
+  public func readAll(size: Int) throws -> Data {
+    let read = try self.read(size: size)
+    if read.count != size {
+      throw TTransportError(error: .endOfFile)
+    }
+    return read
+  }
+  
+  public func read(size: Int) throws -> Data {
+    let avail = responseData.count - responseDataOffset
+    let (start, stop) = (responseDataOffset, responseDataOffset + min(size, avail))
+    let read = responseData.subdata(in: start..<stop)
+    responseDataOffset += read.count
+    return read
+  }
+  
+  public func write(data: Data) throws {
+    requestData.append(data)
+  }
+  
+  public func flush(_ completed: @escaping (TAsyncTransport, Error?) -> Void) {
+    var error: Error?
+    var task: URLSessionTask?
+    
+    var request = URLRequest(url: factory.url)
+    request.httpMethod = "POST"
+    request.httpBody =  requestData
+
+    requestData = Data()
+
+    do {
+      task = try factory.taskWithRequest(request, completionHandler: { (data, response, taskError) in
+
+        // Check if there was an error with the network
+        if taskError != nil {
+            error = TTransportError(error: .timedOut)
+            completed(self, error)
+            return
+        }
+
+        // Check response type
+        if taskError == nil && !(response is HTTPURLResponse) {
+            error = THTTPTransportError(error: .invalidResponse)
+            completed(self, error)
+            return
+        }
+        
+        // Check status code
+        if let httpResponse = response as? HTTPURLResponse {
+          if taskError == nil && httpResponse.statusCode != 200 {
+            if httpResponse.statusCode == 401 {
+              error = THTTPTransportError(error: .authentication)
+            } else {
+              error = THTTPTransportError(error: .invalidStatus(statusCode: httpResponse.statusCode))
+            }
+          }
+          
+          // Allow factory to check
+          if error != nil {
+            do {
+              try self.factory.validateResponse(httpResponse, data: data)
+            } catch let validateError {
+              error = validateError
+            }
+          }
+          
+          self.responseDataOffset = 0
+          if error != nil {
+            self.responseData = Data()
+          } else {
+            self.responseData = data ?? Data()
+          }
+          completed(self, error)
+        }
+      })
+      
+    } catch let taskError {
+      error = taskError
+    }
+    
+    if let error = error, task == nil {
+      completed(self, error)
+    }
+    task?.resume()
+  }
+
+  public func flush() throws {
+    let completed = DispatchSemaphore(value: 0)
+    var internalError: Error?
+    
+    flush() { _, error in
+      internalError = error
+      completed.signal()
+    }
+    
+    _ = completed.wait(timeout: DispatchTime.distantFuture)
+    
+    if let error = internalError {
+      throw error
+    }
+  }
+}
diff --git a/lib/swift/Sources/TList.swift b/lib/swift/Sources/TList.swift
new file mode 100644
index 0000000..0077156
--- /dev/null
+++ b/lib/swift/Sources/TList.swift
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+public struct TList<Element : TSerializable> : RandomAccessCollection, MutableCollection, ExpressibleByArrayLiteral, TSerializable, Hashable {
+  typealias Storage = Array<Element>
+  public typealias Indices = Storage.Indices
+
+  internal var storage = Storage()
+  public init() { }
+  public init(arrayLiteral elements: Element...) {
+    self.storage = Storage(elements)
+  }
+  public init<Source : Sequence>(_ sequence: Source) where Source.Iterator.Element == Element {
+    storage = Storage(sequence)
+  }
+
+  /// Mark: Hashable
+  public var hashValue : Int {
+    let prime = 31
+    var result = 1
+    for element in storage {
+      result = prime &* result &+ element.hashValue
+    }
+    return result
+  }
+  
+  /// Mark: TSerializable
+  public static var thriftType : TType { return .list }
+
+  public static func read(from proto: TProtocol) throws -> TList {
+    let (elementType, size) = try proto.readListBegin()
+    if elementType != Element.thriftType {
+      throw TProtocolError(error: .invalidData,
+                           extendedError: .unexpectedType(type: elementType))
+    }
+    var list = TList()
+    for _ in 0..<size {
+      let element = try Element.read(from: proto)
+      list.storage.append(element)
+    }
+    try proto.readListEnd()
+    return list
+  }
+  
+  public func write(to proto: TProtocol) throws {
+    try proto.writeListBegin(elementType: Element.thriftType, size: Int32(self.count))
+    for element in self.storage {
+      try Element.write(element, to: proto)
+    }
+    try proto.writeListEnd()
+  }
+
+  /// Mark: MutableCollection
+  
+  public typealias SubSequence = Storage.SubSequence
+  public typealias Index = Storage.Index
+  
+  public subscript(position: Storage.Index) -> Element {
+    get {
+      return storage[position]
+    }
+    set {
+      storage[position] = newValue
+    }
+  }
+  
+  public subscript(range: Range<Index>) -> SubSequence {
+    get {
+      return storage[range]
+    }
+    set {
+      storage[range] = newValue
+    }
+  }
+  
+  public var startIndex: Index {
+    return storage.startIndex
+  }
+  public var endIndex: Index {
+    return storage.endIndex
+  }
+  
+  public func formIndex(after i: inout Index) {
+    storage.formIndex(after: &i)
+  }
+  
+  public func formIndex(before i: inout Int) {
+    storage.formIndex(before: &i)
+  }
+  
+  public func index(after i: Index) -> Index {
+    return storage.index(after: i)
+  }
+
+  public func index(before i: Int) -> Int {
+    return storage.index(before: i)
+  }
+
+}
+
+extension TList : RangeReplaceableCollection {
+  public mutating func replaceSubrange<C: Collection>(_ subrange: Range<Index>, with newElements: C)
+    where C.Iterator.Element == Element {
+    storage.replaceSubrange(subrange, with: newElements)
+  }
+}
+
+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.elementsEqual(rhs.storage) { $0 == $1 }
+}
diff --git a/lib/swift/Sources/TMap.swift b/lib/swift/Sources/TMap.swift
new file mode 100644
index 0000000..f8b02d2
--- /dev/null
+++ b/lib/swift/Sources/TMap.swift
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+public struct TMap<Key : TSerializable & Hashable, Value : TSerializable>: Collection, ExpressibleByDictionaryLiteral, Hashable, TSerializable {
+  typealias Storage = Dictionary<Key, Value>
+  public typealias Element = Storage.Element
+  public typealias Index = Storage.Index
+  public typealias IndexDistance = Storage.IndexDistance
+  public typealias Indices = Storage.Indices
+  public typealias SubSequence = Storage.SubSequence
+  internal var storage = Storage()
+  
+  /// Mark: Be Like Dictionary
+  
+  public func indexForKey(_ key: Key) -> Index? {
+    return storage.index(forKey: key)
+  }
+  
+  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.removeValue(forKey: key)
+  }
+  
+  public init(minimumCapacity: Int) {
+    storage = Storage(minimumCapacity: minimumCapacity)
+  }
+  
+  /// init from Dictionary<K,V>
+  public init(_ dict: [Key: Value]) {
+    storage = dict
+  }
+
+  /// read only access to storage if needed as Dictionary<K,V>
+  public var dictionary: [Key: Value] {
+    return storage
+  }
+  
+  public subscript (key: Key) -> Value? {
+    get {
+      return storage[key]
+    }
+    set {
+      storage[key] = newValue
+    }
+  }
+  
+  /// Mark: Collection
+  
+  public var indices: Indices {
+    return storage.indices
+  }
+  
+  public func distance(from start: Index, to end: Index) -> IndexDistance {
+    return storage.distance(from: start, to: end)
+  }
+  
+  public func index(_ i: Index, offsetBy n: IndexDistance) -> Index {
+    return storage.index(i, offsetBy: n)
+  }
+  
+  public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? {
+    return storage.index(i, offsetBy: n, limitedBy: limit)
+  }
+  
+  public subscript(position: Index) -> Element {
+    return storage[position]
+  }
+  
+  /// Mark: IndexableBase
+  
+  public var startIndex: Index { return storage.startIndex }
+  public var endIndex: Index { return storage.endIndex }
+  public func index(after i: Index) -> Index {
+    return storage.index(after: i)
+  }
+  
+  public func formIndex(after i: inout Index) {
+    storage.formIndex(after: &i)
+  }
+  
+  public subscript(bounds: Range<Index>) -> SubSequence {
+    return storage[bounds]
+  }
+  
+  /// Mark: DictionaryLiteralConvertible
+  
+  public init(dictionaryLiteral elements: (Key, Value)...) {
+    storage = Storage()
+    for (key, value) in elements {
+      storage[key] = value
+    }
+  }
+
+  /// Mark: Hashable
+  
+  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
+  }
+  
+  /// Mark: TSerializable
+  
+  public static var thriftType : TType { return .map }
+  public init() {
+    storage = Storage()
+  }
+   
+  public static func read(from proto: TProtocol) throws -> TMap {
+
+    let (keyType, valueType, size) = try proto.readMapBegin()
+    if size > 0 {
+      if keyType != Key.thriftType {
+        throw TProtocolError(error: .invalidData,
+                             message: "Unexpected TMap Key Type",
+                             extendedError: .unexpectedType(type: keyType))
+      }
+      if valueType != Value.thriftType {
+        throw TProtocolError(error: .invalidData,
+                             message: "Unexpected TMap Value Type",
+                             extendedError: .unexpectedType(type: valueType))
+      }
+    }
+
+    var map = TMap()
+    for _ in 0..<size {
+      let key = try Key.read(from: proto)
+      let value = try Value.read(from: proto)
+      map.storage[key] = value
+    }
+    try proto.readMapEnd()
+    return map
+  }
+  
+  public func write(to proto: TProtocol) throws {
+    try proto.writeMapBegin(keyType: Key.thriftType,
+                            valueType: Value.thriftType, size: Int32(self.count))
+    for (key, value) in self.storage {
+      try Key.write(key, to: proto)
+      try Value.write(value, to: proto)
+    }
+    try proto.writeMapEnd()
+  }
+}
+
+/// Mark: CustomStringConvertible, CustomDebugStringConvertible
+
+extension TMap : CustomStringConvertible, CustomDebugStringConvertible {
+  
+  public var description : String {
+    return storage.description
+  }
+  
+  public var debugDescription : String {
+    return storage.debugDescription
+  }
+  
+}
+
+/// Mark: Equatable
+
+public func ==<Key, Value>(lhs: TMap<Key,Value>, rhs: TMap<Key, Value>) -> Bool {
+  if lhs.count != rhs.count {
+    return false
+  }
+  return lhs.storage.elementsEqual(rhs.storage) { $0.key == $1.key && $0.value == $1.value }
+}
diff --git a/lib/swift/Sources/TMemoryBufferTransport.swift b/lib/swift/Sources/TMemoryBufferTransport.swift
new file mode 100644
index 0000000..bd58b6e
--- /dev/null
+++ b/lib/swift/Sources/TMemoryBufferTransport.swift
@@ -0,0 +1,74 @@
+/*
+ * 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 class TMemoryBufferTransport : TTransport {
+  public private(set) var readBuffer = Data()
+  public private(set) var writeBuffer = Data()
+  
+  public private(set) var position = 0
+
+  public var bytesRemainingInBuffer: Int {
+    return readBuffer.count - position
+  }
+  
+  public func consumeBuffer(size: Int) {
+    position += size
+  }
+  public func clear() {
+    readBuffer = Data()
+    writeBuffer = Data()
+  }
+  
+  
+  private var flushHandler: ((TMemoryBufferTransport, Data) -> ())?
+  
+  public init(flushHandler: ((TMemoryBufferTransport, Data) -> ())? = nil) {
+    self.flushHandler = flushHandler
+  }
+  
+  public convenience init(readBuffer: Data, flushHandler: ((TMemoryBufferTransport, Data) -> ())? = nil) {
+    self.init()
+    self.readBuffer = readBuffer
+  }
+  
+  public func reset(readBuffer: Data = Data(), writeBuffer: Data = Data()) {
+    self.readBuffer = readBuffer
+    self.writeBuffer = writeBuffer
+  }
+  
+  public func read(size: Int) throws -> Data {
+    let amountToRead = min(bytesRemainingInBuffer, size)
+    if amountToRead > 0 {
+      let ret = readBuffer.subdata(in: Range(uncheckedBounds: (lower: position, upper: position + amountToRead)))
+      position += ret.count
+      return ret
+    }
+    return Data()
+  }
+  
+  public func write(data: Data) throws {
+    writeBuffer.append(data)
+  }
+  
+  public func flush() throws {
+    flushHandler?(self, writeBuffer)
+  }
+}
diff --git a/lib/swift/Sources/TMultiplexedProtocol.swift b/lib/swift/Sources/TMultiplexedProtocol.swift
new file mode 100644
index 0000000..73a8d51
--- /dev/null
+++ b/lib/swift/Sources/TMultiplexedProtocol.swift
@@ -0,0 +1,47 @@
+/*
+* 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.
+*/
+
+public class TMultiplexedProtocol<Protocol: TProtocol>: TWrappedProtocol<Protocol> {
+  public let separator = ":"
+
+  public var serviceName = ""
+  
+  public convenience init(on transport: TTransport, serviceName: String) {
+    self.init(on: transport)
+    self.serviceName = serviceName    
+  }
+
+  override public func writeMessageBegin(name: String,
+                                         type messageType: TMessageType,
+                                         sequenceID: Int32) throws {
+    switch messageType {
+    case .call, .oneway:
+      var serviceFunction = serviceName
+      serviceFunction += serviceName == "" ? "" : separator
+      serviceFunction += name
+      return try super.writeMessageBegin(name: serviceFunction,
+                                         type: messageType,
+                                         sequenceID: sequenceID)
+    default:
+      return try super.writeMessageBegin(name: name,
+                                         type: messageType,
+                                         sequenceID: sequenceID)
+    }
+  }
+}
diff --git a/lib/swift/Sources/TProcessor.swift b/lib/swift/Sources/TProcessor.swift
new file mode 100644
index 0000000..7ff222e
--- /dev/null
+++ b/lib/swift/Sources/TProcessor.swift
@@ -0,0 +1,29 @@
+/*
+* 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.
+*/
+
+
+public typealias TProcessorMessageHandler<T> = (Int, TProtocol, TProtocol, T) -> Void
+
+public protocol TProcessor {
+  associatedtype Service
+  var service: Service { get set }
+  func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws
+  init(service: Service)
+}
+
diff --git a/lib/swift/Sources/TProtocol.swift b/lib/swift/Sources/TProtocol.swift
new file mode 100644
index 0000000..a4e4a20
--- /dev/null
+++ b/lib/swift/Sources/TProtocol.swift
@@ -0,0 +1,182 @@
+/*
+* 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 enum TMessageType: Int32 {
+  case call = 1
+  case reply = 2
+  case exception = 3
+  case oneway = 4
+}
+
+public enum TType: Int32 {
+  case stop     = 0
+  case void     = 1
+  case bool     = 2
+  case i8       = 3
+  case double   = 4
+  case i16      = 6
+  case i32      = 8
+  case i64      = 10
+  case string   = 11
+  case `struct` = 12
+  case map      = 13
+  case set      = 14
+  case list     = 15
+  case utf8     = 16
+  case utf16    = 17
+}
+
+public protocol TProtocol {
+  var transport: TTransport { get set }
+  init(on transport: TTransport)
+  // Reading Methods
+  
+  func readMessageBegin() throws -> (String, TMessageType, Int32)
+  func readMessageEnd() throws
+  func readStructBegin() throws -> String
+  func readStructEnd() throws
+  func readFieldBegin() throws -> (String, TType, Int32)
+  func readFieldEnd() throws
+  func readMapBegin() throws -> (TType, TType, Int32)
+  func readMapEnd() throws
+  func readSetBegin() throws -> (TType, Int32)
+  func readSetEnd() throws
+  func readListBegin() throws -> (TType, Int32)
+  func readListEnd() throws
+  
+  func read() throws -> String
+  func read() throws -> Bool
+  func read() throws -> UInt8
+  func read() throws -> Int16
+  func read() throws -> Int32
+  func read() throws -> Int64
+  func read() throws -> Double
+  func read() throws -> Data
+  
+  // Writing methods
+  
+  func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws
+  func writeMessageEnd() throws
+  func writeStructBegin(name: String) throws
+  func writeStructEnd() throws
+  func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws
+  func writeFieldStop() throws
+  func writeFieldEnd() throws
+  func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws
+  func writeMapEnd() throws
+  func writeSetBegin(elementType: TType, size: Int32) throws
+  func writeSetEnd() throws
+  func writeListBegin(elementType: TType, size: Int32) throws
+  func writeListEnd() throws
+
+  func write(_ value: String) throws
+  func write(_ value: Bool) throws
+  func write(_ value: UInt8) throws
+  func write(_ value: Int16) throws
+  func write(_ value: Int32) throws
+  func write(_ value: Int64) throws
+  func write(_ value: Double) throws
+  func write(_ value: Data) throws
+}
+
+public extension TProtocol {
+  public func writeFieldValue(_ value: TSerializable, name: String, type: TType, id: Int32) throws {
+    try writeFieldBegin(name: name, type: type, fieldID: id)
+    try value.write(to: self)
+    try writeFieldEnd()
+  }
+
+  public func validateValue(_ value: Any?, named name: String) throws {
+    if value == nil {
+      throw TProtocolError(error: .unknown, message: "Missing required value for field: \(name)")
+    }
+  }
+  
+  public func readResultMessageBegin() throws {
+    let (_, type, _) = try readMessageBegin();
+    if type == .exception {
+      let x = try readException()
+      throw x
+    }
+    return
+  }
+  
+  public func readException() throws -> TApplicationError {
+    return try TApplicationError.read(from: self)
+  }
+  
+  public func writeException(messageName name: String, sequenceID: Int32, ex: TApplicationError) throws {
+    try writeMessageBegin(name: name, type: .exception, sequenceID: sequenceID)
+    try ex.write(to: self)
+    try writeMessageEnd()
+  }
+  
+  public func skip(type: TType) throws {
+    switch type {
+    case .bool:   _ = try read() as Bool
+    case .i8:   _ = try read() as UInt8
+    case .i16:    _ = try read() as Int16
+    case .i32:    _ = try read() as Int32
+    case .i64:    _ = try read() as Int64
+    case .double: _ = try read() as Double
+    case .string: _ = try read() as String
+      
+    case .struct:
+      _ = try readStructBegin()
+      while true {
+        let (_, fieldType, _) = try readFieldBegin()
+        if fieldType == .stop {
+          break
+        }
+        try skip(type: fieldType)
+        try readFieldEnd()
+      }
+      try readStructEnd()
+      
+      
+    case .map:
+      let (keyType, valueType, size) = try readMapBegin()
+      for _ in 0..<size {
+        try skip(type: keyType)
+        try skip(type: valueType)
+      }
+      try readMapEnd()
+      
+      
+    case .set:
+      let (elemType, size) = try readSetBegin()
+      for _ in 0..<size {
+        try skip(type: elemType)
+      }
+      try readSetEnd()
+      
+    case .list:
+      let (elemType, size) = try readListBegin()
+      for _ in 0..<size {
+        try skip(type: elemType)
+      }
+      try readListEnd()
+    default:
+      return
+    }
+  }
+}
diff --git a/lib/swift/Sources/TProtocolError.swift b/lib/swift/Sources/TProtocolError.swift
new file mode 100644
index 0000000..a5d14f9
--- /dev/null
+++ b/lib/swift/Sources/TProtocolError.swift
@@ -0,0 +1,146 @@
+/*
+* 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 TProtocolError : TError {
+  public init() { }
+
+  public enum Code : TErrorCode {
+    case unknown
+    case invalidData
+    case negativeSize
+    case sizeLimit(limit: Int, got: Int)
+    case badVersion(expected: String, got: String)
+    case notImplemented
+    case depthLimit
+
+    public var thriftErrorCode: Int {
+      switch self {
+      case .unknown:        return 0
+      case .invalidData:    return 1
+      case .negativeSize:   return 2
+      case .sizeLimit:      return 3
+      case .badVersion:     return 4
+      case .notImplemented: return 5
+      case .depthLimit:     return 6
+      }
+
+    }
+    public var description: String {
+      switch self {
+      case .unknown:        return "Unknown TProtocolError"
+      case .invalidData:    return "Invalid Data"
+      case .negativeSize:   return "Negative Size"
+      case .sizeLimit(let limit, let got):
+        return "Message exceeds size limit of \(limit) (received: \(got)"
+      case .badVersion(let expected, let got):
+        return "Bad Version. (Expected: \(expected), Got: \(got)"
+      case .notImplemented: return "Not Implemented"
+      case .depthLimit:     return "Depth Limit"
+      }
+    }
+  }
+
+  public enum ExtendedErrorCode : TErrorCode {
+    case unknown
+    case missingRequiredField(fieldName: String)
+    case unexpectedType(type: TType)
+    case mismatchedProtocol(expected: String, got: String)
+    public var thriftErrorCode: Int {
+      switch self {
+      case .unknown:              return 1000
+      case .missingRequiredField: return 1001
+      case .unexpectedType:       return 1002
+      case .mismatchedProtocol:   return 1003
+      }
+    }
+    public var description: String {
+      switch self {
+      case .unknown:                                    return "Unknown TProtocolExtendedError"
+      case .missingRequiredField(let fieldName):        return "Missing Required Field: \(fieldName)"
+      case .unexpectedType(let type):                   return "Unexpected Type \(type.self)"
+      case .mismatchedProtocol(let expected, let got):  return "Mismatched Protocol.  (Expected: \(expected), got \(got))"
+      }
+    }
+  }
+
+  public var extendedError: ExtendedErrorCode? = nil
+
+  public init(error: Code = .unknown,
+              message: String? = nil,
+              extendedError: ExtendedErrorCode? = nil) {
+    self.error = error
+    self.message = message
+    self.extendedError = extendedError
+  }
+
+  /// Mark: TError
+  public var error: Code = .unknown
+  public var message: String? = nil
+  public static var defaultCase: Code { return .unknown }
+
+  public var description: String {
+    var out = "\(TProtocolError.self):  (\(error.thriftErrorCode) \(error.description)\n"
+    if let extendedError = extendedError {
+      out += "TProtocolExtendedError (\(extendedError.thriftErrorCode)): \(extendedError.description)"
+    }
+    if let message = message {
+      out += "Message: \(message)"
+    }
+    return out
+  }
+}
+
+
+/// Wrapper for Transport errors in Protocols.  Inspired by Thrift-Cocoa PROTOCOL_TRANSPORT_ERROR
+/// macro.  Modified to be more Swift-y.  Catches any TError thrown within the block and
+/// rethrows a given TProtocolError, the original error's description is appended to the new
+/// TProtocolError's message.  sourceFile, sourceLine, sourceMethod are auto-populated and should
+/// be ignored when calling.
+///
+/// - parameter error:        TProtocolError to throw if the block throws
+/// - parameter sourceFile:   throwing file, autopopulated
+/// - parameter sourceLine:   throwing line, autopopulated
+/// - parameter sourceMethod: throwing method, autopopulated
+/// - parameter block:        throwing block
+///
+/// - throws: TProtocolError  Default is TProtocolError.ErrorCode.unknown.  Underlying
+///                           error's description appended to TProtocolError.message
+func ProtocolTransportTry(error: TProtocolError = TProtocolError(),
+                          sourceFile: String = #file,
+                          sourceLine: Int = #line,
+                          sourceMethod: String = #function,
+                          block: () throws -> ()) throws {
+  // Need mutable copy
+  var error = error
+  do {
+    try block()
+  } catch let err as TError {
+    var message = error.message ?? ""
+    message += "\nFile: \(sourceFile)\n"
+    message += "Line: \(sourceLine)\n"
+    message += "Method: \(sourceMethod)"
+    message += "\nOriginal Error:\n" + err.description
+    error.message = message
+    throw error
+  }
+}
+
+
diff --git a/lib/swift/Sources/TSSLSocketTransport.swift b/lib/swift/Sources/TSSLSocketTransport.swift
new file mode 100644
index 0000000..c2b5902
--- /dev/null
+++ b/lib/swift/Sources/TSSLSocketTransport.swift
@@ -0,0 +1,229 @@
+/*
+* 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
+import CoreFoundation
+
+#if os(Linux)
+public class TSSLSocketTransport {
+  init(hostname: String, port: UInt16) {
+    // FIXME!
+    assert(false, "Security not available in Linux, TSSLSocketTransport Unavilable for now")
+  }
+}
+#else
+let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian
+let htons  = isLittleEndian ? _OSSwapInt16 : { $0 }
+let htonl  = isLittleEndian ? _OSSwapInt32 : { $0 }
+
+public class TSSLSocketTransport: TStreamTransport {
+  var sslHostname: String
+  var sd: Int32 = 0
+  
+  public init(hostname: String, port: UInt16) throws {
+    sslHostname = hostname
+    var readStream: Unmanaged<CFReadStream>?
+    var writeStream: Unmanaged<CFWriteStream>?
+    
+    /* create a socket structure */
+    var pin: sockaddr_in = sockaddr_in()
+    var hp: UnsafeMutablePointer<hostent>? = nil
+    for i in 0..<10 {
+      
+      hp = gethostbyname(hostname.cString(using: String.Encoding.utf8)!)
+      if hp == nil {
+        print("failed to resolve hostname \(hostname)")
+        herror("resolv")
+        if i == 9 {
+          super.init(inputStream: nil, outputStream: nil) // have to init before throwing
+          throw TSSLSocketTransportError(error: .hostanameResolution(hostname: hostname))
+        }
+        Thread.sleep(forTimeInterval: 0.2)
+      } else {
+        break
+      }
+    }
+    pin.sin_family  = UInt8(AF_INET)
+    pin.sin_addr    = in_addr(s_addr: UInt32((hp?.pointee.h_addr_list.pointee?.pointee)!)) // Is there a better way to get this???
+    pin.sin_port    = htons(port)
+    
+    /* create the socket */
+    sd = socket(Int32(AF_INET), Int32(SOCK_STREAM), Int32(IPPROTO_TCP))
+    if sd == -1 {
+      super.init(inputStream: nil, outputStream: nil) // have to init before throwing
+      throw TSSLSocketTransportError(error: .socketCreate(port: Int(port)))
+    }
+    
+    /* open a connection */
+    // need a non-self ref to sd, otherwise the j complains
+    let sd_local = sd
+    let connectResult = withUnsafePointer(to: &pin) {
+      connect(sd_local, UnsafePointer<sockaddr>(OpaquePointer($0)), socklen_t(MemoryLayout<sockaddr_in>.size))
+    }
+    if connectResult == -1 {
+      super.init(inputStream: nil, outputStream: nil) // have to init before throwing
+      throw TSSLSocketTransportError(error: .connect)
+    }
+    
+    CFStreamCreatePairWithSocket(kCFAllocatorDefault, sd, &readStream, &writeStream)
+    
+    CFReadStreamSetProperty(readStream?.takeRetainedValue(), .socketNativeHandle, kCFBooleanTrue)
+    CFWriteStreamSetProperty(writeStream?.takeRetainedValue(), .socketNativeHandle, kCFBooleanTrue)
+    
+    var inputStream: InputStream? = nil
+    var outputStream: OutputStream? = nil
+    if readStream != nil && writeStream != nil {
+      
+      CFReadStreamSetProperty(readStream?.takeRetainedValue(),
+                              .socketSecurityLevel,
+                              kCFStreamSocketSecurityLevelTLSv1)
+      
+      let settings: [String: Bool] = [kCFStreamSSLValidatesCertificateChain as String: true]
+      
+      CFReadStreamSetProperty(readStream?.takeRetainedValue(),
+                              .SSLSettings,
+                              settings as CFTypeRef!)
+      
+      CFWriteStreamSetProperty(writeStream?.takeRetainedValue(),
+                              .SSLSettings,
+                              settings as CFTypeRef!)
+      
+      inputStream = readStream!.takeRetainedValue()
+      inputStream?.schedule(in: .current, forMode: .defaultRunLoopMode)
+      inputStream?.open()
+      
+      outputStream = writeStream!.takeRetainedValue()
+      outputStream?.schedule(in: .current, forMode: .defaultRunLoopMode)
+      outputStream?.open()
+      
+      readStream?.release()
+      writeStream?.release()
+    }
+    
+    
+    super.init(inputStream: inputStream, outputStream: outputStream)
+    self.input?.delegate = self
+    self.output?.delegate = self
+  }
+  
+  func recoverFromTrustFailure(_ myTrust: SecTrust, lastTrustResult: SecTrustResultType) -> Bool {
+    let trustTime = SecTrustGetVerifyTime(myTrust)
+    let currentTime = CFAbsoluteTimeGetCurrent()
+    
+    let timeIncrement = 31536000 // from TSSLSocketTransport.m
+    let newTime = currentTime - Double(timeIncrement)
+    
+    if trustTime - newTime != 0 {
+      let newDate = CFDateCreate(nil, newTime)
+      SecTrustSetVerifyDate(myTrust, newDate!)
+      
+      var tr = lastTrustResult
+      let success = withUnsafeMutablePointer(to: &tr) { trPtr -> Bool in
+        if SecTrustEvaluate(myTrust, trPtr) != errSecSuccess {
+          return false
+        }
+        return true
+      }
+      if !success { return false }
+    }
+    if lastTrustResult == .proceed || lastTrustResult == .unspecified {
+        return false
+    }
+
+    print("TSSLSocketTransport: Unable to recover certificate trust failure")
+    return true
+  }
+  
+  public func isOpen() -> Bool {
+    return sd > 0
+  }
+}
+
+extension TSSLSocketTransport: StreamDelegate {
+  public func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
+    
+    switch eventCode {
+    case Stream.Event(): break
+    case Stream.Event.hasBytesAvailable: break
+    case Stream.Event.openCompleted: break
+    case Stream.Event.hasSpaceAvailable:
+      var proceed = false
+      var trustResult: SecTrustResultType = .invalid
+
+      var newPolicies: CFMutableArray?
+      
+      repeat {
+        let trust: SecTrust = aStream.property(forKey: .SSLPeerTrust) as! SecTrust
+        
+        // Add new policy to current list of policies
+        let policy = SecPolicyCreateSSL(false, sslHostname as CFString?)
+        var ppolicy = policy // mutable for pointer
+        let policies: UnsafeMutablePointer<CFArray?>? = nil
+        if SecTrustCopyPolicies(trust, policies!) != errSecSuccess {
+          break
+        }
+        withUnsafeMutablePointer(to: &ppolicy) { ptr in
+          newPolicies = CFArrayCreateMutableCopy(nil, 0, policies?.pointee)
+          CFArrayAppendValue(newPolicies, ptr)
+        }
+        
+        // update trust policies
+        if SecTrustSetPolicies(trust, newPolicies!) != errSecSuccess {
+          break
+        }
+        
+        // Evaluate the trust chain
+        let success = withUnsafeMutablePointer(to: &trustResult) { trustPtr -> Bool in
+          if SecTrustEvaluate(trust, trustPtr) != errSecSuccess {
+            return false
+          }
+          return true
+        }
+        
+        if !success {
+          break
+        }
+        
+        
+        switch trustResult {
+        case .proceed:      proceed = true
+        case .unspecified:  proceed = true
+        case .recoverableTrustFailure:
+          proceed = self.recoverFromTrustFailure(trust, lastTrustResult: trustResult)
+          
+        case .deny:         break
+        case .fatalTrustFailure: break
+        case .otherError:   break
+        case .invalid:      break
+        default: break
+        }
+      } while false
+  
+      if !proceed {
+        print("TSSLSocketTransport: Cannot trust certificate.  Result: \(trustResult)")
+        aStream.close()
+      }
+      
+    case Stream.Event.errorOccurred: break
+    case Stream.Event.endEncountered: break
+    default: break
+    }
+  }
+}
+#endif
diff --git a/lib/swift/Sources/TSSLSocketTransportError.swift b/lib/swift/Sources/TSSLSocketTransportError.swift
new file mode 100644
index 0000000..fda162b
--- /dev/null
+++ b/lib/swift/Sources/TSSLSocketTransportError.swift
@@ -0,0 +1,48 @@
+/*
+* 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.
+*/
+
+public struct TSSLSocketTransportError: TError {
+  public enum ErrorCode: TErrorCode {
+    case hostanameResolution(hostname: String)
+    case socketCreate(port: Int)
+    case connect
+  
+    public var thriftErrorCode: Int {
+      switch self {
+      case .hostanameResolution:  return -10000
+      case .socketCreate:         return -10001
+      case .connect:              return -10002
+      }
+    }
+  
+    public var description: String {
+      switch self {
+      case .hostanameResolution(let hostname):  return "Failed to resolve hostname: \(hostname)"
+      case .socketCreate(let port):             return "Could not create socket on port: \(port)"
+      case .connect:                            return "Connect error"
+      }
+    }
+  
+  }
+  public var error: ErrorCode = .connect
+  public var message: String?
+  public static var defaultCase: ErrorCode { return .connect }
+  
+  public init() { }
+}
diff --git a/lib/swift/Sources/TSerializable.swift b/lib/swift/Sources/TSerializable.swift
new file mode 100644
index 0000000..b45096b
--- /dev/null
+++ b/lib/swift/Sources/TSerializable.swift
@@ -0,0 +1,136 @@
+/*
+ * 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 {
+  var hashValue: Int { get }
+
+  /// TType for instance
+  static var thriftType: TType { get }
+
+  /// Read TSerializable instance from Protocol
+  static func read(from proto: TProtocol) throws -> Self
+
+  /// Write TSerializable instance to Protocol
+  func write(to proto: TProtocol) throws
+
+}
+
+extension TSerializable {
+  public static func write(_ value: Self, to proto: TProtocol) throws {
+    try value.write(to: proto)
+  }
+
+  /// convenience for member access
+  public var thriftType: TType { return Self.thriftType }
+}
+
+public func ==<T>(lhs: T, rhs: T) -> Bool where T : TSerializable {
+  return lhs.hashValue == rhs.hashValue
+}
+
+/// Default read/write for primitave Thrift types:
+/// Bool, Int8 (byte), Int16, Int32, Int64, Double, String
+
+extension Bool : TSerializable {
+  public static var thriftType: TType { return .bool }
+
+  public static func read(from proto: TProtocol) throws -> Bool {
+    return try proto.read()
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
+
+extension Int8 : TSerializable {
+  public static var thriftType: TType { return .i8 }
+
+  public static func read(from proto: TProtocol) throws -> Int8 {
+    return Int8(try proto.read() as UInt8)
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(UInt8(self))
+  }
+}
+
+extension Int16 : TSerializable {
+  public static var thriftType: TType { return .i16 }
+
+  public static func read(from proto: TProtocol) throws -> Int16 {
+    return try proto.read()
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
+
+extension Int32 : TSerializable {
+  public static var thriftType: TType { return .i32 }
+
+  public static func read(from proto: TProtocol) throws -> Int32 {
+    return try proto.read()
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
+
+
+extension Int64 : TSerializable {
+  public static var thriftType: TType { return .i64 }
+
+  public static func read(from proto: TProtocol) throws -> Int64 {
+    return try proto.read()
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
+
+extension Double : TSerializable {
+  public static var thriftType: TType { return .double }
+
+  public static func read(from proto: TProtocol) throws -> Double {
+    return try proto.read()
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
+
+extension String : TSerializable {
+  public static var thriftType: TType { return .string }
+
+  public static func read(from proto: TProtocol) throws -> String {
+    return try proto.read()
+  }
+
+  public func write(to proto: TProtocol) throws {
+    try proto.write(self)
+  }
+}
diff --git a/lib/swift/Sources/TSet.swift b/lib/swift/Sources/TSet.swift
new file mode 100644
index 0000000..3e014c1
--- /dev/null
+++ b/lib/swift/Sources/TSet.swift
@@ -0,0 +1,189 @@
+/*
+ * 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 & Hashable> : SetAlgebra, Hashable, Collection, ExpressibleByArrayLiteral, TSerializable {
+  /// Typealias for Storage type
+  typealias Storage = Set<Element>
+  
+  
+  /// Internal Storage used for TSet (Set\<Element\>)
+  internal var storage : Storage
+  
+  
+  /// Mark: Collection
+  
+  public typealias Indices = Storage.Indices
+  public typealias Index = Storage.Index
+  public typealias IndexDistance = Storage.IndexDistance
+  public typealias SubSequence = Storage.SubSequence
+  
+  
+  public var indices: Indices { return storage.indices }
+  
+  // Must implement isEmpty even though both SetAlgebra and Collection provide it due to their conflciting default implementations
+  public var isEmpty: Bool { return storage.isEmpty }
+  
+  public func distance(from start: Index, to end: Index) -> IndexDistance {
+    return storage.distance(from: start, to: end)
+  }
+  
+  public func index(_ i: Index, offsetBy n: IndexDistance) -> Index {
+    return storage.index(i, offsetBy: n)
+  }
+  
+  public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? {
+    return storage.index(i, offsetBy: n, limitedBy: limit)
+  }
+  
+  #if swift(>=3.2)
+  public subscript (position: Storage.Index) -> Element {
+      return storage[position]
+    }
+  #else
+  public subscript (position: Storage.Index) -> Element? {
+    return storage[position]
+  }
+  #endif
+  
+  /// Mark: SetAlgebra
+  internal init(storage: Set<Element>) {
+    self.storage = storage
+  }
+  
+  public func contains(_ member: Element) -> Bool {
+    return storage.contains(member)
+  }
+  
+  public mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element) {
+    return storage.insert(newMember)
+  }
+  
+  public mutating func remove(_ member: Element) -> Element? {
+    return storage.remove(member)
+  }
+  
+  public func union(_ other: TSet<Element>) -> TSet {
+    return TSet(storage: storage.union(other.storage))
+  }
+  
+  public mutating func formIntersection(_ other: TSet<Element>) {
+    return storage.formIntersection(other.storage)
+  }
+  
+  public mutating func formSymmetricDifference(_ other: TSet<Element>) {
+    return storage.formSymmetricDifference(other.storage)
+  }
+  
+  public mutating func formUnion(_ other: TSet<Element>) {
+    return storage.formUnion(other.storage)
+  }
+  
+  public func intersection(_ other: TSet<Element>) -> TSet {
+    return TSet(storage: storage.intersection(other.storage))
+  }
+  
+  public func symmetricDifference(_ other: TSet<Element>) -> TSet {
+    return TSet(storage: storage.symmetricDifference(other.storage))
+  }
+  
+  public mutating func update(with newMember: Element) -> Element? {
+    return storage.update(with: newMember)
+  }
+  
+  /// Mark: IndexableBase
+  
+  public var startIndex: Index { return storage.startIndex }
+  public var endIndex: Index { return storage.endIndex }
+  public func index(after i: Index) -> Index {
+    return storage.index(after: i)
+  }
+
+  public func formIndex(after i: inout Storage.Index) {
+    storage.formIndex(after: &i)
+  }
+  
+  public subscript(bounds: Range<Index>) -> SubSequence {
+    return storage[bounds]
+  }
+
+  
+  /// Mark: Hashable
+  public var hashValue : Int {
+    let prime = 31
+    var result = 1
+    for element in storage {
+      result = prime &* result &+ element.hashValue
+    }
+    return result
+  }
+  
+  /// Mark: TSerializable
+  public static var thriftType : TType { return .set }
+  
+  public init() {
+    storage = Storage()
+  }
+  
+  public init(arrayLiteral elements: Element...) {
+    self.storage = Storage(elements)
+  }
+  
+  public init<Source : Sequence>(_ sequence: Source) where Source.Iterator.Element == Element {
+    storage = Storage(sequence)
+  }
+  
+  public static func read(from proto: TProtocol) throws -> TSet {
+    let (elementType, size) = try proto.readSetBegin()
+    if elementType != Element.thriftType {
+      throw TProtocolError(error: .invalidData,
+                           extendedError: .unexpectedType(type: elementType))
+    }
+    var set = TSet()
+    for _ in 0..<size {
+      let element = try Element.read(from: proto)
+      set.storage.insert(element)
+    }
+    try proto.readSetEnd()
+    return set
+  }
+  
+  public func write(to proto: TProtocol) throws {
+    try proto.writeSetBegin(elementType: Element.thriftType, size: Int32(self.count))
+    for element in self.storage {
+      try Element.write(element, to: 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
+}
diff --git a/lib/swift/Sources/TSocketServer.swift b/lib/swift/Sources/TSocketServer.swift
new file mode 100644
index 0000000..0224e67
--- /dev/null
+++ b/lib/swift/Sources/TSocketServer.swift
@@ -0,0 +1,149 @@
+/*
+* 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.
+*/
+
+#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
+  import Darwin
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+  import Glibc
+  import Dispatch
+#endif
+
+import Foundation
+import CoreFoundation
+
+public let TSocketServerClientConnectionFinished = "TSocketServerClientConnectionFinished"
+public let TSocketServerProcessorKey = "TSocketServerProcessor"
+public let TSocketServerTransportKey = "TSocketServerTransport"
+
+class TSocketServer<InProtocol: TProtocol, OutProtocol: TProtocol, Processor: TProcessor, Service> where Processor.Service == Service {
+  var socketFileHandle: FileHandle
+  var processingQueue =  DispatchQueue(label: "TSocketServer.processing",
+                                       qos: .background,
+                                       attributes: .concurrent)
+  var serviceHandler: Service
+
+  public init(port: Int,
+              service: Service,
+              inProtocol: InProtocol.Type,
+              outProtocol: OutProtocol.Type,
+              processor: Processor.Type) throws {
+    // set service handler
+    self.serviceHandler = service
+
+    // create a socket
+    var fd: Int32 = -1
+    #if os(Linux)
+      let sock = CFSocketCreate(kCFAllocatorDefault, PF_INET, Int32(SOCK_STREAM.rawValue), Int32(IPPROTO_TCP), 0, nil, nil)
+    #else
+      let sock = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, 0, nil, nil)
+    #endif
+    if sock != nil {
+      CFSocketSetSocketFlags(sock, CFSocketGetSocketFlags(sock) & ~kCFSocketCloseOnInvalidate)
+
+      fd = CFSocketGetNative(sock)
+      var yes = 1
+      setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, UInt32(MemoryLayout<Int>.size))
+
+      #if os(Linux)
+        var addr = sockaddr_in(sin_family: sa_family_t(AF_INET),
+                               sin_port: in_port_t(port.bigEndian),
+                               sin_addr: in_addr(s_addr: in_addr_t(0)),
+                               sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
+      #else
+        var addr = sockaddr_in(sin_len: UInt8(MemoryLayout<sockaddr_in>.size),
+                               sin_family: sa_family_t(AF_INET),
+                               sin_port: in_port_t(port.bigEndian),
+                               sin_addr: in_addr(s_addr: in_addr_t(0)),
+                               sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
+      #endif
+
+      let ptr = withUnsafePointer(to: &addr) {
+        return UnsafePointer<UInt8>(OpaquePointer($0))
+      }
+
+      let address = Data(bytes: ptr, count: MemoryLayout<sockaddr_in>.size)
+
+      let cfaddr = address.withUnsafeBytes {
+        CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, $0, address.count, nil)
+      }
+      if CFSocketSetAddress(sock, cfaddr) != CFSocketError.success { //kCFSocketSuccess {
+        CFSocketInvalidate(sock)
+        print("TSocketServer: Could not bind to address")
+        throw TTransportError(error: .notOpen, message: "Could not bind to address")
+      }
+
+    } else {
+      print("TSocketServer: No server socket")
+      throw TTransportError(error: .notOpen, message: "Could not create socket")
+    }
+
+    // wrap it in a file handle so we can get messages from it
+    socketFileHandle = FileHandle(fileDescriptor: fd, closeOnDealloc: true)
+
+    // throw away our socket
+    CFSocketInvalidate(sock)
+
+    // register for notifications of accepted incoming connections
+    _ = NotificationCenter.default.addObserver(forName: .NSFileHandleConnectionAccepted,
+                                               object: nil, queue: nil) {
+                                                [weak self] notification in
+                                                guard let strongSelf = self else { return }
+                                                strongSelf.connectionAccepted(strongSelf.socketFileHandle)
+
+    }
+
+    // tell socket to listen
+    socketFileHandle.acceptConnectionInBackgroundAndNotify()
+
+    print("TSocketServer: Listening on TCP port \(port)")
+  }
+
+  deinit {
+    NotificationCenter.default.removeObserver(self)
+  }
+
+  func connectionAccepted(_ socket: FileHandle) {
+    // Now that we have a client connected, handle the request on queue
+    processingQueue.async {
+      self.handleClientConnection(socket)
+    }
+  }
+
+  func handleClientConnection(_ clientSocket: FileHandle) {
+
+    let transport = TFileHandleTransport(fileHandle: clientSocket)
+    let processor = Processor(service: serviceHandler)
+
+    let inProtocol = InProtocol(on: transport)
+    let outProtocol = OutProtocol(on: transport)
+
+    do {
+      try processor.process(on: inProtocol, outProtocol: outProtocol)
+    } catch let error {
+      print("Error processign request: \(error)")
+    }
+    DispatchQueue.main.async {
+      NotificationCenter.default
+        .post(name: Notification.Name(rawValue: TSocketServerClientConnectionFinished),
+              object: self,
+              userInfo: [TSocketServerProcessorKey: processor,
+                         TSocketServerTransportKey: transport])
+    }
+  }
+}
diff --git a/lib/swift/Sources/TSocketTransport.swift b/lib/swift/Sources/TSocketTransport.swift
new file mode 100644
index 0000000..891bd27
--- /dev/null
+++ b/lib/swift/Sources/TSocketTransport.swift
@@ -0,0 +1,210 @@
+
+/*
+ * 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.
+ */
+
+
+#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
+  import Darwin
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+  import Glibc
+  import Dispatch
+#endif
+
+import Foundation
+import CoreFoundation
+
+private struct Sys {
+  #if os(Linux)
+  static let read = Glibc.read
+  static let write = Glibc.write
+  static let close = Glibc.close
+  #else
+  static let read = Darwin.read
+  static let write = Darwin.write
+  static let close = Darwin.close
+  #endif
+}
+
+extension in_addr {
+  public init?(hostent: hostent?) {
+    guard let host = hostent, host.h_addr_list != nil, host.h_addr_list.pointee != nil else {
+      return nil
+    }
+    self.init()
+    memcpy(&self, host.h_addr_list.pointee!, Int(host.h_length))
+    
+  }
+}
+
+
+#if os(Linux)
+  /// TCFSocketTransport currently unavailable
+  /// remove comments and build to see why/fix
+  /// currently CF[Read|Write]Stream's can't cast to [Input|Output]Streams which breaks thigns
+#else
+extension Stream.PropertyKey {
+  static let SSLPeerTrust = Stream.PropertyKey(kCFStreamPropertySSLPeerTrust as String)
+}
+
+/// TCFSocketTransport, uses CFSockets and (NS)Stream's
+public class TCFSocketTransport: TStreamTransport {
+    public init?(hostname: String, port: Int, secure: Bool = false) {
+    
+    var inputStream: InputStream
+    var outputStream: OutputStream
+    
+    var readStream:  Unmanaged<CFReadStream>?
+    var writeStream:  Unmanaged<CFWriteStream>?
+    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
+                                       hostname as CFString!,
+                                       UInt32(port),
+                                       &readStream,
+                                       &writeStream)
+    
+    if let readStream = readStream?.takeRetainedValue(),
+      let writeStream = writeStream?.takeRetainedValue() {
+        CFReadStreamSetProperty(readStream, .shouldCloseNativeSocket, kCFBooleanTrue)
+        CFWriteStreamSetProperty(writeStream, .shouldCloseNativeSocket, kCFBooleanTrue)
+      
+        if secure {
+            CFReadStreamSetProperty(readStream, .socketSecurityLevel, StreamSocketSecurityLevel.negotiatedSSL._rawValue)
+            CFWriteStreamSetProperty(writeStream, .socketSecurityLevel, StreamSocketSecurityLevel.negotiatedSSL._rawValue)
+        }
+
+      inputStream = readStream as InputStream
+      inputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
+      inputStream.open()
+      
+      outputStream = writeStream as OutputStream
+      outputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
+      outputStream.open()
+      
+    } else {
+      
+      if readStream != nil {
+        readStream?.release()
+      }
+      if writeStream != nil {
+        writeStream?.release()
+      }
+      super.init(inputStream: nil, outputStream: nil)
+      return nil
+    }
+    
+    super.init(inputStream: inputStream, outputStream: outputStream)
+    
+    self.input?.delegate = self
+    self.output?.delegate = self
+  }
+}
+
+extension TCFSocketTransport: StreamDelegate { }
+#endif
+
+
+/// TSocketTransport, posix sockets.  Supports IPv4 only for now
+public class TSocketTransport : TTransport {
+  public var socketDescriptor: Int32
+  
+  
+  
+  /// Initialize from an already set up socketDescriptor.
+  /// Expects socket thats already bound/connected (i.e. from listening)
+  ///
+  /// - parameter socketDescriptor: posix socket descriptor (Int32)
+  public init(socketDescriptor: Int32) {
+    self.socketDescriptor = socketDescriptor
+  }
+  
+  
+  public convenience init(hostname: String, port: Int) throws {
+    guard let hp = gethostbyname(hostname.cString(using: .utf8)!)?.pointee,
+      let hostAddr = in_addr(hostent: hp) else {
+        throw TTransportError(error: .unknown, message: "Invalid address: \(hostname)")
+    }
+    
+    
+    
+    #if os(Linux)
+      let sock = socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0)
+      var addr = sockaddr_in(sin_family: sa_family_t(AF_INET),
+                             sin_port: in_port_t(htons(UInt16(port))),
+                             sin_addr: hostAddr,
+                             sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
+    #else
+      let sock = socket(AF_INET, SOCK_STREAM, 0)
+      
+      var addr = sockaddr_in(sin_len: UInt8(MemoryLayout<sockaddr_in>.size),
+                             sin_family: sa_family_t(AF_INET),
+                             sin_port: in_port_t(htons(UInt16(port))),
+                             sin_addr: in_addr(s_addr: in_addr_t(0)),
+                             sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
+      
+    #endif
+    
+    let addrPtr = withUnsafePointer(to: &addr){ UnsafePointer<sockaddr>(OpaquePointer($0)) }
+    
+    let connected = connect(sock, addrPtr, UInt32(MemoryLayout<sockaddr_in>.size))
+    if connected != 0 {
+      throw TTransportError(error: .notOpen, message: "Error binding to host: \(hostname) \(port)")
+    }
+    
+    self.init(socketDescriptor: sock)
+  }
+  
+  deinit {
+    close()
+  }
+  
+  public func readAll(size: Int) throws -> Data {
+    var out = Data()
+    while out.count < size {
+      out.append(try self.read(size: size))
+    }
+    return out
+  }
+  
+  public func read(size: Int) throws -> Data {
+    var buff = Array<UInt8>.init(repeating: 0, count: size)
+    let readBytes = Sys.read(socketDescriptor, &buff, size)
+    
+    return Data(bytes: buff[0..<readBytes])
+  }
+  
+  public func write(data: Data) {
+    var bytesToWrite = data.count
+    var writeBuffer = data
+    while bytesToWrite > 0 {
+      let written = writeBuffer.withUnsafeBytes {
+        Sys.write(socketDescriptor, $0, writeBuffer.count)
+      }
+      writeBuffer = writeBuffer.subdata(in: written ..< writeBuffer.count)
+      bytesToWrite -= written
+    }
+  }
+  
+  public func flush() throws {
+    // nothing to do
+  }
+  
+  public func close() {
+    shutdown(socketDescriptor, Int32(SHUT_RDWR))
+    _ = Sys.close(socketDescriptor)
+  }
+}
diff --git a/lib/swift/Sources/TStreamTransport.swift b/lib/swift/Sources/TStreamTransport.swift
new file mode 100644
index 0000000..26bc1b8
--- /dev/null
+++ b/lib/swift/Sources/TStreamTransport.swift
@@ -0,0 +1,143 @@
+/*
+ * 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
+import CoreFoundation
+
+#if os(Linux)
+  /// Currently unavailable in Linux
+  /// Remove comments and build to fix
+  /// Currently kConstants for CFSockets don't exist in linux and not all have been moved
+  /// to property structs yet
+#else
+  // Must inherit NSObject for NSStreamDelegate conformance
+  public class TStreamTransport : NSObject, TTransport {
+    public var input: InputStream? = nil
+    public var output: OutputStream? = nil
+    
+    public init(inputStream: InputStream?, outputStream: OutputStream?) {
+      input   = inputStream
+      output  = outputStream
+    }
+    
+    public convenience init(inputStream: InputStream?) {
+      self.init(inputStream: inputStream, outputStream: nil)
+    }
+    
+    public convenience init(outputStream: OutputStream?) {
+      self.init(inputStream: nil, outputStream: outputStream)
+    }
+    
+    deinit {
+      close()
+    }
+    
+    public func readAll(size: Int) throws -> Data {
+      guard let input = input else {
+        throw TTransportError(error: .unknown)
+      }
+      
+      var read = Data()
+      while read.count < size {
+        var buffer = Array<UInt8>(repeating: 0, count: size - read.count)
+        
+        let bytesRead = buffer.withUnsafeMutableBufferPointer { bufferPtr in
+          return input.read(bufferPtr.baseAddress!, maxLength: size - read.count)
+        }
+        
+        if bytesRead <= 0 {
+          throw TTransportError(error: .notOpen)
+        }
+        read.append(Data(bytes: buffer))
+      }
+      return read
+    }
+    
+    public func read(size: Int) throws -> Data {
+      guard let input = input else {
+        throw TTransportError(error: .unknown)
+      }
+      
+      var read = Data()
+      while read.count < size {
+        var buffer = Array<UInt8>(repeating: 0, count: size - read.count)
+        let bytesRead = buffer.withUnsafeMutableBufferPointer {
+          input.read($0.baseAddress!, maxLength: size - read.count)
+        }
+        
+        if bytesRead <= 0 {
+          break
+        }
+        
+        read.append(Data(bytes: buffer))
+      }
+      return read
+    }
+    
+    public func write(data: Data) throws {
+      guard let output = output else {
+        throw TTransportError(error: .unknown)
+      }
+      
+      var bytesWritten = 0
+      while bytesWritten < data.count {
+        bytesWritten = data.withUnsafeBytes {
+          return output.write($0, maxLength: data.count)
+        }
+        
+        if bytesWritten == -1 {
+          throw TTransportError(error: .notOpen)
+        } else if bytesWritten == 0 {
+          throw TTransportError(error: .endOfFile)
+        }
+      }
+    }
+    
+    
+    public func flush() throws {
+      return
+    }
+    
+    public func close() {
+      
+      if input != nil {
+        // Close and reset inputstream
+        if let cf: CFReadStream = input {
+          CFReadStreamSetProperty(cf, .shouldCloseNativeSocket, kCFBooleanTrue)
+        }
+        
+        input?.delegate = nil
+        input?.close()
+        input?.remove(from: .current, forMode: .defaultRunLoopMode)
+        input = nil
+      }
+      
+      if output != nil {
+        // Close and reset output stream
+        if let cf: CFWriteStream = output {
+          CFWriteStreamSetProperty(cf, .shouldCloseNativeSocket, kCFBooleanTrue)
+        }
+        output?.delegate = nil
+        output?.close()
+        output?.remove(from: .current, forMode: .defaultRunLoopMode)
+        output = nil
+      }
+    }
+  }
+#endif
diff --git a/lib/swift/Sources/TStruct.swift b/lib/swift/Sources/TStruct.swift
new file mode 100644
index 0000000..f172a32
--- /dev/null
+++ b/lib/swift/Sources/TStruct.swift
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+
+/// Protocol for Generated Structs to conform to
+/// Dictionary maps field names to internal IDs and uses Reflection
+/// to iterate through all fields.  
+/// `writeFieldValue(_:name:type:id:)` calls `TSerializable.write(to:)` internally
+/// giving a nice recursive behavior for nested TStructs, TLists, TMaps, and TSets
+public protocol TStruct : TSerializable {
+  static var fieldIds: [String: Int32] { get }
+  static var structName: String { get }
+}
+
+public extension TStruct {
+  public static var fieldIds: [String: (id: Int32, type: TType)] { return [:] }
+  public static var thriftType: TType { return .struct }
+  
+  public func write(to proto: TProtocol) throws {
+    // Write struct name first
+    try proto.writeStructBegin(name: Self.structName)
+    
+    try self.forEach { name, value, id in
+      // Write to protocol
+      try proto.writeFieldValue(value, name: name,
+                                type: value.thriftType, id: id)
+    }
+    try proto.writeFieldStop()
+    try proto.writeStructEnd()
+  }
+  
+  public var hashValue: Int {
+    let prime = 31
+    var result = 1
+    self.forEach { _, value, _ in
+      result = prime &* result &+ (value.hashValue)
+    }
+    return result
+  }
+  
+  /// Provides a block for handling each (available) thrift property using reflection
+  /// Caveat: Skips over optional values
+  
+  
+  /// Provides a block for handling each (available) thrift property using reflection
+  ///
+  /// - parameter block: block for handling property
+  ///
+  /// - throws: rethrows any Error thrown in block
+  private func forEach(_ block: (_ name: String, _ value: TSerializable, _ id: Int32) throws -> Void) rethrows {
+    // Mirror the object, getting (name: String?, value: Any) for every property
+    let mirror = Mirror(reflecting: self)
+    
+    // Iterate through all children, ignore empty property names
+    for (propName, propValue) in mirror.children {
+      guard let propName = propName else { continue }
+
+      if let tval = unwrap(any: propValue) as? TSerializable, let id = Self.fieldIds[propName] {
+        try block(propName, tval, id)
+      }
+    }
+  }
+  
+  
+  /// Any can mysteriously be an Optional<Any> at the same time,
+  /// this checks and always returns Optional<Any> without double wrapping
+  /// we then try to bind value as TSerializable to ignore any extension properties
+  /// and the like and verify the property exists and grab the Thrift
+  /// property ID at the same time
+  ///
+  /// - parameter any: Any instance to attempt to unwrap
+  ///
+  /// - returns: Unwrapped Any as Optional<Any>
+  private func unwrap(any: Any) -> Any? {
+    let mi = Mirror(reflecting: any)
+    
+    if mi.displayStyle != .optional { return any }
+    if mi.children.count == 0 { return nil }
+    
+    let (_, some) = mi.children.first!
+    return some
+  }
+}
+
diff --git a/lib/swift/Sources/TTransport.swift b/lib/swift/Sources/TTransport.swift
new file mode 100644
index 0000000..e82bbe1
--- /dev/null
+++ b/lib/swift/Sources/TTransport.swift
@@ -0,0 +1,64 @@
+/*
+* 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 TTransport {
+  
+  // Required
+  func read(size: Int) throws -> Data
+  func write(data: Data) throws
+  func flush() throws
+
+  // Optional (default provided)
+  func readAll(size: Int) throws -> Data
+  func isOpen() throws -> Bool
+  func open() throws
+  func close() throws
+}
+
+public extension TTransport {
+  func isOpen() throws -> Bool { return true }
+  func open() throws { }
+  func close() throws { }
+  
+  func readAll(size: Int) throws -> Data {
+    var buff = Data()
+    var have = 0
+    while have < size {
+      let chunk = try self.read(size: size - have)
+      have += chunk.count
+      buff.append(chunk)
+      if chunk.count == 0 {
+        throw TTransportError(error: .endOfFile)
+      }
+    }
+    return buff
+  }
+}
+
+public protocol TAsyncTransport : TTransport {
+  // Factory
+  func flush(_ completion: @escaping (TAsyncTransport, Error?) ->())
+}
+
+public protocol TAsyncTransportFactory {
+  associatedtype Transport : TAsyncTransport
+  func newTransport() -> Transport
+}
diff --git a/lib/swift/Sources/TTransportError.swift b/lib/swift/Sources/TTransportError.swift
new file mode 100644
index 0000000..3fd0059
--- /dev/null
+++ b/lib/swift/Sources/TTransportError.swift
@@ -0,0 +1,86 @@
+/*
+* 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.
+*/
+
+public struct TTransportError: TError {
+  public enum ErrorCode: TErrorCode {
+    case unknown
+    case notOpen
+    case alreadyOpen
+    case timedOut
+    case endOfFile
+    case negativeSize
+    case sizeLimit(limit: Int, got: Int)
+    
+    public var thriftErrorCode: Int {
+      switch self {
+      case .unknown:      return 0
+      case .notOpen:      return 1
+      case .alreadyOpen:  return 2
+      case .timedOut:     return 3
+      case .endOfFile:    return 4
+      case .negativeSize: return 5
+      case .sizeLimit:    return 6
+      }
+    }
+    public var description: String {
+      switch self {
+      case .unknown:      return "Unknown TTransportError"
+      case .notOpen:      return "Not Open"
+      case .alreadyOpen:  return "Already Open"
+      case .timedOut:     return "Timed Out"
+      case .endOfFile:    return "End Of File"
+      case .negativeSize: return "Negative Size"
+      case .sizeLimit(let limit, let got):
+        return "Message exceeds size limit of \(limit) (received: \(got)"
+      }
+    }
+  }
+  public var error: ErrorCode = .unknown
+  public var message: String? = nil
+  public static var defaultCase: ErrorCode { return .unknown }
+  
+  public init() { }
+
+}
+
+/// THTTPTransportError
+///
+/// Error's thrown on HTTP Transport
+public struct THTTPTransportError: TError {
+  public enum ErrorCode: TErrorCode {
+    case invalidResponse
+    case invalidStatus(statusCode: Int)
+    case authentication
+    
+    public var description: String {
+      switch self {
+      case .invalidResponse:                return "Invalid HTTP Response"
+      case .invalidStatus(let statusCode):  return "Invalid HTTP Status Code (\(statusCode))"
+      case .authentication:                 return "Authentication Error"
+      }
+    }
+    public var thriftErrorCode: Int { return 0 }
+  }
+  public var error: ErrorCode = .invalidResponse
+  public var message: String? = nil
+  public static var defaultCase: ErrorCode { return .invalidResponse }
+  
+  public init() { }
+}
+
diff --git a/lib/swift/Sources/TWrappedProtocol.swift b/lib/swift/Sources/TWrappedProtocol.swift
new file mode 100644
index 0000000..8e8577b
--- /dev/null
+++ b/lib/swift/Sources/TWrappedProtocol.swift
@@ -0,0 +1,208 @@
+/*
+* 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 // For (NS)Data
+
+
+/// Generic protocol, implementes TProtocol and wraps a concrete protocol.
+/// Useful for generically subclassing protocols to override specific methods 
+/// (i.e. TMultiplexedProtocol)
+open class TWrappedProtocol<Protocol: TProtocol> : TProtocol {
+  var concreteProtocol: Protocol
+  
+  public var transport: TTransport {
+    get {
+      return concreteProtocol.transport
+    }
+    set {
+      concreteProtocol.transport = newValue
+    }
+  }
+
+  public required init(on transport: TTransport) {
+    self.concreteProtocol = Protocol(on: transport)
+  }
+  
+  // Read methods
+  
+  public func readMessageBegin() throws -> (String, TMessageType, Int32) {
+    return try concreteProtocol.readMessageBegin()
+  }
+  
+  public func readMessageEnd() throws {
+    try concreteProtocol.readMessageEnd()
+  }
+  
+  public func readStructBegin() throws -> String {
+    return try concreteProtocol.readStructBegin()
+  }
+  
+  public func readStructEnd() throws {
+    try concreteProtocol.readStructEnd()
+  }
+  
+  public func readFieldBegin() throws -> (String, TType, Int32) {
+    return try concreteProtocol.readFieldBegin()
+  }
+  
+  public func readFieldEnd() throws {
+    try concreteProtocol.readFieldEnd()
+  }
+  
+  public func readMapBegin() throws -> (TType, TType, Int32) {
+    return try concreteProtocol.readMapBegin()
+  }
+  
+  public func readMapEnd() throws {
+    try concreteProtocol.readMapEnd()
+  }
+  
+  public func readSetBegin() throws -> (TType, Int32) {
+    return try concreteProtocol.readSetBegin()
+  }
+  
+  public func readSetEnd() throws {
+    try concreteProtocol.readSetEnd()
+  }
+  
+  public func readListBegin() throws -> (TType, Int32) {
+    return try concreteProtocol.readListBegin()
+  }
+  
+  public func readListEnd() throws {
+    try concreteProtocol.readListEnd()
+  }
+  
+  public func read() throws -> String {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> Bool {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> UInt8 {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> Int16 {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> Int32 {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> Int64 {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> Double {
+    return try concreteProtocol.read()
+  }
+  
+  public func read() throws -> Data {
+    return try concreteProtocol.read()
+  }
+  
+  // Write methods
+  
+  public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws {
+    return try concreteProtocol.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID)
+  }
+  
+  public func writeMessageEnd() throws {
+    try concreteProtocol.writeMessageEnd()
+  }
+  
+  public func writeStructBegin(name: String) throws {
+    try concreteProtocol.writeStructBegin(name: name)
+  }
+  
+  public func writeStructEnd() throws {
+    try concreteProtocol.writeStructEnd()
+  }
+  
+  public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws {
+    try concreteProtocol.writeFieldBegin(name: name, type: fieldType, fieldID: fieldID)
+  }
+  
+  public func writeFieldStop() throws {
+    try concreteProtocol.writeFieldStop()
+  }
+  
+  public func writeFieldEnd() throws {
+    try concreteProtocol.writeFieldEnd()
+  }
+  
+  public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws {
+    try concreteProtocol.writeMapBegin(keyType: keyType, valueType: valueType, size: size)
+  }
+  
+  public func writeMapEnd() throws {
+    try concreteProtocol.writeMapEnd()
+  }
+  
+  public func writeSetBegin(elementType: TType, size: Int32) throws {
+    try concreteProtocol.writeSetBegin(elementType: elementType, size: size)
+  }
+  
+  public func writeSetEnd() throws {
+    try concreteProtocol.writeSetEnd()
+  }
+  
+  public func writeListBegin(elementType: TType, size: Int32) throws {
+    try concreteProtocol.writeListBegin(elementType: elementType, size: size)
+  }
+  
+  public func writeListEnd() throws {
+    try concreteProtocol.writeListEnd()
+  }
+  public func write(_ value: String) throws {
+    try concreteProtocol.write(value)
+  }
+  
+  public func write(_ value: Bool) throws {
+    try concreteProtocol.write(value)
+  }
+  
+  public func write(_ value: UInt8) throws {
+    try concreteProtocol.write(value)
+  }
+
+  public func write(_ value: Int16) throws {
+    try concreteProtocol.write(value)
+  }
+  
+  public func write(_ value: Int32) throws {
+    try concreteProtocol.write(value)
+  }
+  
+  public func write(_ value: Int64) throws {
+    try concreteProtocol.write(value)
+  }
+  
+  public func write(_ value: Double) throws {
+    try concreteProtocol.write(value)
+  }
+
+  public func write(_ data: Data) throws {
+    try concreteProtocol.write(data)
+  }
+}
diff --git a/lib/swift/Sources/Thrift.swift b/lib/swift/Sources/Thrift.swift
new file mode 100644
index 0000000..afa3096
--- /dev/null
+++ b/lib/swift/Sources/Thrift.swift
@@ -0,0 +1,3 @@
+class Thrift {
+	let version = "0.0.1"
+}