// RUN: %empty-directory(%t) // RUN: %target-build-swift -swift-version 4 %s %import-libdispatch -o %t/a.out-4 && %target-codesign %t/a.out-4 && %target-run %t/a.out-4 // RUN: %target-build-swift -swift-version 4.2 %s %import-libdispatch -o %t/a.out-4.2 && %target-codesign %t/a.out-4.2 && %target-run %t/a.out-4.2 // REQUIRES: executable_test // REQUIRES: libdispatch import Dispatch import StdlibUnittest defer { runAllTests() } var DispatchAPI = TestSuite("DispatchAPI") DispatchAPI.test("dispatch_data_t enumeration") { // Ensure we can iterate the empty iterator for _ in DispatchData.empty { _ = 1 } } DispatchAPI.test("dispatch_data_t deallocator") { let q = DispatchQueue(label: "dealloc queue") var t = 0 do { let size = 1024 let p = UnsafeMutablePointer.allocate(capacity: size) let _ = DispatchData(bytesNoCopy: UnsafeBufferPointer(start: p, count: size), deallocator: .custom(q, { t = 1 p.deallocate(); })) } q.sync { expectEqual(1, t) } } DispatchAPI.test("DispatchData.copyBytes") { let source1: [UInt8] = [0, 1, 2, 3] var dest: [UInt8] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] var dispatchData = source1.withUnsafeBytes { return DispatchData(bytes: $0) } dest.withContiguousMutableStorageIfAvailable { destPtr in // Copy from offset 0 var count = dispatchData.copyBytes(to: destPtr, from: 0..<2) expectEqual(count, 2) expectEqual(destPtr[0], 0) expectEqual(destPtr[1], 1) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 2 count = dispatchData.copyBytes(to: destPtr, from: 2..<4) expectEqual(count, 2) expectEqual(destPtr[0], 2) expectEqual(destPtr[1], 3) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Add two more regions let source2: [UInt8] = [0x10, 0x11, 0x12, 0x13] source2.withUnsafeBytes { dispatchData.append(DispatchData(bytes: $0)) } let source3: [UInt8] = [0x14, 0x15, 0x16] source3.withUnsafeBytes { dispatchData.append(DispatchData(bytes: $0)) } // Copy from offset 0. Copies across the first two regions count = dispatchData.copyBytes(to: destPtr, from: 0..<6) expectEqual(count, 6) expectEqual(destPtr[0], 0) expectEqual(destPtr[1], 1) expectEqual(destPtr[2], 2) expectEqual(destPtr[3], 3) expectEqual(destPtr[4], 0x10) expectEqual(destPtr[5], 0x11) // Copy from offset 2. Copies across the first two regions count = dispatchData.copyBytes(to: destPtr, from: 2..<8) expectEqual(count, 6) expectEqual(destPtr[0], 2) expectEqual(destPtr[1], 3) expectEqual(destPtr[2], 0x10) expectEqual(destPtr[3], 0x11) expectEqual(destPtr[4], 0x12) expectEqual(destPtr[5], 0x13) // Copy from offset 3. Copies across all three regions count = dispatchData.copyBytes(to: destPtr, from: 3..<9) expectEqual(count, 6) expectEqual(destPtr[0], 3) expectEqual(destPtr[1], 0x10) expectEqual(destPtr[2], 0x11) expectEqual(destPtr[3], 0x12) expectEqual(destPtr[4], 0x13) expectEqual(destPtr[5], 0x14) // Copy from offset 5. Skips the first region and the first byte of the second count = dispatchData.copyBytes(to: destPtr, from: 5..<11) expectEqual(count, 6) expectEqual(destPtr[0], 0x11) expectEqual(destPtr[1], 0x12) expectEqual(destPtr[2], 0x13) expectEqual(destPtr[3], 0x14) expectEqual(destPtr[4], 0x15) expectEqual(destPtr[5], 0x16) // Copy from offset 8. Skips the first two regions destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF count = dispatchData.copyBytes(to: destPtr, from: 8..<11) expectEqual(count, 3) expectEqual(destPtr[0], 0x14) expectEqual(destPtr[1], 0x15) expectEqual(destPtr[2], 0x16) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 9. Skips the first two regions and the first byte of the third destPtr[2] = 0xFF destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF count = dispatchData.copyBytes(to: destPtr, from: 9..<11) expectEqual(count, 2) expectEqual(destPtr[0], 0x15) expectEqual(destPtr[1], 0x16) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 9, but only 1 byte. Ends before the end of the data destPtr[1] = 0xFF destPtr[2] = 0xFF destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF count = dispatchData.copyBytes(to: destPtr, from: 9..<10) expectEqual(count, 1) expectEqual(destPtr[0], 0x15) expectEqual(destPtr[1], 0xFF) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 2, but only 1 byte. This copy is bounded within the // first region. destPtr[1] = 0xFF destPtr[2] = 0xFF destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF count = dispatchData.copyBytes(to: destPtr, from: 2..<3) expectEqual(count, 1) expectEqual(destPtr[0], 2) expectEqual(destPtr[1], 0xFF) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) } } DispatchAPI.test("DispatchData.copyBytesUnsafeRawBufferPointer") { let source1: [UInt8] = [0, 1, 2, 3] var dest: [UInt8] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] var dispatchData = source1.withUnsafeBytes { return DispatchData(bytes: $0) } dest.withContiguousMutableStorageIfAvailable { destPtr in // Copy from offset 0 dispatchData.copyBytes(to: destPtr, from: 0..<2) expectEqual(destPtr[0], 0) expectEqual(destPtr[1], 1) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 2 dispatchData.copyBytes(to: destPtr, from: 2..<4) expectEqual(destPtr[0], 2) expectEqual(destPtr[1], 3) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Add two more regions let source2: [UInt8] = [0x10, 0x11, 0x12, 0x13] source2.withUnsafeBytes { dispatchData.append(DispatchData(bytes: $0)) } let source3: [UInt8] = [0x14, 0x15, 0x16] source3.withUnsafeBytes { dispatchData.append(DispatchData(bytes: $0)) } // Copy from offset 0. Copies across the first two regions dispatchData.copyBytes(to: destPtr, from: 0..<6) expectEqual(destPtr[0], 0) expectEqual(destPtr[1], 1) expectEqual(destPtr[2], 2) expectEqual(destPtr[3], 3) expectEqual(destPtr[4], 0x10) expectEqual(destPtr[5], 0x11) // Copy from offset 2. Copies across the first two regions dispatchData.copyBytes(to: destPtr, from: 2..<8) expectEqual(destPtr[0], 2) expectEqual(destPtr[1], 3) expectEqual(destPtr[2], 0x10) expectEqual(destPtr[3], 0x11) expectEqual(destPtr[4], 0x12) expectEqual(destPtr[5], 0x13) // Copy from offset 3. Copies across all three regions dispatchData.copyBytes(to: destPtr, from: 3..<9) expectEqual(destPtr[0], 3) expectEqual(destPtr[1], 0x10) expectEqual(destPtr[2], 0x11) expectEqual(destPtr[3], 0x12) expectEqual(destPtr[4], 0x13) expectEqual(destPtr[5], 0x14) // Copy from offset 5. Skips the first region and the first byte of the second dispatchData.copyBytes(to: destPtr, from: 5..<11) expectEqual(destPtr[0], 0x11) expectEqual(destPtr[1], 0x12) expectEqual(destPtr[2], 0x13) expectEqual(destPtr[3], 0x14) expectEqual(destPtr[4], 0x15) expectEqual(destPtr[5], 0x16) // Copy from offset 8. Skips the first two regions destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF dispatchData.copyBytes(to: destPtr, from: 8..<11) expectEqual(destPtr[0], 0x14) expectEqual(destPtr[1], 0x15) expectEqual(destPtr[2], 0x16) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 9. Skips the first two regions and the first byte of the third destPtr[2] = 0xFF destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF dispatchData.copyBytes(to: destPtr, from: 9..<11) expectEqual(destPtr[0], 0x15) expectEqual(destPtr[1], 0x16) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 9, but only 1 byte. Ends before the end of the data destPtr[1] = 0xFF destPtr[2] = 0xFF destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF dispatchData.copyBytes(to: destPtr, from: 9..<10) expectEqual(destPtr[0], 0x15) expectEqual(destPtr[1], 0xFF) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) // Copy from offset 2, but only 1 byte. This copy is bounded within the // first region. destPtr[1] = 0xFF destPtr[2] = 0xFF destPtr[3] = 0xFF destPtr[4] = 0xFF destPtr[5] = 0xFF dispatchData.copyBytes(to: destPtr, from: 2..<3) expectEqual(destPtr[0], 2) expectEqual(destPtr[1], 0xFF) expectEqual(destPtr[2], 0xFF) expectEqual(destPtr[3], 0xFF) expectEqual(destPtr[4], 0xFF) expectEqual(destPtr[5], 0xFF) } } DispatchAPI.test("DispatchData.buffers") { let bytes = [UInt8(0), UInt8(1), UInt8(2), UInt8(2)] var ptr = UnsafeBufferPointer(start: bytes, count: bytes.count) var data = DispatchData(bytes: ptr) expectEqual(bytes.count, data.count) for i in 0..(start: nil, count: 0) data = DispatchData(bytes: ptr) expectEqual(data.count, 0) data = DispatchData(bytesNoCopy: ptr, deallocator: .custom(nil, {})) expectEqual(data.count, 0) } DispatchAPI.test("DispatchData.bufferUnsafeRawBufferPointer") { let bytes = [UInt8(0), UInt8(1), UInt8(2), UInt8(2)] var ptr = UnsafeRawBufferPointer(start: bytes, count: bytes.count) var data = DispatchData(bytes: ptr) expectEqual(bytes.count, data.count) for i in 0..=4.2) data.enumerateBytes({ ptr, offset, stop in for i in 0..