Skip to content

Commit 1099962

Browse files
authored
Merge pull request #1225 from dplanitzer/NSString-contents-of-file
2 parents aee3ba4 + f7f5258 commit 1099962

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

Foundation/NSString.swift

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,33 +1248,37 @@ extension NSString {
12481248
public convenience init(contentsOf url: URL, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
12491249
let readResult = try NSData(contentsOf: url, options:[])
12501250

1251-
var offset = 0
1251+
let encoding: UInt
1252+
let offset: Int
12521253
let bytePtr = readResult.bytes.bindMemory(to: UInt8.self, capacity:readResult.length)
12531254
if readResult.length >= 4 && bytePtr[0] == 0xFF && bytePtr[1] == 0xFE && bytePtr[2] == 0x00 && bytePtr[3] == 0x00 {
1254-
enc?.pointee = String.Encoding.utf32LittleEndian.rawValue
1255+
encoding = String.Encoding.utf32LittleEndian.rawValue
12551256
offset = 4
12561257
}
12571258
else if readResult.length >= 2 && bytePtr[0] == 0xFE && bytePtr[1] == 0xFF {
1258-
enc?.pointee = String.Encoding.utf16BigEndian.rawValue
1259+
encoding = String.Encoding.utf16BigEndian.rawValue
12591260
offset = 2
12601261
}
12611262
else if readResult.length >= 2 && bytePtr[0] == 0xFF && bytePtr[1] == 0xFE {
1262-
enc?.pointee = String.Encoding.utf16LittleEndian.rawValue
1263+
encoding = String.Encoding.utf16LittleEndian.rawValue
12631264
offset = 2
12641265
}
12651266
else if readResult.length >= 4 && bytePtr[0] == 0x00 && bytePtr[1] == 0x00 && bytePtr[2] == 0xFE && bytePtr[3] == 0xFF {
1266-
enc?.pointee = String.Encoding.utf32BigEndian.rawValue
1267+
encoding = String.Encoding.utf32BigEndian.rawValue
12671268
offset = 4
12681269
}
12691270
else {
12701271
//Need to work on more conditions. This should be the default
1271-
enc?.pointee = String.Encoding.utf8.rawValue
1272+
encoding = String.Encoding.utf8.rawValue
1273+
offset = 0
12721274
}
12731275

1276+
enc?.pointee = encoding
1277+
12741278
// Since the encoding being passed includes the byte order the BOM wont be checked or skipped, so pass offset to
12751279
// manually skip the BOM header.
1276-
guard let enc = enc, let cf = CFStringCreateWithBytes(kCFAllocatorDefault, bytePtr + offset, readResult.length - offset,
1277-
CFStringConvertNSStringEncodingToEncoding(enc.pointee), true) else {
1280+
guard let cf = CFStringCreateWithBytes(kCFAllocatorDefault, bytePtr + offset, readResult.length - offset,
1281+
CFStringConvertNSStringEncodingToEncoding(encoding), true) else {
12781282
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInapplicableStringEncoding.rawValue, userInfo: [
12791283
"NSDebugDescription" : "Unable to create a string using the specified encoding."
12801284
])
@@ -1286,11 +1290,11 @@ extension NSString {
12861290
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInapplicableStringEncoding.rawValue, userInfo: [
12871291
"NSDebugDescription" : "Unable to bridge CFString to String."
12881292
])
1289-
}
1293+
}
12901294
}
12911295

12921296
public convenience init(contentsOfFile path: String, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
1293-
NSUnimplemented()
1297+
try self.init(contentsOf: URL(fileURLWithPath: path), usedEncoding: enc)
12941298
}
12951299
}
12961300

TestFoundation/TestNSString.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class TestNSString : XCTestCase {
6666
("test_rangeOfCharacterFromSet", test_rangeOfCharacterFromSet ),
6767
("test_CFStringCreateMutableCopy", test_CFStringCreateMutableCopy),
6868
("test_FromContentsOfURL",test_FromContentsOfURL),
69+
("test_FromContentOfFileUsedEncodingIgnored", test_FromContentOfFileUsedEncodingIgnored),
70+
("test_FromContentOfFileUsedEncodingUTF8", test_FromContentOfFileUsedEncodingUTF8),
6971
("test_FromContentsOfURLUsedEncodingUTF16BE", test_FromContentsOfURLUsedEncodingUTF16BE),
7072
("test_FromContentsOfURLUsedEncodingUTF16LE", test_FromContentsOfURLUsedEncodingUTF16LE),
7173
("test_FromContentsOfURLUsedEncodingUTF32BE", test_FromContentsOfURLUsedEncodingUTF32BE),
@@ -303,6 +305,32 @@ class TestNSString : XCTestCase {
303305
}
304306
}
305307

308+
func test_FromContentOfFileUsedEncodingIgnored() {
309+
let testFilePath = testBundle().path(forResource: "NSStringTestData", ofType: "txt")
310+
XCTAssertNotNil(testFilePath)
311+
312+
do {
313+
let str = try NSString(contentsOfFile: testFilePath!, usedEncoding: nil)
314+
XCTAssertEqual(str, "swift-corelibs-foundation")
315+
} catch {
316+
XCTFail("Unable to init NSString from contentsOfFile:encoding:")
317+
}
318+
}
319+
320+
func test_FromContentOfFileUsedEncodingUTF8() {
321+
let testFilePath = testBundle().path(forResource: "NSStringTestData", ofType: "txt")
322+
XCTAssertNotNil(testFilePath)
323+
324+
do {
325+
var encoding: UInt = 0
326+
let str = try NSString(contentsOfFile: testFilePath!, usedEncoding: &encoding)
327+
XCTAssertEqual(str, "swift-corelibs-foundation")
328+
XCTAssertEqual(encoding, String.Encoding.utf8.rawValue, "Wrong encoding detected from UTF8 file")
329+
} catch {
330+
XCTFail("Unable to init NSString from contentsOfFile:encoding:")
331+
}
332+
}
333+
306334
func test_FromContentsOfURLUsedEncodingUTF16BE() {
307335
guard let testFileURL = testBundle().url(forResource: "NSString-UTF16-BE-data", withExtension: "txt") else {
308336
XCTFail("URL for NSString-UTF16-BE-data.txt is nil")

0 commit comments

Comments
 (0)