mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add fast paths for String(decoding:…, as: Unicode.ASCII.self)
This commit is contained in:
@@ -50,12 +50,10 @@ internal func _allASCII(_ input: UnsafeBufferPointer<UInt8>) -> Bool {
|
||||
}
|
||||
|
||||
extension String {
|
||||
@usableFromInline
|
||||
internal static func _fromASCII(
|
||||
|
||||
internal static func _uncheckedFromASCII(
|
||||
_ input: UnsafeBufferPointer<UInt8>
|
||||
) -> String {
|
||||
_internalInvariant(_allASCII(input), "not actually ASCII")
|
||||
|
||||
if let smol = _SmallString(input) {
|
||||
return String(_StringGuts(smol))
|
||||
}
|
||||
@@ -63,6 +61,23 @@ extension String {
|
||||
let storage = __StringStorage.create(initializingFrom: input, isASCII: true)
|
||||
return storage.asString
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
internal static func _fromASCII(
|
||||
_ input: UnsafeBufferPointer<UInt8>
|
||||
) -> String {
|
||||
_internalInvariant(_allASCII(input), "not actually ASCII")
|
||||
return _uncheckedFromASCII(input)
|
||||
}
|
||||
|
||||
internal static func _fromASCIIValidating(
|
||||
_ input: UnsafeBufferPointer<UInt8>
|
||||
) -> String? {
|
||||
if _fastPath(_allASCII(input)) {
|
||||
return _uncheckedFromASCII(input)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public // SPI(Foundation)
|
||||
static func _tryFromUTF8(_ input: UnsafeBufferPointer<UInt8>) -> String? {
|
||||
@@ -166,9 +181,9 @@ extension String {
|
||||
|
||||
return contents.withUnsafeBufferPointer { String._uncheckedFromUTF8($0) }
|
||||
}
|
||||
|
||||
@usableFromInline @inline(never) // slow-path
|
||||
internal static func _fromCodeUnits<
|
||||
|
||||
@inline(never) // slow path
|
||||
private static func _slowFromCodeUnits<
|
||||
Input: Collection,
|
||||
Encoding: Unicode.Encoding
|
||||
>(
|
||||
@@ -194,6 +209,46 @@ extension String {
|
||||
let str = contents.withUnsafeBufferPointer { String._uncheckedFromUTF8($0) }
|
||||
return (str, repaired)
|
||||
}
|
||||
|
||||
@usableFromInline @inline(never) // can't be inlined w/out breaking ABI
|
||||
@_specialize(
|
||||
where Input == UnsafeBufferPointer<UInt8>, Encoding == Unicode.ASCII)
|
||||
@_specialize(
|
||||
where Input == Array<UInt8>, Encoding == Unicode.ASCII)
|
||||
internal static func _fromCodeUnits<
|
||||
Input: Collection,
|
||||
Encoding: Unicode.Encoding
|
||||
>(
|
||||
_ input: Input,
|
||||
encoding: Encoding.Type,
|
||||
repair: Bool
|
||||
) -> (String, repairsMade: Bool)?
|
||||
where Input.Element == Encoding.CodeUnit {
|
||||
guard _fastPath(encoding == Unicode.ASCII.self) else {
|
||||
return _slowFromCodeUnits(input, encoding: encoding, repair: repair)
|
||||
}
|
||||
|
||||
var result:String? = nil
|
||||
|
||||
if let contigBytes = input as? _HasContiguousBytes,
|
||||
contigBytes._providesContiguousBytesNoCopy {
|
||||
result = contigBytes.withUnsafeBytes { rawBufPtr in
|
||||
let buffer = UnsafeBufferPointer(
|
||||
start: rawBufPtr.baseAddress?.assumingMemoryBound(to: UInt8.self),
|
||||
count: rawBufPtr.count)
|
||||
return String._fromASCIIValidating(buffer)
|
||||
}
|
||||
} else {
|
||||
result = Array(input).withUnsafeBufferPointer {
|
||||
let buffer = UnsafeRawBufferPointer($0).bindMemory(to: UInt8.self)
|
||||
return String._fromASCIIValidating(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
return result != nil ?
|
||||
(result!, repairsMade: false) :
|
||||
_slowFromCodeUnits(input, encoding: encoding, repair: repair)
|
||||
}
|
||||
|
||||
public // @testable
|
||||
static func _fromInvalidUTF16(
|
||||
|
||||
Reference in New Issue
Block a user