Mike S Mike S - 1 year ago 95
Swift Question

copy NSData to UnsafeMutablePointer<Void>

Hi there stackoverflowers. I'm implementing a wrapper for Secure Transport and I'm stuck on some of the C -> Swift syntax.

func sslReadCallback(connection: SSLConnectionRef,
data: UnsafeMutablePointer<Void>,
var dataLength: UnsafeMutablePointer<Int>) -> OSStatus
//let bytesRequested = dataLength.memory
let transportWrapper:SecureTransportWrapper = UnsafePointer(connection).memory
let bytesRead:NSData = transportWrapper.readFromConnectionFunc(transportWrapper.connection)

dataLength = UnsafeMutablePointer<Int>.alloc(1)

if (bytesRead.length == 0)
return OSStatus(errSSLClosedGraceful)
data.alloc(sizeof(bytesRead.length)) //<----compile error here
return noErr

I've marked the location of the compile error. I don't blame it for erring, I was kind of guessing here :P. I'm trying to copy the the NSData to the data:UnsafeMutablePointer. How do I do that?

Compile error:

/Users/*/SecureTransportWrapper.swift:108:9: Static member 'alloc' cannot be used on instance of type 'UnsafeMutablePointer' (aka 'UnsafeMutablePointer<()>')

Thanks a ton!


Update: here is the api doc for what the sslReadCallback is supposed to do:

connection: A connection reference.

data: On return, your callback should overwrite the memory at this location with the data read from the connection.

dataLength: On input, a pointer to an integer
representing the length of the data in bytes. On return, your callback
should overwrite that integer with the number of bytes actually

Excerpt from here

hnh hnh
Answer Source

OK, lets go through your code:

dataLength = UnsafeMutablePointer<Int>.alloc(1)

dataLength is a pointer you get passed in, it is where the caller of the function both gives you the size of the buffer and wants you to put the number of bytes you read. You don't need to alloc this, it is already allocated.

(Irrelevant for this example but: Also in alloc(N) and initialize(N) the N should be the same (it is the amount of memory being allocated, and then initialized))

I think what you want (Swift 3 uses pointee instead of memory) is this:

dataLength.memory = bytesRead.length

The C API says that you also get the size of the data buffer from this variable. data will be pre-allocated for this size.

Make sure the data you read fits (bytesRead.length <= dataLength.memory), then just do a

memcpy(data, bytesRead.bytes, bytesRead.length)

That's all.