Bridge non-ASCII SmallStrings as native Swift Strings rather than by creating CFStrings. This gets consistent behavior with non-smol Strings when the String contains a BOM

This commit is contained in:
David Smith
2019-06-28 14:19:28 -07:00
parent acee7c2a18
commit 27359bdec6
2 changed files with 43 additions and 9 deletions

View File

@@ -321,15 +321,25 @@ extension String {
@_effects(releasenone)
public // SPI(Foundation)
func _bridgeToObjectiveCImpl() -> AnyObject {
if _guts.isSmall {
// Smol ASCII a) may bridge to tagged pointers, b) can't contain a BOM
if _guts.isSmallASCII {
return _guts.asSmall.withUTF8 { bufPtr in
return _createCFString(
bufPtr.baseAddress._unsafelyUnwrappedUnchecked,
bufPtr.count,
kCFStringEncodingUTF8
bufPtr.baseAddress._unsafelyUnwrappedUnchecked,
bufPtr.count,
kCFStringEncodingUTF8
)
}
}
if _guts.isSmall {
// We can't form a tagged pointer String, so grow to a non-small String,
// and bridge that instead. Also avoids CF deleting any BOM that may be
// present
var copy = self
copy._guts.grow(_SmallString.capacity + 1)
_internalInvariant(!copy._guts.isSmall)
return copy._bridgeToObjectiveCImpl()
}
if _guts._object.isImmortal {
// TODO: We'd rather emit a valid ObjC object statically than create a
// shared string class instance.