diff options
Diffstat (limited to 'src/jaegertracing/thrift/lib/swift/Sources/TFramedTransport.swift')
-rw-r--r-- | src/jaegertracing/thrift/lib/swift/Sources/TFramedTransport.swift | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/lib/swift/Sources/TFramedTransport.swift b/src/jaegertracing/thrift/lib/swift/Sources/TFramedTransport.swift new file mode 100644 index 000000000..59855eb9c --- /dev/null +++ b/src/jaegertracing/thrift/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([UInt8(0xff & (size >> 24))])) + data.append(Data([UInt8(0xff & (size >> 16))])) + data.append(Data([UInt8(0xff & (size >> 8))])) + data.append(Data([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() + } +} |