Skip to content

Instantly share code, notes, and snippets.

@yossan
Last active July 12, 2018 05:33
Show Gist options
  • Save yossan/91079df35609892722f3102246493394 to your computer and use it in GitHub Desktop.
Save yossan/91079df35609892722f3102246493394 to your computer and use it in GitHub Desktop.
Making UnsafeMutablePointer<UInt8> from String without Foundation.
// String → UTF8View → UnsafeMutablePointer<UInt8>
// Note: UTF8View.Element == UInt8
// Note: utf8CString: ContigiousArray<Int8>
func makeCString(from str: String) -> UnsafeMutablePointer<UInt8> {
var utf8 = Array(str.utf8)
utf8.append(0) // adds null character
let count = utf8.count
let result = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: count)
_ = result.initialize(from: utf8)
return result.baseAddress!
}
do {
let str = "abc abc"
let cstr = makeCString(from: str)
let restr = String(cString: cstr)
print(str == restr) // true
let str2 = "世界の皆様 おはようございます。 🌄 Good morning!"
let cstr2 = makeCString(from: str2)
let restr2 = String(cString: cstr2)
print(str2 == restr2) // true
let str3 = "✑ 🍍 🍎 ✒"
let cstr3 = makeCString(from: str3)
let restr3 = String(cString: cstr3)
print(str3 == restr3) // true
}
// Method 2
// String → UnsafePointer<UInt8> → UnsafeMutablePointer<UInt8>
// func withCString<Result, TargetEncoding>(encodedAs targetEncoding: TargetEncoding.Type, _ body: (UnsafePointer<TargetEncoding.CodeUnit>) throws -> Result) rethrows -> Result where TargetEncoding : _UnicodeEncoding
// Note: UTF8.CodeUnit = UInt8
func makeCString2(from str: String) -> UnsafeMutablePointer<UInt8> {
let count = str.utf8.count + 1
let result = UnsafeMutablePointer<UInt8>.allocate(capacity: count)
str.withCString(encodedAs: UTF8.self) { (baseAddress) in
// baseAddress: UnsafePointer<UInt8>
result.initialize(from: baseAddress, count: count)
}
return result
}
do {
let str = "abc abc"
let cstr = makeCString2(from: str)
let restr = String(cString: cstr)
print(str == restr) // true
let str2 = "世界の皆様 おはようございます。 🌄 Good morning!"
let cstr2 = makeCString2(from: str2)
let restr2 = String(cString: cstr2)
print(str2 == restr2) // true
let str3 = "✑ 🍍 🍎 ✒"
let cstr3 = makeCString2(from: str3)
let restr3 = String(cString: cstr3)
print(str3 == restr3) // true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment