Skip to content

Commit 40533f2

Browse files
author
Mohit Athwani
committed
Added basic implementation for NSString contentsOfURL:usedEncoding:
In NSString, for contentsOfURL:usedEncoding: checking the BOM of the received data and determinig whether encoding to be used should be UTF 16 BE Fixed guard statement to handle nil case Fixed indentation in test case Updated build.py file to include test input file Fixed Indentation in build.py
1 parent e3f514d commit 40533f2

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed

Foundation/NSString.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,33 @@ extension NSString {
12561256
}
12571257

12581258
public convenience init(contentsOf url: URL, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
1259-
NSUnimplemented()
1259+
let readResult = try NSData(contentsOf: url, options:[])
1260+
1261+
let bytePtr = readResult.bytes.bindMemory(to: UInt8.self, capacity:readResult.length)
1262+
if bytePtr[0] == 254 && bytePtr[1] == 255 {
1263+
enc?.pointee = String.Encoding.utf16BigEndian.rawValue
1264+
}
1265+
else if bytePtr[0] == 255 && bytePtr[1] == 254 {
1266+
enc?.pointee = String.Encoding.utf16LittleEndian.rawValue
1267+
}
1268+
else {
1269+
//Need to work on more conditions. This should be the default
1270+
enc?.pointee = String.Encoding.utf8.rawValue
1271+
}
1272+
1273+
guard let enc = enc, let cf = CFStringCreateWithBytes(kCFAllocatorDefault, bytePtr, readResult.length, CFStringConvertNSStringEncodingToEncoding(enc.pointee), true) else {
1274+
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInapplicableStringEncoding.rawValue, userInfo: [
1275+
"NSDebugDescription" : "Unable to create a string using the specified encoding."
1276+
])
1277+
}
1278+
var str: String?
1279+
if String._conditionallyBridgeFromObjectiveC(cf._nsObject, result: &str) {
1280+
self.init(str!)
1281+
} else {
1282+
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInapplicableStringEncoding.rawValue, userInfo: [
1283+
"NSDebugDescription" : "Unable to bridge CFString to String."
1284+
])
1285+
}
12601286
}
12611287

12621288
public convenience init(contentsOfFile path: String, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
108 Bytes
Binary file not shown.

TestFoundation/TestNSString.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class TestNSString : XCTestCase {
6666
("test_rangeOfCharacterFromSet", test_rangeOfCharacterFromSet ),
6767
("test_CFStringCreateMutableCopy", test_CFStringCreateMutableCopy),
6868
("test_FromContentsOfURL",test_FromContentsOfURL),
69+
("test_FromContentsOfURLUsedEncodingUTF16BE", test_FromContentsOfURLUsedEncodingUTF16BE),
6970
("test_FromContentOfFile",test_FromContentOfFile),
7071
("test_swiftStringUTF16", test_swiftStringUTF16),
7172
// This test takes forever on build servers; it has been seen up to 1852.084 seconds
@@ -299,6 +300,22 @@ class TestNSString : XCTestCase {
299300
}
300301
}
301302

303+
func test_FromContentsOfURLUsedEncodingUTF16BE() {
304+
guard let testFileURL = testBundle().url(forResource: "NSString-UTF16-BE-data", withExtension: "txt") else {
305+
XCTFail("URL for NSString-UTF16-BE-data.txt is nil")
306+
return
307+
}
308+
309+
do {
310+
var encoding: UInt = 0
311+
let string = try NSString(contentsOf: testFileURL, usedEncoding: &encoding)
312+
XCTAssertEqual(string, "NSString fromURL usedEncoding test with UTF16 BE file", "Wrong result when reading UTF16BE file")
313+
XCTAssertEqual(encoding, String.Encoding.utf16BigEndian.rawValue, "Wrong encoding detected from UTF16BE file")
314+
} catch {
315+
XCTFail("Unable to init NSString from contentsOf:encoding:")
316+
}
317+
}
318+
302319
func test_FromContentOfFile() {
303320
let testFilePath = testBundle().path(forResource: "NSStringTestData", ofType: "txt")
304321
XCTAssertNotNil(testFilePath)

build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@
459459
'TestFoundation/Resources/NSURLTestData.plist',
460460
'TestFoundation/Resources/Test.plist',
461461
'TestFoundation/Resources/NSStringTestData.txt',
462+
'TestFoundation/Resources/NSString-UTF16-BE-data.txt',
462463
'TestFoundation/Resources/NSXMLDocumentTestData.xml',
463464
'TestFoundation/Resources/PropertyList-1.0.dtd',
464465
'TestFoundation/Resources/NSXMLDTDTestData.xml',

0 commit comments

Comments
 (0)