Swift 基于NSData子集的NSData字符串转换

Swift NSData String Conversion Based on Subset of NSData

情况

我正在处理中间有一个字符串编码的二进制数据。我想做的是提取这个字符串,这样我就可以 "set" 和 "get" 它了。我提出了一种看起来有点古怪的方法(实际上有 3 个选项)。我已经包含了一个游乐场代码,您可以查看。

我想知道是否有 "better" 方法来处理这些数据而不是我想出的方法。更好意味着代码更高效或更清晰。

要读取数据,我执行以下操作 -

  1. 通过将 NSMutableData 转换为 UnsafeMutablePoitner<UInt8>
  2. 来制作 var rawData
  3. rawData.mutableBytes
  4. 创建 var ptr : UnsafeMutablePointer<UInt8>
  5. 从第一个两个变量的组合
  6. 创建类型UnsafeMutableBufferPointer<UInt8>的数组bytes
  7. 创建一个仅由包含字符串 bytes[19] - bytes[26]
  8. 的字节组成的新数组
  9. 将这个数组提取成一个字符串

然后设置变量我有3种方法,但我想我会使用的是 1.制作一串新的8串 2.创建[UInt8]字符串的字符数组 3.循环遍历新数组中的每个字节并将bytes数组中字节的值设置为问题中的值

我假设有一些方法可以让我直接使用 "parent" 字节数组,而不是制作一个子数组来使用。游乐场代码如下。我正在寻找一种更简洁的方法来执行此操作,但也许没有。

谢谢

游乐场代码

import Cocoa
//import AppKit



///This is the raw data
var testBytes : [UInt8] = [0x14, 0x00, 0xAB, 0x45, 0x49, 0x1F, 0xEF, 0x15, 0xA8, 0x89, 0x78, 0x0F, 0x09, 0xA9, 0x07, 0xB0, 0x01, 0x20, 0x01, 0x4E, 0x38, 0x32, 0x35, 0x56, 0x20, 0x20, 0x20, 0x00]

///Convert into msgData
var msgData = NSMutableData(bytes: testBytes, length: testBytes.count)


// Store raw data into a byte array for messing with
var rawData: NSMutableData = NSMutableData(data: msgData)
var ptr: UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(rawData.mutableBytes)
var bytes : UnsafeMutableBufferPointer<UInt8> = UnsafeMutableBufferPointer<UInt8>(start: ptr, count: rawData.length)


// Extract Callsign from the data stream
var callsignArray : [UInt8] = [bytes[19], bytes[20], bytes[21], bytes[22], bytes[23], bytes[24], bytes[25], bytes[26]]
var callsignString = NSString(bytes: callsignArray, length: callsignArray.count, encoding: NSUTF8StringEncoding)
let callsignString0 = callsignString!
println(callsignArray)
println("1. -- Initial Callsign [\(callsignString0)]")


//OPTION #1
// Edit Callsgin Array Directly (sketchy)
// And manually copy the bytes back into the base array
callsignArray[0] = 97
callsignArray[1] = 98
callsignArray[2] = 99
callsignArray[3] = 100

println(callsignArray)

// Write the new "bytes" back into the main array - there must be a better way
for (var i = 0; i <= 7; i++) {
    bytes[19+i] = callsignArray[i]
}

let callsign1 = NSString(bytes: callsignArray, length: callsignArray.count, encoding: NSUTF8StringEncoding)!

println("2. -- Modification of Bytes [\(callsign1)]")

//Option 3 - Go from String to Bytes

let callsign3 = "AABCDEF "
var buf = [UInt8](callsign3.utf8)

for (var i = 0; i <= 7; i++) {
    bytes[19+i] = buf[i]
}
println(rawData)

callsignArray = [bytes[19], bytes[20], bytes[21], bytes[22], bytes[23], bytes[24], bytes[25], bytes[26]]
callsignString = NSString(bytes: callsignArray, length: callsignArray.count, encoding: NSUTF8StringEncoding)

NSMutableData 有提取和替换子范围的方法:

// Get: 
let subData = msgData.subdataWithRange(NSMakeRange(19, 8))
let string = NSString(data: subData, encoding: NSUTF8StringEncoding)

// Set:
let newString = "AABCDEF "
let newData = newString.dataUsingEncoding(NSUTF8StringEncoding)!
msgData.replaceBytesInRange(NSMakeRange(19, 8), withBytes: newData.bytes, length: newData.length)

也可以直接对[UInt8]数组进行操作:

// Get:
let string = testBytes.withUnsafeBufferPointer {
    NSString(bytes: UnsafePointer([=11=].baseAddress + 19), length: 8, encoding: NSUTF8StringEncoding)
}

// Set:
testBytes.replaceRange(19 ... 26, with: Array(newString.utf8))