Hello,
I want to test that a blob loaded from SQLite has not been copied:
// Test the Row.dataNoCopy(atIndex:) method.
// It should not copy the blob buffer loaded by SQLite.
let rows = try Row.fetchCursor(db, "SELECT * FROM datas")
while let row = try rows.next() {
// The pointer to the blob loaded by SQLite (using C API)
let sqlitePointer: UnsafeRawPointer? = sqlite3_column_blob(row.sqliteStatement, 0)
// Load that blob into a Data value with the tested method.
// This internally calls Data(bytesNoCopy:count:deallocator:)
// with the same blob buffer as above.
let data: Data = row.dataNoCopy(atIndex: 0)!
data.withUnsafeBytes { buffer in
// Test that data has not been copied
XCTAssertEqual(buffer.baseAddress, sqlitePointer)
}
}
This test fails, with Swift 5, with the following error:
XCTAssertEqual failed: ("Optional(0x00007ffeefbfc760)")
is not equal to ("Optional(0x0000000103022200)")
With the Swift 4.2 compiler (Xcode 10.1), the test passes.
Do I write my test in a bad way, or is it a regression in the Foundation library shipped with the latest Swift 5 snapshot (06/02/2019)?
Actually, I really can't manage to see Data(bytesNoCopy:count:deallocator:)
in action:
let data1 = Data([0])
data1.withUnsafeBytes { buffer1 in
let data2 = Data(
bytesNoCopy: UnsafeMutableRawPointer(mutating: buffer1.baseAddress!),
count: buffer1.count,
deallocator: .none)
data2.withUnsafeBytes { buffer2 in
// Unexpectedly (?) fails
assert(buffer1.baseAddress == buffer2.baseAddress)
}
}
let nsData1 = NSData(data: data1)
let nsData2 = NSData(
bytesNoCopy: UnsafeMutableRawPointer(mutating: nsData1.bytes),
length: nsData1.count,
freeWhenDone: false)
// Expectedly passes
assert(nsData1.bytes == nsData2.bytes)