Swift 4中等效的Java ByteBuffer



我正在尝试将底层Java(Android(代码转换为Swift。我被字节缓冲区的部分卡住了。

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

您可以将其用于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())

您可以使用Data类作为缓冲

var frame = Data(capacity: bufferSize)

但是您实际上不需要指定容量,您可以等待frame的初始化,直到您真正有任何数据来初始化它——根据mUserToken的类型,您可以使用适当的Data初始化程序

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

最新更新