Skip to content

Commit 414ebff

Browse files
authored
Merge pull request #1385 from spevans/pr_nsmutable_data_init_fixes
2 parents 90642c9 + 1423298 commit 414ebff

File tree

2 files changed

+156
-6
lines changed

2 files changed

+156
-6
lines changed

Foundation/NSData.swift

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
180180
/// Initializes a data object with the contents of another data object.
181181
public init(data: Data) {
182182
super.init()
183-
_init(bytes: UnsafeMutableRawPointer(mutating: data._nsObject.bytes), length: length, copy: true)
183+
_init(bytes: UnsafeMutableRawPointer(mutating: data._nsObject.bytes), length: data.count, copy: true)
184184
}
185185

186186
/// Initializes a data object with the data from the location specified by a given URL.
@@ -966,7 +966,7 @@ open class NSMutableData : NSData {
966966
}
967967

968968
// NOTE: the deallocator block here is implicitly @escaping by virtue of it being optional
969-
public override init(bytes: UnsafeMutableRawPointer?, length: Int, copy: Bool = false, deallocator: (/*@escaping*/ (UnsafeMutableRawPointer, Int) -> Void)? = nil) {
969+
fileprivate override init(bytes: UnsafeMutableRawPointer?, length: Int, copy: Bool = false, deallocator: (/*@escaping*/ (UnsafeMutableRawPointer, Int) -> Void)? = nil) {
970970
super.init(bytes: bytes, length: length, copy: copy, deallocator: deallocator)
971971
}
972972

@@ -990,6 +990,47 @@ open class NSMutableData : NSData {
990990
super.init(coder: aDecoder)
991991
}
992992

993+
public override init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int) {
994+
super.init(bytesNoCopy: bytes, length: length)
995+
}
996+
997+
public override init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int, deallocator: ((UnsafeMutableRawPointer, Int) -> Void)? = nil) {
998+
super.init(bytesNoCopy: bytes, length: length, deallocator: deallocator)
999+
}
1000+
1001+
public override init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int, freeWhenDone: Bool) {
1002+
super.init(bytesNoCopy: bytes, length: length, freeWhenDone: freeWhenDone)
1003+
}
1004+
1005+
public override init(data: Data) {
1006+
super.init(data: data)
1007+
}
1008+
1009+
public override init?(contentsOfFile path: String) {
1010+
super.init(contentsOfFile: path)
1011+
}
1012+
1013+
public override init(contentsOfFile path: String, options: NSData.ReadingOptions = []) throws {
1014+
try super.init(contentsOfFile: path, options: options)
1015+
}
1016+
1017+
public override init?(contentsOf url: URL) {
1018+
super.init(contentsOf: url)
1019+
}
1020+
1021+
public override init(contentsOf url: URL, options: NSData.ReadingOptions = []) throws {
1022+
try super.init(contentsOf: url, options: options)
1023+
}
1024+
1025+
public override init?(base64Encoded base64Data: Data, options: NSData.Base64DecodingOptions = []) {
1026+
super.init(base64Encoded: base64Data, options: options)
1027+
}
1028+
1029+
public override init?(base64Encoded base64Data: String, options: NSData.Base64DecodingOptions = []) {
1030+
super.init(base64Encoded: base64Data, options: options)
1031+
}
1032+
1033+
9931034
// MARK: - Funnel Methods
9941035
/// A pointer to the data contained by the mutable data object.
9951036
open var mutableBytes: UnsafeMutableRawPointer {

TestFoundation/TestNSData.swift

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ class TestNSData: XCTestCase {
206206
("test_dataHash", test_dataHash),
207207
("test_genericBuffers", test_genericBuffers),
208208
("test_writeFailure", test_writeFailure),
209-
("testBasicConstruction", testBasicConstruction),
210209
("testBridgingDefault", testBridgingDefault),
211210
("testBridgingMutable", testBridgingMutable),
212211
("testCopyBytes_oversized", testCopyBytes_oversized),
@@ -248,8 +247,14 @@ class TestNSData: XCTestCase {
248247
("test_initializeWithBase64EncodedStringGetsDecodedData", test_initializeWithBase64EncodedStringGetsDecodedData),
249248
("test_base64DecodeWithPadding1", test_base64DecodeWithPadding1),
250249
("test_base64DecodeWithPadding2", test_base64DecodeWithPadding2),
251-
("test_rangeOfData",test_rangeOfData),
252-
("test_initMutableDataWithLength", test_initMutableDataWithLength),
250+
("test_rangeOfData", test_rangeOfData),
251+
("test_initNSMutableData()", test_initNSMutableData),
252+
("test_initNSMutableDataWithLength", test_initNSMutableDataWithLength),
253+
("test_initNSMutableDataWithCapacity", test_initNSMutableDataWithCapacity),
254+
("test_initNSMutableDataFromData", test_initNSMutableDataFromData),
255+
("test_initNSMutableDataFromBytes", test_initNSMutableDataFromBytes),
256+
("test_initNSMutableDataContentsOf", test_initNSMutableDataContentsOf),
257+
("test_initNSMutableDataBase64", test_initNSMutableDataBase64),
253258
("test_replaceBytes", test_replaceBytes),
254259
("test_replaceBytesWithNil", test_replaceBytesWithNil),
255260
("test_initDataWithCapacity", test_initDataWithCapacity),
@@ -811,12 +816,116 @@ class TestNSData: XCTestCase {
811816

812817
}
813818

814-
func test_initMutableDataWithLength() {
819+
// Check all of the NSMutableData constructors are available.
820+
func test_initNSMutableData() {
821+
let mData = NSMutableData()
822+
XCTAssertNotNil(mData)
823+
XCTAssertEqual(mData.length, 0)
824+
}
825+
826+
func test_initNSMutableDataWithLength() {
815827
let mData = NSMutableData(length: 30)
816828
XCTAssertNotNil(mData)
817829
XCTAssertEqual(mData!.length, 30)
818830
}
819831

832+
func test_initNSMutableDataWithCapacity() {
833+
let mData = NSMutableData(capacity: 30)
834+
XCTAssertNotNil(mData)
835+
XCTAssertEqual(mData!.length, 0)
836+
}
837+
838+
func test_initNSMutableDataFromData() {
839+
let data = Data(bytes: [1, 2, 3])
840+
let mData = NSMutableData(data: data)
841+
XCTAssertEqual(mData.length, 3)
842+
XCTAssertEqual(NSData(data: data), mData)
843+
}
844+
845+
func test_initNSMutableDataFromBytes() {
846+
let data = Data([1, 2, 3, 4, 5, 6])
847+
var testBytes: [UInt8] = [1, 2, 3, 4, 5, 6]
848+
849+
let md1 = NSMutableData(bytes: &testBytes, length: testBytes.count)
850+
XCTAssertEqual(md1, NSData(data: data))
851+
852+
let md2 = NSMutableData(bytes: nil, length: 0)
853+
XCTAssertEqual(md2.length, 0)
854+
855+
let testBuffer = malloc(testBytes.count)!
856+
let md3 = NSMutableData(bytesNoCopy: testBuffer, length: testBytes.count)
857+
md3.replaceBytes(in: NSRange(location: 0, length: testBytes.count), withBytes: &testBytes)
858+
XCTAssertEqual(md3, NSData(data: data))
859+
860+
let md4 = NSMutableData(bytesNoCopy: &testBytes, length: testBytes.count, deallocator: nil)
861+
XCTAssertEqual(md4.length, testBytes.count)
862+
863+
let md5 = NSMutableData(bytesNoCopy: &testBytes, length: testBytes.count, freeWhenDone: false)
864+
XCTAssertEqual(md5, NSData(data: data))
865+
}
866+
867+
func test_initNSMutableDataContentsOf() {
868+
let testDir = testBundle().resourcePath
869+
let filename = testDir!.appending("/NSStringTestData.txt")
870+
let url = URL(fileURLWithPath: filename)
871+
872+
func testText(_ mData: NSMutableData?) {
873+
guard let mData = mData else {
874+
XCTFail("Contents of file are Nil")
875+
return
876+
}
877+
if let txt = String(data: Data(referencing: mData), encoding: .ascii) {
878+
XCTAssertEqual(txt, "swift-corelibs-foundation")
879+
} else {
880+
XCTFail("Cant convert to string")
881+
}
882+
}
883+
884+
let contents1 = NSMutableData(contentsOfFile: filename)
885+
XCTAssertNotNil(contents1)
886+
testText(contents1)
887+
888+
let contents2 = try? NSMutableData(contentsOfFile: filename, options: [])
889+
XCTAssertNotNil(contents2)
890+
testText(contents2)
891+
892+
let contents3 = NSMutableData(contentsOf: url)
893+
XCTAssertNotNil(contents3)
894+
testText(contents3)
895+
896+
let contents4 = try? NSMutableData(contentsOf: url, options: [])
897+
XCTAssertNotNil(contents4)
898+
testText(contents4)
899+
900+
// Test failure to read
901+
let badFilename = "does not exist"
902+
let badUrl = URL(fileURLWithPath: badFilename)
903+
904+
XCTAssertNil(NSMutableData(contentsOfFile: badFilename))
905+
XCTAssertNil(try? NSMutableData(contentsOfFile: badFilename, options: []))
906+
XCTAssertNil(NSMutableData(contentsOf: badUrl))
907+
XCTAssertNil(try? NSMutableData(contentsOf: badUrl, options: []))
908+
}
909+
910+
func test_initNSMutableDataBase64() {
911+
let srcData = Data([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
912+
let base64Data = srcData.base64EncodedData()
913+
let base64String = srcData.base64EncodedString()
914+
XCTAssertEqual(base64String, "AQIDBAUGBwgJAA==")
915+
916+
let mData1 = NSMutableData(base64Encoded: base64Data)
917+
XCTAssertNotNil(mData1)
918+
XCTAssertEqual(mData1!, NSData(data: srcData))
919+
920+
let mData2 = NSMutableData(base64Encoded: base64String)
921+
XCTAssertNotNil(mData2)
922+
XCTAssertEqual(mData2!, NSData(data: srcData))
923+
924+
// Test bad input
925+
XCTAssertNil(NSMutableData(base64Encoded: Data([1,2,3]), options: []))
926+
XCTAssertNil(NSMutableData(base64Encoded: "x", options: []))
927+
}
928+
820929
func test_replaceBytes() {
821930
var data = Data(bytes: [0, 0, 0, 0, 0])
822931
let newData = Data(bytes: [1, 2, 3, 4, 5])

0 commit comments

Comments
 (0)