File tree Expand file tree Collapse file tree 2 files changed +28
-4
lines changed Expand file tree Collapse file tree 2 files changed +28
-4
lines changed Original file line number Diff line number Diff line change 15
15
internal func _allASCII( _ input: UnsafeBufferPointer < UInt8 > ) -> Bool {
16
16
// NOTE: Avoiding for-in syntax to avoid bounds checks
17
17
//
18
- // TODO(String performance): Vectorize and/or incorporate into validity
19
- // checking, perhaps both.
18
+ // TODO(String performance): SIMD-ize
20
19
//
21
20
let ptr = input. baseAddress. _unsafelyUnwrappedUnchecked
22
21
var i = 0
23
- while i < input. count {
24
- guard ptr [ i] <= 0x7F else { return false }
22
+
23
+ let count = input. count
24
+ let stride = MemoryLayout< UInt> . stride
25
+ let address = Int ( bitPattern: ptr)
26
+
27
+ let wordASCIIMask = UInt ( truncatingIfNeeded: 0x8080_8080_8080_8080 as UInt64 )
28
+ let byteASCIIMask = UInt8 ( truncatingIfNeeded: wordASCIIMask)
29
+
30
+ while ( address &+ i) % stride != 0 && i < count {
31
+ guard ptr [ i] & byteASCIIMask == 0 else { return false }
32
+ i &+= 1
33
+ }
34
+
35
+ while ( i &+ stride) <= count {
36
+ let word : UInt = UnsafePointer (
37
+ bitPattern: address &+ i
38
+ ) . _unsafelyUnwrappedUnchecked. pointee
39
+ guard word & wordASCIIMask == 0 else { return false }
40
+ i &+= stride
41
+ }
42
+
43
+ while i < count {
44
+ guard ptr [ i] & byteASCIIMask == 0 else { return false }
25
45
i &+= 1
26
46
}
27
47
return true
Original file line number Diff line number Diff line change @@ -36,6 +36,10 @@ extension UTF8ValidationResult: Equatable {}
36
36
private struct UTF8ValidationError : Error { }
37
37
38
38
internal func validateUTF8( _ buf: UnsafeBufferPointer < UInt8 > ) -> UTF8ValidationResult {
39
+ if _allASCII ( buf) {
40
+ return . success( UTF8ExtraInfo ( isASCII: true ) )
41
+ }
42
+
39
43
var iter = buf. makeIterator ( )
40
44
var lastValidIndex = buf. startIndex
41
45
You can’t perform that action at this time.
0 commit comments