@@ -966,39 +966,6 @@ extension Unicode.Scalar.Properties {
966
966
}
967
967
}
968
968
969
- /// Executes a block that will attempt to store text in the memory owned by the
970
- /// given string storage object, returning the length of the text.
971
- ///
972
- /// The closure is assumed to return an `Int32` value (the convention of ICU's C
973
- /// functions) that is equal to the length of the string being stored. If the
974
- /// storage object is not large enough to hold the string, it is replaced by one
975
- /// that is exactly the required size and the closure is executed one more time
976
- /// to populate it.
977
- @_inlineable
978
- @_versioned
979
- internal func _expandingStorageIfNeeded<
980
- CodeUnit: UnsignedInteger & FixedWidthInteger
981
- > (
982
- _ storage: inout _SwiftStringStorage < CodeUnit > ,
983
- body: ( _SwiftStringStorage < CodeUnit > ) throws -> Int32
984
- ) rethrows -> Int {
985
- let z = try body ( storage)
986
- let correctSize = Int ( z)
987
- if correctSize > storage. capacity {
988
- // If the buffer wasn't large enough, replace it with one that is the
989
- // correct size and execute the closure again.
990
- storage = _SwiftStringStorage< CodeUnit> . create(
991
- capacity: correctSize,
992
- count: correctSize)
993
- return Int ( try body ( storage) )
994
- } else {
995
- // Otherwise, the buffer has been populated; update its count to the correct
996
- // value.
997
- storage. count = correctSize
998
- return correctSize
999
- }
1000
- }
1001
-
1002
969
extension Unicode . Scalar . Properties {
1003
970
1004
971
internal func _scalarName(
@@ -1069,6 +1036,67 @@ extension Unicode.Scalar.Properties {
1069
1036
1070
1037
extension Unicode . Scalar . Properties {
1071
1038
1039
+ // The type of ICU case conversion functions.
1040
+ internal typealias _U_StrToX = (
1041
+ /* dest */ UnsafeMutablePointer < __swift_stdlib_UChar > ,
1042
+ /* destCapacity */ Int32 ,
1043
+ /* src */ UnsafePointer < __swift_stdlib_UChar > ,
1044
+ /* srcLength */ Int32 ,
1045
+ /* locale */ UnsafePointer < Int8 > ,
1046
+ /* pErrorCode */ UnsafeMutablePointer < __swift_stdlib_UErrorCode >
1047
+ ) -> Int32
1048
+
1049
+ /// Applies the given ICU string mapping to the scalar.
1050
+ ///
1051
+ /// This function attempts first to write the mapping into a stack-based
1052
+ /// UTF-16 buffer capable of holding 16 code units, which should be enough for
1053
+ /// all current case mappings. In the event more space is needed, it will be
1054
+ /// allocated on the heap.
1055
+ internal func _applyMapping( _ u_strTo: _U_StrToX ) -> String {
1056
+ var scratchBuffer = _Normalization. _SegmentOutputBuffer ( allZeros: ( ) )
1057
+ let count = scratchBuffer. withUnsafeMutableBufferPointer { bufPtr -> Int in
1058
+ var utf16 = _utf16
1059
+ return withUnsafePointer ( to: & utf16. 0 ) { utf16Pointer in
1060
+ var err = __swift_stdlib_U_ZERO_ERROR
1061
+ let correctSize = u_strTo (
1062
+ bufPtr. baseAddress. _unsafelyUnwrappedUnchecked,
1063
+ Int32 ( bufPtr. count) ,
1064
+ utf16Pointer,
1065
+ Int32 ( _utf16Length) ,
1066
+ " " ,
1067
+ & err)
1068
+ guard err. isSuccess ||
1069
+ err == __swift_stdlib_U_BUFFER_OVERFLOW_ERROR else {
1070
+ fatalError ( " Unexpected error case-converting Unicode scalar. " )
1071
+ }
1072
+ return Int ( correctSize)
1073
+ }
1074
+ }
1075
+ if _fastPath ( count <= scratchBuffer. count) {
1076
+ scratchBuffer. count = count
1077
+ return String . _fromWellFormedUTF16CodeUnits ( scratchBuffer)
1078
+ }
1079
+ var array = Array < UInt16 > ( repeating: 0 , count: count)
1080
+ array. withUnsafeMutableBufferPointer { bufPtr in
1081
+ var utf16 = _utf16
1082
+ withUnsafePointer ( to: & utf16. 0 ) { utf16Pointer in
1083
+ var err = __swift_stdlib_U_ZERO_ERROR
1084
+ let correctSize = u_strTo (
1085
+ bufPtr. baseAddress. _unsafelyUnwrappedUnchecked,
1086
+ Int32 ( bufPtr. count) ,
1087
+ utf16Pointer,
1088
+ Int32 ( _utf16Length) ,
1089
+ " " ,
1090
+ & err)
1091
+ guard err. isSuccess else {
1092
+ fatalError ( " Unexpected error case-converting Unicode scalar. " )
1093
+ }
1094
+ _sanityCheck ( count == correctSize, " inconsistent ICU behavior " )
1095
+ }
1096
+ }
1097
+ return String . _fromWellFormedUTF16CodeUnits ( array [ ..< count] )
1098
+ }
1099
+
1072
1100
/// The lowercase mapping of the scalar.
1073
1101
///
1074
1102
/// This property is a `String`, not a `Unicode.Scalar` or `Character`,
@@ -1080,28 +1108,7 @@ extension Unicode.Scalar.Properties {
1080
1108
/// This property corresponds to the `Lowercase_Mapping` property in the
1081
1109
/// [Unicode Standard](http://www.unicode.org/versions/latest/).
1082
1110
public var lowercaseMapping : String {
1083
- let initialCapacity = 1
1084
-
1085
- var storage = _SwiftStringStorage< UTF16 . CodeUnit> . create(
1086
- capacity: initialCapacity,
1087
- count: 0 )
1088
-
1089
- _ = _expandingStorageIfNeeded ( & storage) { storage in
1090
- var utf16 = _utf16
1091
- return withUnsafePointer ( to: & utf16. 0 ) { utf16Pointer in
1092
- var err = __swift_stdlib_U_ZERO_ERROR
1093
- let correctSize = __swift_stdlib_u_strToLower (
1094
- storage. start, Int32 ( storage. capacity) ,
1095
- utf16Pointer, Int32 ( _utf16Length) , " " , & err)
1096
- guard err. isSuccess ||
1097
- err == __swift_stdlib_U_BUFFER_OVERFLOW_ERROR else {
1098
- fatalError (
1099
- " u_strToLower: Unexpected error lowercasing Unicode scalar. " )
1100
- }
1101
- return correctSize
1102
- }
1103
- }
1104
- return String ( _storage: storage)
1111
+ return _applyMapping ( __swift_stdlib_u_strToLower)
1105
1112
}
1106
1113
1107
1114
/// The titlecase mapping of the scalar.
@@ -1115,28 +1122,9 @@ extension Unicode.Scalar.Properties {
1115
1122
/// This property corresponds to the `Titlecase_Mapping` property in the
1116
1123
/// [Unicode Standard](http://www.unicode.org/versions/latest/).
1117
1124
public var titlecaseMapping : String {
1118
- let initialCapacity = 1
1119
-
1120
- var storage = _SwiftStringStorage< UTF16 . CodeUnit> . create(
1121
- capacity: initialCapacity,
1122
- count: 0 )
1123
-
1124
- _ = _expandingStorageIfNeeded ( & storage) { storage in
1125
- var utf16 = _utf16
1126
- return withUnsafePointer ( to: & utf16. 0 ) { utf16Pointer in
1127
- var err = __swift_stdlib_U_ZERO_ERROR
1128
- let correctSize = __swift_stdlib_u_strToTitle (
1129
- storage. start, Int32 ( storage. capacity) ,
1130
- utf16Pointer, Int32 ( _utf16Length) , nil , " " , & err)
1131
- guard err. isSuccess ||
1132
- err == __swift_stdlib_U_BUFFER_OVERFLOW_ERROR else {
1133
- fatalError (
1134
- " u_strToTitle: Unexpected error titlecasing Unicode scalar. " )
1135
- }
1136
- return correctSize
1137
- }
1125
+ return _applyMapping { ptr, cap, src, len, locale, err in
1126
+ return __swift_stdlib_u_strToTitle ( ptr, cap, src, len, nil , locale, err)
1138
1127
}
1139
- return String ( _storage: storage)
1140
1128
}
1141
1129
1142
1130
/// The uppercase mapping of the scalar.
@@ -1150,28 +1138,7 @@ extension Unicode.Scalar.Properties {
1150
1138
/// This property corresponds to the `Uppercase_Mapping` property in the
1151
1139
/// [Unicode Standard](http://www.unicode.org/versions/latest/).
1152
1140
public var uppercaseMapping : String {
1153
- let initialCapacity = 1
1154
-
1155
- var storage = _SwiftStringStorage< UTF16 . CodeUnit> . create(
1156
- capacity: initialCapacity,
1157
- count: 0 )
1158
-
1159
- _ = _expandingStorageIfNeeded ( & storage) { storage in
1160
- var utf16 = _utf16
1161
- return withUnsafePointer ( to: & utf16. 0 ) { utf16Pointer in
1162
- var err = __swift_stdlib_U_ZERO_ERROR
1163
- let correctSize = __swift_stdlib_u_strToUpper (
1164
- storage. start, Int32 ( storage. capacity) ,
1165
- utf16Pointer, Int32 ( _utf16Length) , " " , & err)
1166
- guard err. isSuccess ||
1167
- err == __swift_stdlib_U_BUFFER_OVERFLOW_ERROR else {
1168
- fatalError (
1169
- " u_strToUpper: Unexpected error uppercasing Unicode scalar. " )
1170
- }
1171
- return correctSize
1172
- }
1173
- }
1174
- return String ( _storage: storage)
1141
+ return _applyMapping ( __swift_stdlib_u_strToUpper)
1175
1142
}
1176
1143
}
1177
1144
0 commit comments