@@ -167,8 +167,9 @@ internal func _cocoaStringSubscript(
167
167
}
168
168
169
169
@_effects ( releasenone)
170
- private func _NSStringCopyUTF8 (
170
+ private func _NSStringCopyBytes (
171
171
_ o: _StringSelectorHolder ,
172
+ encoding: UInt ,
172
173
into bufPtr: UnsafeMutableRawBufferPointer
173
174
) -> Int ? {
174
175
let ptr = bufPtr. baseAddress. _unsafelyUnwrappedUnchecked
@@ -179,7 +180,7 @@ private func _NSStringCopyUTF8(
179
180
ptr,
180
181
maxLength: bufPtr. count,
181
182
usedLength: & usedLen,
182
- encoding: _cocoaUTF8Encoding ,
183
+ encoding: encoding ,
183
184
options: 0 ,
184
185
range: _SwiftNSRange ( location: 0 , length: len) ,
185
186
remaining: & remainingRange
@@ -195,7 +196,23 @@ internal func _cocoaStringCopyUTF8(
195
196
_ target: _CocoaString ,
196
197
into bufPtr: UnsafeMutableRawBufferPointer
197
198
) -> Int ? {
198
- return _NSStringCopyUTF8 ( _objc ( target) , into: bufPtr)
199
+ return _NSStringCopyBytes (
200
+ _objc ( target) ,
201
+ encoding: _cocoaUTF8Encoding,
202
+ into: bufPtr
203
+ )
204
+ }
205
+
206
+ @_effects ( releasenone)
207
+ internal func _cocoaStringCopyASCII(
208
+ _ target: _CocoaString ,
209
+ into bufPtr: UnsafeMutableRawBufferPointer
210
+ ) -> Int ? {
211
+ return _NSStringCopyBytes (
212
+ _objc ( target) ,
213
+ encoding: _cocoaASCIIEncoding,
214
+ into: bufPtr
215
+ )
199
216
}
200
217
201
218
@_effects ( readonly)
@@ -346,17 +363,30 @@ internal func _bridgeTagged(
346
363
_internalInvariant ( _isObjCTaggedPointer ( cocoa) )
347
364
return _cocoaStringCopyUTF8 ( cocoa, into: bufPtr)
348
365
}
366
+
367
+ @_effects ( releasenone) // @opaque
368
+ internal func _bridgeTaggedASCII(
369
+ _ cocoa: _CocoaString ,
370
+ intoUTF8 bufPtr: UnsafeMutableRawBufferPointer
371
+ ) -> Int ? {
372
+ _internalInvariant ( _isObjCTaggedPointer ( cocoa) )
373
+ return _cocoaStringCopyASCII ( cocoa, into: bufPtr)
374
+ }
349
375
#endif
350
376
351
377
@_effects ( readonly)
352
378
private func _NSStringASCIIPointer( _ str: _StringSelectorHolder ) -> UnsafePointer < UInt8 > ? {
353
- // TODO(String bridging): Is there a better interface here? Ideally we'd be
354
- // able to ask for UTF8 rather than just ASCII
355
379
//TODO(String bridging): Unconditionally asking for nul-terminated contents is
356
380
// overly conservative and hurts perf with some NSStrings
357
381
return str. _fastCStringContents ( 1 ) ? . _asUInt8
358
382
}
359
383
384
+ @_effects ( readonly)
385
+ private func _NSStringUTF8Pointer( _ str: _StringSelectorHolder ) -> UnsafePointer < UInt8 > ? {
386
+ //We don't have a way to ask for UTF8 here currently
387
+ return _NSStringASCIIPointer ( str)
388
+ }
389
+
360
390
@_effects ( readonly) // @opaque
361
391
private func _withCocoaASCIIPointer< R> (
362
392
_ str: _CocoaString ,
@@ -371,7 +401,7 @@ private func _withCocoaASCIIPointer<R>(
371
401
if requireStableAddress {
372
402
return nil // tagged pointer strings don't support _fastCStringContents
373
403
}
374
- if let smol = _SmallString ( taggedCocoa : str) {
404
+ if let smol = _SmallString ( taggedASCIICocoa : str) {
375
405
return _StringGuts ( smol) . withFastUTF8 {
376
406
work ( $0. baseAddress. _unsafelyUnwrappedUnchecked)
377
407
}
@@ -385,6 +415,34 @@ private func _withCocoaASCIIPointer<R>(
385
415
return nil
386
416
}
387
417
418
+ @_effects ( readonly) // @opaque
419
+ private func _withCocoaUTF8Pointer< R> (
420
+ _ str: _CocoaString ,
421
+ requireStableAddress: Bool ,
422
+ work: ( UnsafePointer < UInt8 > ) -> R ?
423
+ ) -> R ? {
424
+ #if !(arch(i386) || arch(arm) || arch(arm64_32))
425
+ if _isObjCTaggedPointer ( str) {
426
+ if let ptr = getConstantTaggedCocoaContents ( str) ? . asciiContentsPointer {
427
+ return work ( ptr)
428
+ }
429
+ if requireStableAddress {
430
+ return nil // tagged pointer strings don't support _fastCStringContents
431
+ }
432
+ if let smol = _SmallString ( taggedCocoa: str) {
433
+ return _StringGuts ( smol) . withFastUTF8 {
434
+ work ( $0. baseAddress. _unsafelyUnwrappedUnchecked)
435
+ }
436
+ }
437
+ }
438
+ #endif
439
+ defer { _fixLifetime ( str) }
440
+ if let ptr = _NSStringUTF8Pointer ( _objc ( str) ) {
441
+ return work ( ptr)
442
+ }
443
+ return nil
444
+ }
445
+
388
446
@_effects ( readonly) // @opaque
389
447
internal func withCocoaASCIIPointer< R> (
390
448
_ str: _CocoaString ,
@@ -393,12 +451,26 @@ internal func withCocoaASCIIPointer<R>(
393
451
return _withCocoaASCIIPointer ( str, requireStableAddress: false , work: work)
394
452
}
395
453
454
+ @_effects ( readonly) // @opaque
455
+ internal func withCocoaUTF8Pointer< R> (
456
+ _ str: _CocoaString ,
457
+ work: ( UnsafePointer < UInt8 > ) -> R ?
458
+ ) -> R ? {
459
+ return _withCocoaUTF8Pointer ( str, requireStableAddress: false , work: work)
460
+ }
461
+
396
462
@_effects ( readonly)
397
463
internal func stableCocoaASCIIPointer( _ str: _CocoaString )
398
464
-> UnsafePointer < UInt8 > ? {
399
465
return _withCocoaASCIIPointer ( str, requireStableAddress: true , work: { $0 } )
400
466
}
401
467
468
+ @_effects ( readonly)
469
+ internal func stableCocoaUTF8Pointer( _ str: _CocoaString )
470
+ -> UnsafePointer < UInt8 > ? {
471
+ return _withCocoaUTF8Pointer ( str, requireStableAddress: true , work: { $0 } )
472
+ }
473
+
402
474
private enum CocoaStringPointer {
403
475
case ascii( UnsafePointer < UInt8 > )
404
476
case utf8( UnsafePointer < UInt8 > )
0 commit comments