Converting an UnsafePointer with length to a Swift Array type
You can simply initialize a Swift Array
from an UnsafeBufferPointer
:
func convert(length: Int, data: UnsafePointer<Int8>) -> [Int8] { let buffer = UnsafeBufferPointer(start: data, count: length); return Array(buffer)}
This creates an array of the needed size and copies the data.
Or as a generic function:
func convert<T>(count: Int, data: UnsafePointer<T>) -> [T] { let buffer = UnsafeBufferPointer(start: data, count: count); return Array(buffer) }
where length
is the number of items that the pointer points to.
If you have a UInt8
pointer but want to create an [T]
array from the pointed-to data, then this is a possible solution:
// Swift 2:func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] { let buffer = UnsafeBufferPointer<T>(start: UnsafePointer(data), count: length/strideof(T)); return Array(buffer) }// Swift 3:func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] { let numItems = length/MemoryLayout<T>.stride let buffer = data.withMemoryRebound(to: T.self, capacity: numItems) { UnsafeBufferPointer(start: $0, count: numItems) } return Array(buffer) }
where length
now is the number of bytes. Example:
let arr = convert(12, data: ptr, Float.self)
would create an array of 3 Float
s from the 12 bytes pointed to by ptr
.
extension NSData { public func convertToBytes() -> [UInt8] { let count = self.length / sizeof(UInt8) var bytesArray = [UInt8](count: count, repeatedValue: 0) self.getBytes(&bytesArray, length:count * sizeof(UInt8)) return bytesArray }}
You can convert row data to byts (Uint8)
Copy Extension and use it..
You can also use the Array init function:
init(unsafeUninitializedCapacity: Int, initializingWith initializer: (inout UnsafeMutableBufferPointer<Element>, inout Int) throws -> Void) rethrows
First convert the unsafeRawPointer to unsafePointer if neededThen convert the pointer to a buffer pointer, and finally the buffer pointer to an array.
Example, assuming you have an unsafeRawPointer (dataPtr
) and its size (dataSize
)
let numberOfItems = dataSize / MemoryLayout<MyClass>.stridelet myArray = dataPtr.withMemoryRebound(to: MyClass.self, capacity: numberOfItems) { typedPtr in // Convert pointer to buffer pointer to access buffer via indices let bufferPointer = UnsafeBufferPointer(start: typedPtr, count: numberOfItems) // Construct array return [MyClass](unsafeUninitializedCapacity: numberOfItems) { arrayBuffer, count in count = numberOfItems for i in 0..<count { arrayBuffer[i] = bufferPointer[i] } }}