blob: a4e4a20fa9192585f48180d101ad87a52527d7f4 [file] [log] [blame]
/*
* 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
}
}
}