Skip to content

Commit 2d7847d

Browse files
authored
Merge pull request #3648 from mwwa/libdispatch-data-fixes
[libdispatch] libdispatch data fixes
2 parents b8603b8 + 56a5797 commit 2d7847d

File tree

5 files changed

+40
-11
lines changed

5 files changed

+40
-11
lines changed

apinotes/Dispatch.apinotes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ Functions:
198198
AvailabilityMsg: 'Use DispatchWorkItem.isCancelled'
199199
# dispatch_data
200200
- Name: dispatch_data_create
201-
SwiftPrivate: true
201+
Availability: nonswift
202202
- Name: dispatch_data_get_size
203203
SwiftPrivate: true
204204
- Name: dispatch_data_apply

stdlib/public/SDK/Dispatch/Data.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import SwiftShims
14+
1315
public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
1416
public typealias Iterator = DispatchDataIterator
1517
public typealias Index = Int
@@ -43,8 +45,8 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
4345
/// - parameter bytes: A pointer to the memory. It will be copied.
4446
/// - parameter count: The number of bytes to copy.
4547
public init(bytes buffer: UnsafeBufferPointer<UInt8>) {
46-
__wrapped = __dispatch_data_create(
47-
buffer.baseAddress!, buffer.count, nil, _dispatch_data_destructor_default())
48+
__wrapped = _swift_dispatch_data_create(
49+
buffer.baseAddress!, buffer.count, nil, _dispatch_data_destructor_default()) as! __DispatchData
4850
}
4951

5052
/// Initialize a `Data` without copying the bytes.
@@ -55,8 +57,8 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
5557
public init(bytesNoCopy bytes: UnsafeBufferPointer<UInt8>, deallocator: Deallocator = .free) {
5658
let (q, b) = deallocator._deallocator
5759

58-
__wrapped = __dispatch_data_create(
59-
bytes.baseAddress!, bytes.count, q, b)
60+
__wrapped = _swift_dispatch_data_create(
61+
bytes.baseAddress!, bytes.count, q, b) as! __DispatchData
6062
}
6163

6264
internal init(data: __DispatchData) {
@@ -93,15 +95,15 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
9395
/// - parameter bytes: A pointer to the bytes to copy in to the data.
9496
/// - parameter count: The number of bytes to copy.
9597
public mutating func append(_ bytes: UnsafePointer<UInt8>, count: Int) {
96-
let data = __dispatch_data_create(bytes, count, nil, _dispatch_data_destructor_default())
98+
let data = _swift_dispatch_data_create(bytes, count, nil, _dispatch_data_destructor_default()) as! __DispatchData
9799
self.append(DispatchData(data: data))
98100
}
99101

100102
/// Append data to the data.
101103
///
102104
/// - parameter data: The data to append to this data.
103105
public mutating func append(_ other: DispatchData) {
104-
let data = __dispatch_data_create_concat(__wrapped, other as __DispatchData)
106+
let data = __dispatch_data_create_concat(__wrapped, other.__wrapped)
105107
__wrapped = data
106108
}
107109

@@ -237,14 +239,15 @@ public struct DispatchDataIterator : IteratorProtocol, Sequence {
237239
self._count = 0
238240
self._data = __dispatch_data_create_map(
239241
_data as __DispatchData, &ptr, &self._count)
240-
self._ptr = UnsafePointer(ptr!)
242+
self._ptr = UnsafePointer(ptr)
241243
self._position = _data.startIndex
244+
245+
// The only time we expect a 'nil' pointer is when the data is empty.
246+
assert(self._ptr != nil || self._count == self._position)
242247
}
243248

244249
/// Advance to the next element and return it, or `nil` if no next
245250
/// element exists.
246-
///
247-
/// - Precondition: No preceding call to `self.next()` has returned `nil`.
248251
public mutating func next() -> DispatchData._Element? {
249252
if _position == _count { return nil }
250253
let element = _ptr[_position]
@@ -253,7 +256,7 @@ public struct DispatchDataIterator : IteratorProtocol, Sequence {
253256
}
254257

255258
internal let _data: __DispatchData
256-
internal var _ptr: UnsafePointer<UInt8>
259+
internal var _ptr: UnsafePointer<UInt8>!
257260
internal var _count: Int
258261
internal var _position: DispatchData.Index
259262
}

stdlib/public/SwiftShims/DispatchShims.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ void _swift_dispatch_apply_current(
9595
unsigned int iterations,
9696
void SWIFT_DISPATCH_NOESCAPE (^block)(long));
9797

98+
SWIFT_RUNTIME_STDLIB_INTERFACE
99+
__swift_shims_dispatch_data_t
100+
_swift_dispatch_data_create(
101+
const void *buffer,
102+
__swift_size_t size,
103+
__swift_shims_dispatch_queue_t queue,
104+
__swift_shims_dispatch_block_t destructor);
105+
98106
#ifdef __cplusplus
99107
}} // extern "C", namespace swift
100108
#endif

stdlib/public/stubs/DispatchShims.mm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,14 @@ void SWIFT_DISPATCH_NOESCAPE (^block)(long))
120120
block((long)i);
121121
});
122122
}
123+
124+
__swift_shims_dispatch_data_t
125+
swift::_swift_dispatch_data_create(
126+
const void *buffer,
127+
__swift_size_t size,
128+
__swift_shims_dispatch_queue_t queue,
129+
__swift_shims_dispatch_block_t destructor)
130+
{
131+
return dispatch_data_create(buffer, size, cast(queue), cast(destructor));
132+
}
133+

test/1_stdlib/Dispatch.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,10 @@ if #available(OSX 10.10, iOS 8.0, *) {
6161
block.cancel()
6262
}
6363
}
64+
65+
DispatchAPI.test("dispatch_data_t enumeration") {
66+
// Ensure we can iterate the empty iterator
67+
for x in DispatchData.empty {
68+
_ = 1
69+
}
70+
}

0 commit comments

Comments
 (0)