]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / lib / swift / Sources / TBinaryProtocol.swift
diff --git a/ceph/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift b/ceph/src/jaegertracing/thrift/lib/swift/Sources/TBinaryProtocol.swift
new file mode 100644 (file)
index 0000000..85acce0
--- /dev/null
@@ -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)
+    }
+  }
+}