summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift384
1 files changed, 384 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift b/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift
new file mode 100644
index 000000000..85acce045
--- /dev/null
+++ b/src/jaegertracing/thrift/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 Double(bitPattern: UInt64(bitPattern: val))
+ }
+
+ 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([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([UInt8(0xff & (value >> 8))]))
+ buff.append(Data([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([UInt8(0xff & (value >> 24))]))
+ buff.append(Data([UInt8(0xff & (value >> 16))]))
+ buff.append(Data([UInt8(0xff & (value >> 8))]))
+ buff.append(Data([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([UInt8(0xff & (value >> 56))]))
+ buff.append(Data([UInt8(0xff & (value >> 48))]))
+ buff.append(Data([UInt8(0xff & (value >> 40))]))
+ buff.append(Data([UInt8(0xff & (value >> 32))]))
+ buff.append(Data([UInt8(0xff & (value >> 24))]))
+ buff.append(Data([UInt8(0xff & (value >> 16))]))
+ buff.append(Data([UInt8(0xff & (value >> 8))]))
+ buff.append(Data([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(Int64(bitPattern: value.bitPattern))
+ }
+
+ 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)
+ }
+ }
+}