Skip to content

[libdispatch] libdispatch data fixes #3648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apinotes/Dispatch.apinotes
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ Functions:
AvailabilityMsg: 'Use DispatchWorkItem.isCancelled'
# dispatch_data
- Name: dispatch_data_create
SwiftPrivate: true
Availability: nonswift
- Name: dispatch_data_get_size
SwiftPrivate: true
- Name: dispatch_data_apply
Expand Down
23 changes: 13 additions & 10 deletions stdlib/public/SDK/Dispatch/Data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//

import SwiftShims

public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
public typealias Iterator = DispatchDataIterator
public typealias Index = Int
Expand Down Expand Up @@ -43,8 +45,8 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
/// - parameter bytes: A pointer to the memory. It will be copied.
/// - parameter count: The number of bytes to copy.
public init(bytes buffer: UnsafeBufferPointer<UInt8>) {
__wrapped = __dispatch_data_create(
buffer.baseAddress!, buffer.count, nil, _dispatch_data_destructor_default())
__wrapped = _swift_dispatch_data_create(
buffer.baseAddress!, buffer.count, nil, _dispatch_data_destructor_default()) as! __DispatchData
}

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

__wrapped = __dispatch_data_create(
bytes.baseAddress!, bytes.count, q, b)
__wrapped = _swift_dispatch_data_create(
bytes.baseAddress!, bytes.count, q, b) as! __DispatchData
}

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

/// Append data to the data.
///
/// - parameter data: The data to append to this data.
public mutating func append(_ other: DispatchData) {
let data = __dispatch_data_create_concat(__wrapped, other as __DispatchData)
let data = __dispatch_data_create_concat(__wrapped, other.__wrapped)
__wrapped = data
}

Expand Down Expand Up @@ -237,14 +239,15 @@ public struct DispatchDataIterator : IteratorProtocol, Sequence {
self._count = 0
self._data = __dispatch_data_create_map(
_data as __DispatchData, &ptr, &self._count)
self._ptr = UnsafePointer(ptr!)
self._ptr = UnsafePointer(ptr)
self._position = _data.startIndex

// The only time we expect a 'nil' pointer is when the data is empty.
assert(self._ptr != nil || self._count == self._position)
}

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

internal let _data: __DispatchData
internal var _ptr: UnsafePointer<UInt8>
internal var _ptr: UnsafePointer<UInt8>!
internal var _count: Int
internal var _position: DispatchData.Index
}
Expand Down
8 changes: 8 additions & 0 deletions stdlib/public/SwiftShims/DispatchShims.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ void _swift_dispatch_apply_current(
unsigned int iterations,
void SWIFT_DISPATCH_NOESCAPE (^block)(long));

SWIFT_RUNTIME_STDLIB_INTERFACE
__swift_shims_dispatch_data_t
_swift_dispatch_data_create(
const void *buffer,
__swift_size_t size,
__swift_shims_dispatch_queue_t queue,
__swift_shims_dispatch_block_t destructor);

#ifdef __cplusplus
}} // extern "C", namespace swift
#endif
Expand Down
11 changes: 11 additions & 0 deletions stdlib/public/stubs/DispatchShims.mm
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,14 @@ void SWIFT_DISPATCH_NOESCAPE (^block)(long))
block((long)i);
});
}

__swift_shims_dispatch_data_t
swift::_swift_dispatch_data_create(
const void *buffer,
__swift_size_t size,
__swift_shims_dispatch_queue_t queue,
__swift_shims_dispatch_block_t destructor)
{
return dispatch_data_create(buffer, size, cast(queue), cast(destructor));
}

7 changes: 7 additions & 0 deletions test/1_stdlib/Dispatch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,10 @@ if #available(OSX 10.10, iOS 8.0, *) {
block.cancel()
}
}

DispatchAPI.test("dispatch_data_t enumeration") {
// Ensure we can iterate the empty iterator
for x in DispatchData.empty {
_ = 1
}
}