/* * 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 { 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() } func validateValue(_ value: Any?, named name: String) throws { if value == nil { throw TProtocolError(error: .unknown, message: "Missing required value for field: \(name)") } } func readResultMessageBegin() throws { let (_, type, _) = try readMessageBegin(); if type == .exception { let x = try readException() throw x } return } func readException() throws -> TApplicationError { return try TApplicationError.read(from: self) } 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() } 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..