Skip to content

Commit 56d04be

Browse files
committed
[stdlib] Rewrite _scalarName to fully use a small string
1 parent 47deadc commit 56d04be

File tree

1 file changed

+29
-29
lines changed

1 file changed

+29
-29
lines changed

stdlib/public/core/UnicodeScalarProperties.swift

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -962,40 +962,40 @@ extension Unicode.Scalar.Properties {
962962
internal func _scalarName(
963963
_ choice: __swift_stdlib_UCharNameChoice
964964
) -> String? {
965-
// Attempt to fit it into a small UTF-8 string first. Code points names are
966-
// guaranteed by the standard to be ASCII only.
967-
var smallString = _SmallUTF8String()
968-
var err = __swift_stdlib_U_ZERO_ERROR
969-
let correctSizeRaw = smallString._withMutableExcessCapacityBytes { ptr in
970-
return __swift_stdlib_u_charName(
971-
_value,
972-
choice,
973-
ptr.baseAddress._unsafelyUnwrappedUnchecked.assumingMemoryBound(
965+
// ICU writes a trailing nul. We allow ICU to store up to and including
966+
// `capacity` bytes. If ICU writes `capacity` bytes, then ICU will also
967+
// write nul into the count, which we will overwrite after.
968+
var smol = _SmallUTF8String()
969+
let count = smol._withAllUnsafeMutableBytes { bufPtr -> Int in
970+
var err = __swift_stdlib_U_ZERO_ERROR
971+
let count32 = __swift_stdlib_u_charName(
972+
_value, choice,
973+
bufPtr.baseAddress._unsafelyUnwrappedUnchecked.assumingMemoryBound(
974974
to: Int8.self),
975-
Int32(ptr.count),
976-
&err)
975+
Int32(bufPtr.count), &err)
976+
return Int(count32)
977977
}
978-
979-
let correctSize = Int(correctSizeRaw)
980-
if err.isSuccess {
981-
if correctSize == 0 { return nil }
982-
smallString.count = correctSize
983-
return String(_StringGuts(smallString))
984-
}
985-
// If the call wasn't successful, the only error we expect to see is buffer
986-
// overflow; anything else is a severe error.
987-
guard err == __swift_stdlib_U_BUFFER_OVERFLOW_ERROR else {
988-
fatalError("u_charName: Unexpected error retrieving scalar name.")
978+
guard count > 0 else { return nil }
979+
if count <= smol.capacity {
980+
smol.count = count
981+
return String(_StringGuts(smol))
989982
}
990983

991-
// If it didn't fit, we need to allocate the necessary amount of memory and
992-
// make a regular ASCII string.
993-
var (asciiArray, ptr) = [UInt8]._allocateUninitialized(correctSize)
994-
_ = ptr.withMemoryRebound(to: Int8.self, capacity: correctSize) { int8Ptr in
995-
err = __swift_stdlib_U_ZERO_ERROR
996-
__swift_stdlib_u_charName(_value, choice, int8Ptr, correctSizeRaw, &err)
984+
// Save room for nul
985+
var array = Array<UInt8>(repeating: 0, count: 1 + count)
986+
array.withUnsafeMutableBufferPointer { bufPtr in
987+
var err = __swift_stdlib_U_ZERO_ERROR
988+
let correctSize = __swift_stdlib_u_charName(
989+
_value, choice,
990+
UnsafeMutableRawPointer(bufPtr.baseAddress._unsafelyUnwrappedUnchecked)
991+
.assumingMemoryBound(to: Int8.self),
992+
Int32(bufPtr.count), &err)
993+
guard err.isSuccess else {
994+
fatalError("Unexpected error case-converting Unicode scalar.")
995+
}
996+
_sanityCheck(count == correctSize, "inconsistent ICU behavior")
997997
}
998-
return String._fromASCII(asciiArray)
998+
return String._fromWellFormedUTF8CodeUnitSequence(array[..<count])
999999
}
10001000

10011001
/// The published name of the scalar.

0 commit comments

Comments
 (0)