Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with NSData in swift

So I've figured out how to extract NSData in swift but i'm getting confused with regards to setting it:

var testBytes : [Byte] = [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]

var msgData = NSData(bytes: testBytes, length: testBytes.count)

println("\(msgData)")


var length : Int = testBytes.count

var out: NSInteger = 0

let ptr = UnsafePointer<UInt8>(msgData.bytes)
var bytes = UnsafeBufferPointer<UInt8>(start: ptr, count: 28)

So if i want to access a specific byte I can get it with something like:

let targetAddress = UInt32(bytes[2]) << 16 |
    UInt32(bytes[3]) << 8 |
    UInt32(bytes[4]) << 0

Now say I wanted to set a value with something like:

bytes[11] = UInt8(UInt32(bytes[11]) | 0x0FF)

I get an error of Cannot assign the result of this expression). I tried also using &bytes[11] which doesn't seem to fly either.

I'm assuming this is because the array uses an unsafe buffer pointer. Is there an easy call that I've some how glossed over to make the assignment work correctly?

like image 976
Jeef Avatar asked Jan 30 '15 11:01

Jeef


People also ask

What is NSData in Swift?

NSData is toll-free bridged with its Core Foundation counterpart, CFData . See Toll-Free Bridging for more information on toll-free bridging. Important. The Swift overlay to the Foundation framework provides the Data structure, which bridges to the NSData class and its mutable subclass NSMutableData .

What is Nsurl?

An NSURL object is composed of two parts—a potentially nil base URL and a string that is resolved relative to the base URL. An NSURL object is considered absolute if its string part is fully resolved without a base; all other URLs are considered relative.

What is CFData?

CFData and its derived mutable type, CFMutableData, provide support for data objects, object-oriented wrappers for byte buffers. Data objects let simple allocated buffers (that is, data with no embedded pointers) take on the behavior of Core Foundation objects.

What is Nsstring?

A static, plain-text Unicode string object which you use when you need reference semantics or other Foundation-specific behavior.


1 Answers

If you want to modify the bytes retrieved from the NSData object, then you should copy the bytes into a separate array

var bytes = [UInt8](count: msgData.length, repeatedValue: 0)
msgData.getBytes(&bytes, length: bytes.count)

bytes[11] = UInt8(UInt32(bytes[11]) | 0x0FF)

NSData is an immutable object, and

let ptr = UnsafePointer<UInt8>(msgData.bytes)

is a constant pointer, so you must not modify the pointed-to data.

Alternatively, use a mutable data object from the beginning:

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

let ptr = UnsafeMutablePointer<UInt8>(msgData.mutableBytes)
var bytes = UnsafeMutableBufferPointer<UInt8>(start: ptr, count: msgData.length)

bytes[11] = UInt8(UInt32(bytes[11]) | 0x0FF)

Note the usage of msgData.mutableBytes instead of msgData.bytes. This will modify the data in msgData directly.

like image 50
Martin R Avatar answered Oct 09 '22 09:10

Martin R