I'm working on a Swift 3 wrapper for the libxml2 C-library.
There are two convenience methods to convert String to UnsafePointer<xmlChar> and vice versa. In libxml2 xmlChar is declared as unsigned char.
UnsafePointer<xmlChar>toStringis uncomplicatedfunc stringFrom(xmlchar: UnsafePointer<xmlChar>) -> String { let string = xmlchar.withMemoryRebound(to: CChar.self, capacity: 1) { return String(validatingUTF8: $0) } return string ?? "" }For
StringtoUnsafePointer<xmlChar>I tried many things for examplelet bytes = string.utf8CString.map{ xmlChar($0) } return UnsafePointer<xmlChar>(bytes)but this doesn't work, the only working solution I figured out is
func xmlCharFrom(string: String) -> UnsafePointer<xmlChar> { let pointer = (string as NSString).utf8String return unsafeBitCast(pointer, to: UnsafePointer<xmlChar>.self) }
Is there a better, swiftier way without the bridge cast to NSString and unsafeBitCast?
Swiftiest way I can think of is to just use the
bitPattern:initializer:let xmlstr = str.utf8CString.map { xmlChar(bitPattern: $0) }This will give you an
ArrayofxmlChars. Hang onto that, and useArray'swithUnsafeBufferPointermethod when you need to pass anUnsafePointerto something:xmlstr.withUnsafeBufferPointer { someAPIThatWantsAPointer($0.baseAddress!) }Don't let the
UnsafePointerescape from the closure, as it won't be valid outside it.EDIT: How's this for a compromise? Instead of having your function return a pointer, have it take a closure.
Or, as an extension on
String: