// RUN: %empty-directory(%t) // RUN: if [ %target-runtime == "objc" ]; \ // RUN: then \ // RUN: %target-clang -fobjc-arc %S/Inputs/NSSlowString/NSSlowString.m -c -o %t/NSSlowString.o && \ // RUN: %target-build-swift -I %S/Inputs/NSSlowString/ %t/NSSlowString.o %s -o %t/String; \ // RUN: else \ // RUN: %target-build-swift %s -o %t/String; \ // RUN: fi // RUN: %target-codesign %t/String // RUN: %target-run %t/String // REQUIRES: executable_test // XFAIL: interpret import StdlibUnittest import StdlibCollectionUnittest #if _runtime(_ObjC) import NSSlowString import Foundation // For NSRange #endif extension String { func withFastUTF8IfAvailable( _ f: (UnsafeBufferPointer) throws -> R ) rethrows -> R? { return try utf8.withContiguousStorageIfAvailable(f) } var isFastUTF8: Bool { return withFastUTF8IfAvailable({ _ in return 0 }) != nil } mutating func makeNative() { self += "" } var isASCII: Bool { return utf8.allSatisfy { $0 < 0x7f } } } var UTF8Tests = TestSuite("StringUTF8Tests") var strings: Array = [ "abcd", "abcdefghijklmnop", "abcde\u{301}fghijk", "a\u{301}", "👻", "Spooky long string. 👻", "в чащах юга жил-был цитрус? да, но фальшивый экземпляр", "日", ] let kCFStringEncodingASCII: UInt32 = 0x0600 UTF8Tests.test("Contiguous Access") { for string in strings { print(string) // Native strings are contiguous UTF-8 expectTrue(string.isFastUTF8) expectEqualSequence( Array(string.utf8), string.withFastUTF8IfAvailable(Array.init)!) // FIXME: Bridge small non-ASCII as StringStorage // expectTrue(((string as NSString) as String).isFastUTF8) var copy = string expectTrue(copy.isFastUTF8) copy.makeNative() expectTrue(copy.isFastUTF8) // FIXME: Bridge small non-ASCII as StringStorage // expectTrue(((copy as NSString) as String).isFastUTF8) #if _runtime(_ObjC) // Lazily bridged strings are not contiguous UTF-8 var slowString = NSSlowString(string: string) as String expectFalse(slowString.isFastUTF8) expectEqualSequence(string.utf8, slowString.utf8) // They become fast when mutated slowString.makeNative() expectTrue(slowString.isFastUTF8) expectEqualSequence( string.utf8, slowString.withFastUTF8IfAvailable(Array.init)!) // Contiguous ASCII CFStrings provide access, even if lazily bridged if string.isASCII { let cfString = string.withCString { CFStringCreateWithCString(nil, $0, kCFStringEncodingASCII)! } as String expectTrue(cfString.isFastUTF8) expectEqualSequence( string.utf8, cfString.withFastUTF8IfAvailable(Array.init)!) } #endif } } runAllTests()