Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3: convert a null-terminated UnsafePointer<UInt8> to a string

Tags:

string

swift

I have a c api that returns a null terminated string that is an array of type unsigned char* (which would correspond to UnsafePointer<UInt8>).

Swift has the initializer String(validatingUTF8:), but the argument has to be UnsafePointer<CChar> (a.k.a. UnsafePointer<Int8>), and there is no trivial way to convert between the two.

How do I convert from this null-terminated c-string to a Swift string?

like image 721
AthanasiusOfAlex Avatar asked Sep 16 '16 13:09

AthanasiusOfAlex


1 Answers

In Swift 3, String has two initializers

public init(cString: UnsafePointer<CChar>)
public init(cString: UnsafePointer<UInt8>)

therefore it can be created from (null-terminated) sequences of both signed and unsigned characters. So

let s = String(cString: yourCharPointer)

should just work.


String has another initializer

public init?(validatingUTF8 cString: UnsafePointer<CChar>)

which fails on ill-formed UTF-8 sequences instead of replacing them by the replacement characters. This init method has no counterpart taking unsigned characters.

Taking the existing implementations in CString.swift as examples, it is not too difficult to add this as an extension:

extension String {
    public init?(validatingUTF8 cString: UnsafePointer<UInt8>) {
        guard let (s, _) = String.decodeCString(cString, as: UTF8.self,
                                                repairingInvalidCodeUnits: false) else {
            return nil
        }
        self = s
    }
}

and then

if let s = String(validatingUTF8: yourCharPointer) {
    print(s)
} else {
    print("invalid UTF-8")
}

also works with (null-terminated) sequences of both signed and unsigned characters.

like image 163
Martin R Avatar answered Nov 15 '22 07:11

Martin R