File tree Expand file tree Collapse file tree 2 files changed +38
-1
lines changed Expand file tree Collapse file tree 2 files changed +38
-1
lines changed Original file line number Diff line number Diff line change @@ -90,6 +90,26 @@ internal func _cocoaStringCopyUTF8(
90
90
return len == converted ? count : nil
91
91
}
92
92
93
+ @_effects ( readonly)
94
+ internal func _cocoaStringUTF8Count(
95
+ _ target: _CocoaString ,
96
+ range: Range < Int >
97
+ ) -> Int ? {
98
+ var count = 0
99
+ let len = _stdlib_binary_CFStringGetLength ( target)
100
+ let converted = _swift_stdlib_CFStringGetBytes (
101
+ target,
102
+ _swift_shims_CFRange ( location: range. startIndex, length: range. count) ,
103
+ kCFStringEncodingUTF8,
104
+ 0 ,
105
+ 0 ,
106
+ UnsafeMutablePointer < UInt8 > ( Builtin . inttoptr_Word ( 0 . _builtinWordValue) ) ,
107
+ 0 ,
108
+ & count
109
+ )
110
+ return converted == len ? count : nil
111
+ }
112
+
93
113
@_effects ( readonly)
94
114
internal func _cocoaStringCompare(
95
115
_ string: _CocoaString , _ other: _CocoaString
Original file line number Diff line number Diff line change @@ -470,14 +470,31 @@ extension String.UTF8View {
470
470
@_effects ( releasenone)
471
471
internal func _foreignDistance( from i: Index , to j: Index ) -> Int {
472
472
_internalInvariant ( _guts. isForeign)
473
+
474
+ #if _runtime(_ObjC)
475
+ // Currently, foreign means NSString
476
+ if let count = _cocoaStringUTF8Count (
477
+ _guts. _object. cocoaObject,
478
+ range: i. _encodedOffset ..< j. _encodedOffset
479
+ ) {
480
+ //_cocoaStringUTF8Count gave us the scalar aligned count, but we still
481
+ //need to compensate for sub-scalar indexing, e.g. if `i` is in the middle
482
+ //of a two-byte UTF8 scalar.
483
+ let refinedCount = count - ( i. transcodedOffset + j. transcodedOffset)
484
+ _internalInvariant ( refinedCount == _distance ( from: i, to: j) )
485
+ return refinedCount
486
+ }
487
+ #endif
488
+
473
489
return _distance ( from: i, to: j)
490
+
474
491
}
475
492
476
493
@usableFromInline @inline ( never)
477
494
@_effects ( releasenone)
478
495
internal func _foreignCount( ) -> Int {
479
496
_internalInvariant ( _guts. isForeign)
480
- return _distance ( from: startIndex, to: endIndex)
497
+ return _foreignDistance ( from: startIndex, to: endIndex)
481
498
}
482
499
}
483
500
You can’t perform that action at this time.
0 commit comments