【问题标题】:Java ByteBuffer equivalent in Swift 4Swift 4 中的 Java ByteBuffer 等价物
【发布时间】:2019-04-10 22:11:45
【问题描述】:

我正在尝试将我的底层 Java (Android) 代码转换为 Swift。 我被困在 ByteBuffer 的一部分。

private MqttMessage createMqttMessage(boolean encrypted, byte[] message) {
    /* add a zero-byte at the end just to be sure it's terminated although the payload is zero-padded */
    int padding = 16 - ((message.length) % 16);

    /* a zero-byte at the end of the JSON is required for determining the string's end */
    padding = padding == 0 ? 16 : padding;

    byte[] payload = new byte[message.length+padding];

    System.arraycopy(message, 0, payload, 0, message.length);

    /* FRAME_HEADER + JSON-payload + zero-byte + FRAME_TAIL_SIZE */
    int bufferSize = Constants.FRAME_HEADER_SIZE + payload.length + 1 + Constants.FRAME_TAIL_SIZE;

    ByteBuffer frame = ByteBuffer.allocate(bufferSize);

    /* The CC3220 is an ARM device, thus little-endian */
    frame.order(ByteOrder.LITTLE_ENDIAN);

    // message flags (uint8_t)
    byte flags = (byte) (encrypted ? Constants.FRAME_FLAG_ENCRYPTED : 0x0);
    // always use authentication
    flags |= Constants.FRAME_FLAG_AUTHENTICATED;

    frame.put(flags);

    // User token   (uint32_t)
    frame.putInt((int)this.mUserToken);

Swift 中的 ByteBuffer 等价物是什么?

这是我目前所拥有的:

private func createMqttMessage(encrypted: Bool, message: [Int8]) {

    var padding:Int = 16 - ((message.count) % 16)

    padding = padding == 0 ? 16 : padding

    var payload:[Int8]

    payload = Array(message[0..<0+message.count])

    let bufferSize = Constants.FRAME_HEADER_SIZE + payload.count + 1 + Constants.FRAME_TAIL_SIZE

【问题讨论】:

    标签: ios swift bytebuffer


    【解决方案1】:

    您可以将其用于ByteBuffer.. 它的行为与 Java 类似.. 可能缺少某些功能,但应该很容易添加它们。

    import Foundation
    
    public class ByteBuffer {
    
        public init(size: Int) {
            array.reserveCapacity(size)
        }
    
        public func allocate(_ size: Int) {
            array = [UInt8]()
            array.reserveCapacity(size)
            currentIndex = 0
        }
    
        public func nativeByteOrder() -> Endianness {
            return hostEndianness
        }
    
        public func currentByteOrder() -> Endianness {
            return currentEndianness
        }
    
        public func order(_ endianness: Endianness) -> ByteBuffer {
            currentEndianness = endianness
            return self
        }
    
        public func put(_ value: UInt8) -> ByteBuffer {
            array.append(value)
            return self
        }
    
        public func put(_ value: Int32) -> ByteBuffer {
            if currentEndianness == .little {
                array.append(contentsOf: to(value.littleEndian))
                return self
            }
    
            array.append(contentsOf: to(value.bigEndian))
            return self
        }
    
        public func put(_ value: Int64) -> ByteBuffer {
            if currentEndianness == .little {
                array.append(contentsOf: to(value.littleEndian))
                return self
            }
    
            array.append(contentsOf: to(value.bigEndian))
            return self
        }
    
        public func put(_ value: Int) -> ByteBuffer {
            if currentEndianness == .little {
                array.append(contentsOf: to(value.littleEndian))
                return self
            }
    
            array.append(contentsOf: to(value.bigEndian))
            return self
        }
    
        public func put(_ value: Float) -> ByteBuffer {
            if currentEndianness == .little {
                array.append(contentsOf: to(value.bitPattern.littleEndian))
                return self
            }
    
            array.append(contentsOf: to(value.bitPattern.bigEndian))
            return self
        }
    
        public func put(_ value: Double) -> ByteBuffer {
            if currentEndianness == .little {
                array.append(contentsOf: to(value.bitPattern.littleEndian))
                return self
            }
    
            array.append(contentsOf: to(value.bitPattern.bigEndian))
            return self
        }
    
        public func get() -> UInt8 {
            let result = array[currentIndex]
            currentIndex += 1
            return result
        }
    
        public func get(_ index: Int) -> UInt8 {
            return array[index]
        }
    
        public func getInt32() -> Int32 {
            let result = from(Array(array[currentIndex..<currentIndex + MemoryLayout<Int32>.size]), Int32.self)
            currentIndex += MemoryLayout<Int32>.size
            return currentEndianness == .little ? result.littleEndian : result.bigEndian
        }
    
        public func getInt32(_ index: Int) -> Int32 {
            let result = from(Array(array[index..<index + MemoryLayout<Int32>.size]), Int32.self)
            return currentEndianness == .little ? result.littleEndian : result.bigEndian
        }
    
        public func getInt64() -> Int64 {
            let result = from(Array(array[currentIndex..<currentIndex + MemoryLayout<Int64>.size]), Int64.self)
            currentIndex += MemoryLayout<Int64>.size
            return currentEndianness == .little ? result.littleEndian : result.bigEndian
        }
    
        public func getInt64(_ index: Int) -> Int64 {
            let result = from(Array(array[index..<index + MemoryLayout<Int64>.size]), Int64.self)
            return currentEndianness == .little ? result.littleEndian : result.bigEndian
        }
    
        public func getInt() -> Int {
            let result = from(Array(array[currentIndex..<currentIndex + MemoryLayout<Int>.size]), Int.self)
            currentIndex += MemoryLayout<Int>.size
            return currentEndianness == .little ? result.littleEndian : result.bigEndian
        }
    
        public func getInt(_ index: Int) -> Int {
            let result = from(Array(array[index..<index + MemoryLayout<Int>.size]), Int.self)
            return currentEndianness == .little ? result.littleEndian : result.bigEndian
        }
    
        public func getFloat() -> Float {
            let result = from(Array(array[currentIndex..<currentIndex + MemoryLayout<UInt32>.size]), UInt32.self)
            currentIndex += MemoryLayout<UInt32>.size
            return currentEndianness == .little ? Float(bitPattern: result.littleEndian) : Float(bitPattern: result.bigEndian)
        }
    
        public func getFloat(_ index: Int) -> Float {
            let result = from(Array(array[index..<index + MemoryLayout<UInt32>.size]), UInt32.self)
            return currentEndianness == .little ? Float(bitPattern: result.littleEndian) : Float(bitPattern: result.bigEndian)
        }
    
        public func getDouble() -> Double {
            let result = from(Array(array[currentIndex..<currentIndex + MemoryLayout<UInt64>.size]), UInt64.self)
            currentIndex += MemoryLayout<UInt64>.size
            return currentEndianness == .little ? Double(bitPattern: result.littleEndian) : Double(bitPattern: result.bigEndian)
        }
    
        public func getDouble(_ index: Int) -> Double {
            let result = from(Array(array[index..<index + MemoryLayout<UInt64>.size]), UInt64.self)
            return currentEndianness == .little ? Double(bitPattern: result.littleEndian) : Double(bitPattern: result.bigEndian)
        }
    
    
        public enum Endianness {
            case little
            case big
        }
    
        private func to<T>(_ value: T) -> [UInt8] {
            var value = value
            return withUnsafeBytes(of: &value, Array.init)
        }
    
        private func from<T>(_ value: [UInt8], _: T.Type) -> T {
            return value.withUnsafeBytes {
                $0.load(fromByteOffset: 0, as: T.self)
            }
        }
    
        private var array = [UInt8]()
        private var currentIndex: Int = 0
    
        private var currentEndianness: Endianness = .big
        private let hostEndianness: Endianness = OSHostByteOrder() == OSLittleEndian ? .little : .big
    }
    
    let buffer = ByteBuffer(size: 100)
    buffer.order(.big)
    buffer.put(1.019001)
    buffer.order(.little)
    buffer.put(1005)
    buffer.order(.big)
    buffer.put(1005)
    
    buffer.order(.big)
    print(buffer.getDouble())
    buffer.order(.little)
    print(buffer.getInt())
    buffer.order(.big)
    print(buffer.getInt())
    

    【讨论】:

      【解决方案2】:

      您可以使用Data 类作为缓冲区

      var frame = Data(capacity: bufferSize)
      

      但您实际上不需要指定容量,您可以等待 frame 的初始化,直到您实际上有任何数据来初始化它 - 取决于 mUserToken 的类型,您可以使用适当的Data 初始化器

      init(bytes: UnsafeRawPointer, count: Int)
      init(bytes: <Array<UInt8>>)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-03
        • 2014-07-23
        • 2014-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多