Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Swift 3, how do I get UnsafeRawPointer from Data?

Tags:

According to the documentation of Data in Swift 3, there is an initializer that I can use to create a Data from UnsafeRawPointer. What I need actually is the opposite. I have a Data, and I want to create a UnsafeRawPointer that points to the bytes of the Data. Here's what I'm doing right now:

1. let data = <from some where> 2. let unsafePointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count) 3. unsafePointer.initialize(to: 0, count: data.count) // is this necessary? 4. data.copyBytes(to: unsafePointer, count: data.count) 5. let unsafeRawPointer = unsafePointer.deinitialize() // this is of the type UnsafeMutalbleRawPointer, and I can use it where UnsafeRawPointer is needed. 

I verified that this code works in Xcode Playground. The code even works without the line number 3. I'm not sure what is the difference with or without the line. Anyway, my question is, am I doing right for what I want? Is there a simpler way to do it?

like image 974
Jake Avatar asked Sep 24 '16 02:09

Jake


People also ask

What is UnsafePointer?

UnsafePointer provides no automated memory management or alignment guarantees. You are responsible for handling the life cycle of any memory you work with through unsafe pointers to avoid leaks or undefined behavior. Memory that you manually manage can be either untyped or bound to a specific type.

What is a pointer in Swift?

A pointer is an object that stores a memory address. In Swift, there are 8 types of pointers. In Swift, pointers are known as UnsafePointer because they support direct operations on memory and these operations are unsafe in nature that's why a Unsafe prefix is used with Pointers in swift.

What is data in Swift?

It is a collection of bytes ( [UInt8] array of unsigned integer 8 bits 0-255).


1 Answers

withUnsafeBytes() gives you a (typed) pointer to the bytes, this can be converted to a raw pointer:

let data = <Data from somewhere> data.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in     let rawPtr = UnsafeRawPointer(u8Ptr)     // ... use `rawPtr` ... } 

The pointer is only valid during the lifetime of the call to the closure.

Alternatively, you can bridge to NSData and access the raw bytes:

let nsData = data as NSData let rawPtr = nsData.bytes 

Now the pointer is valid in the same scope where nsData is valid.

As of Swift 5 it is

let data = <Data from somewhere> data.withUnsafeBytes { rawBufferPointer in     let rawPtr = rawBufferPointer.baseAddress!     // ... use `rawPtr` ... } 

because the closure argument is now a UnsafeRawBufferPointer.

like image 58
Martin R Avatar answered Sep 27 '22 00:09

Martin R