简体   繁体   English

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

[英]Swift NSData String Conversion Based on Subset of NSData

Situation 情况

I'm working with binary data which has a string encoded in the middle. 我正在使用二进制数据,该数据的中间编码有一个字符串。 What I'm trying to do is extract this string so that I can both "set" and "get" it. 我想做的是提取此字符串,以便可以“设置”和“获取”它。 I've come up with a methodology which seems a little funky (actually 3 options). 我想出了一种看起来有点时髦的方法(实际上是3种选择)。 I've included a playground code which you can look at. 我提供了一个游乐场代码,您可以查看。

I'm wondering if there is a "better" way to work with this data than what I've come up. 我想知道是否有比我提出的更好的方法来处理这些数据。 Better means more efficient or clearer code-wise. 更好意味着更高效或更清晰的代码方式。

To read the data I do the following - 要读取数据,请执行以下操作-

  1. make var rawData by converting the NSMutableData to UnsafeMutablePoitner<UInt8> 通过将NSMutableData转换为UnsafeMutablePoitner<UInt8>来制作var rawData
  2. Create var ptr : UnsafeMutablePointer<UInt8> from rawData.mutableBytes rawData.mutableBytes创建var ptr : UnsafeMutablePointer<UInt8>
  3. Create an array bytes of type UnsafeMutableBufferPointer<UInt8> from a combo of the 1st two variables 从第一个两个变量的组合创建类型为UnsafeMutableBufferPointer<UInt8>的数组bytes
  4. Create a new array consisting of just the bytes containing the string bytes[19] - bytes[26] 创建一个仅由包含字符串bytes[19] bytes[26]的字节组成的新数组
  5. Extract this array into a string 将此数组提取为字符串

Then to set the variable I have 3 methods but the one I think I would use is 1. Make a new string of 8 string 2. Create [UInt8] array of the characters of the string 3. Loop through each byte in the new array and set the value of the byte in the bytes array to the value in question 然后设置变量,我有3种方法,但我认为我会使用的一种方法:1.制作一个8字符串的新字符串2.创建字符串的字符的[UInt8]数组3.遍历新数组中的每个字节并将bytes数组中byte的值设置为有问题的值

I'm assuming there is some way where I can be working directly with the "parent" byte array as opposed to making a sub-array to work with. 我假设有某种方法可以直接使用“父”字节数组,而不是使用子数组。 Playground code is below. 游乐场代码如下。 I'm looking for a cleaner way to do this and perhaps there is not one. 我正在寻找一种更清洁的方式来执行此操作,也许没有。

Thanks 谢谢

Playground Code 游乐场代码

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 has methods to extract and replace sub-ranges: 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)

You can also operate on the [UInt8] array directly: 您也可以直接在[UInt8]数组上进行操作:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM