Java ByteBuffer 相当于 Swift 4
Java ByteBuffer equivalent in Swift 4
我正在尝试将下面的 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
你可以使用Data
class作为缓冲
var frame = Data(capacity: bufferSize)
但您实际上不需要指定容量,您可以等待 frame
的初始化,直到您真正有任何数据来初始化它 - 取决于 mUserToken
将要使用的类型是的,你可以使用适当的 Data
初始值设定项
init(bytes: UnsafeRawPointer, count: Int)
init(bytes: <Array<UInt8>>)
您可以将其用于 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 {
[=10=].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())
我正在尝试将下面的 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
你可以使用Data
class作为缓冲
var frame = Data(capacity: bufferSize)
但您实际上不需要指定容量,您可以等待 frame
的初始化,直到您真正有任何数据来初始化它 - 取决于 mUserToken
将要使用的类型是的,你可以使用适当的 Data
初始值设定项
init(bytes: UnsafeRawPointer, count: Int)
init(bytes: <Array<UInt8>>)
您可以将其用于 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 {
[=10=].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())