Duckjd
Duckjd

Reputation: 87

NSMutableData to CConstPointer conversion in Swift needed

The following Swift code (writing bytes to a stream) is rewritten from Objective-C:

var outputStream : NSOutputStream = NSOutputStream()
var pData : NSMutableData = NSMutableData()
var pType : Int = 1
let pMessage : String = "Device_Description\0\0\x01" // 16BitChar with escapeSequence
var pLength : Int = 8+pMessage.lengthOfBytesUsingEncoding(NSUTF16LittleEndianStringEncoding)

pData.appendBytes(&pLength, length: 4)
pData.appendBytes(&pType, length: 4)
pData.appendData((pMessage as NSString).dataUsingEncoding(NSUTF16LittleEndianStringEncoding))

outputStream.write(pData.bytes, maxLength: pData.length)

pData.bytes is of type COpaquePointer, but CConstPointer<Uint8>is needed by the write operation. Any hints for the correct conversion? Thanks in advance.

Upvotes: 1

Views: 298

Answers (3)

Scott D
Scott D

Reputation: 1424

As Jack wu has outlined, but somewhat incompletely, the following code works just the same as using the UnsafePointer option:

var byteData = [UInt8]()
pData.getBytes(&byteData)
self.outputStream!.write(byteData, maxLength: pData.length)

Upvotes: 2

Jack
Jack

Reputation: 16865

From the Swift & Objc interop book section here : https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/buildingcocoaapps/InteractingWithCAPIs.html

C Constant Pointers

When a function is declared as taking a CConstPointer argument, it can accept any of the following:

  • nil, which is passed as a null pointer
  • A CMutablePointer, CMutableVoidPointer, CConstPointer, CConstVoidPointer, or AutoreleasingUnsafePointer value, which
    is converted to CConstPointer if necessary
  • An in-out expression whose operand is an lvalue of type Type, which is passed as the address of the lvalue
  • A Type[] value, which is passed as a pointer to the start of the array, and lifetime-extended for the duration of the call

I believe then it can work like this:

var p: [Uint8] = []
pData.getBytes(&p)
outputStream.write(p, maxLength: pData.length)

Upvotes: 1

Duckjd
Duckjd

Reputation: 87

I found a simple solution right now, by use of UnsafePointer<T>():

var outputStream : NSOutputStream = NSOutputStream()
var pData : NSMutableData = NSMutableData()
var pType : Int = 1
let pMessage : String = "Device_Description\0\0\x01" // 16BitChar with escapeSequence
var pLength : Int = 8+pMessage.lengthOfBytesUsingEncoding(NSUTF16LittleEndianStringEncoding)

pData.appendBytes(&pLength, length: 4)
pData.appendBytes(&pType, length: 4)
pData.appendData(ptpMessage.dataUsingEncoding(NSUTF16LittleEndianStringEncoding))

outputStream.write(UnsafePointer<UInt8>(pData.bytes), maxLength: pData.length)

@holex: Thanks for your input. I know this solution is not quite Swifty, but it´s working for now.

Upvotes: 0

Related Questions