From 0c80c9fe437b7ba800d10b595081aee6ab7409fe Mon Sep 17 00:00:00 2001 From: Kim Topley Date: Wed, 8 Mar 2017 16:50:53 -0800 Subject: [PATCH 1/2] Add support for UnsafeRawBufferPointer to DispatchData (Radar 30699743) --- src/swift/Data.swift | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/swift/Data.swift b/src/swift/Data.swift index e0b7263c9..afd8b4d0a 100644 --- a/src/swift/Data.swift +++ b/src/swift/Data.swift @@ -49,6 +49,7 @@ public struct DispatchData : RandomAccessCollection { /// Initialize a `Data` with copied memory content. /// /// - parameter bytes: A pointer to the memory. It will be copied. + @available(swift, deprecated: 4, message: "Use init(bytes: UnsafeRawBufferPointer) instead") public init(bytes buffer: UnsafeBufferPointer) { let d = buffer.baseAddress == nil ? _swift_dispatch_data_empty() : dispatch_data_create(buffer.baseAddress!, buffer.count, nil, @@ -56,10 +57,22 @@ public struct DispatchData : RandomAccessCollection { self.init(data: d) } + /// Initialize a `Data` with copied memory content. + /// + /// - parameter bytes: A pointer to the memory. It will be copied. + /// - parameter count: The number of bytes to copy. + public init(bytes buffer: UnsafeRawBufferPointer) { + let d = buffer.baseAddress == nil ? _swift_dispatch_data_empty() + : dispatch_data_create(buffer.baseAddress!, buffer.count, nil, + _dispatch_data_destructor_default()) + self.init(data: d) + } + /// Initialize a `Data` without copying the bytes. /// /// - parameter bytes: A buffer pointer containing the data. /// - parameter deallocator: Specifies the mechanism to free the indicated buffer. + @available(swift, deprecated: 4, message: "Use init(bytes: UnsafeRawBufferPointer, deallocater: Deallocator) instead") public init(bytesNoCopy bytes: UnsafeBufferPointer, deallocator: Deallocator = .free) { let (q, b) = deallocator._deallocator let d = bytes.baseAddress == nil ? _swift_dispatch_data_empty() @@ -67,6 +80,18 @@ public struct DispatchData : RandomAccessCollection { self.init(data: d) } + /// Initialize a `Data` without copying the bytes. + /// + /// - parameter bytes: A pointer to the bytes. + /// - parameter count: The size of the bytes. + /// - parameter deallocator: Specifies the mechanism to free the indicated buffer. + public init(bytesNoCopy bytes: UnsafeRawBufferPointer, deallocator: Deallocator = .free) { + let (q, b) = deallocator._deallocator + let d = bytes.baseAddress == nil ? _swift_dispatch_data_empty() + : dispatch_data_create(bytes.baseAddress!, bytes.count, q?.__wrapped, b) + self.init(data: d) + } + internal init(data: dispatch_data_t) { __wrapped = __DispatchData(data: data, owned: true) } @@ -113,11 +138,23 @@ public struct DispatchData : RandomAccessCollection { /// /// - parameter bytes: A pointer to the bytes to copy in to the data. /// - parameter count: The number of bytes to copy. + @available(swift, deprecated: 4, message: "Use append(_: UnsafeRawBufferPointer) instead") public mutating func append(_ bytes: UnsafePointer, count: Int) { let data = dispatch_data_create(bytes, count, nil, _dispatch_data_destructor_default()) self.append(DispatchData(data: data)) } + /// Append bytes to the data. + /// + /// - 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: UnsafeRawBufferPointer) { + // Nil base address does nothing. + guard bytes.baseAddress != nil else { return } + let data = dispatch_data_create(bytes.baseAddress!, bytes.count, nil, _dispatch_data_destructor_default()) + self.append(DispatchData(data: data)) + } + /// Append data to the data. /// /// - parameter data: The data to append to this data. @@ -156,19 +193,41 @@ public struct DispatchData : RandomAccessCollection { /// - parameter pointer: A pointer to the buffer you wish to copy the bytes into. /// - parameter count: The number of bytes to copy. /// - warning: This method does not verify that the contents at pointer have enough space to hold `count` bytes. + @available(swift, deprecated: 4, message: "Use copyBytes(to: UnsafeMutableRawBufferPointer, count: Int) instead") public func copyBytes(to pointer: UnsafeMutablePointer, count: Int) { _copyBytesHelper(to: pointer, from: 0..) instead") public func copyBytes(to pointer: UnsafeMutablePointer, from range: CountableRange) { _copyBytesHelper(to: pointer, from: range) } + /// Copy a subset of the contents of the data to a pointer. + /// + /// - parameter pointer: A pointer to the buffer you wish to copy the bytes into. + /// - parameter range: The range in the `Data` to copy. + /// - warning: This method does not verify that the contents at pointer have enough space to hold the required number of bytes. + public func copyBytes(to pointer: UnsafeMutableRawBufferPointer, from range: CountableRange) { + guard pointer.baseAddress != nil else { return } + _copyBytesHelper(to: pointer.baseAddress!, from: range) + } + /// Copy the contents of the data into a buffer. /// /// This function copies the bytes in `range` from the data into the buffer. If the count of the `range` is greater than `MemoryLayout.stride * buffer.count` then the first N bytes will be copied into the buffer. From 5db517cf1adb0f61467487d76788bc3969a4a94e Mon Sep 17 00:00:00 2001 From: Kim Topley Date: Fri, 10 Mar 2017 10:57:46 -0800 Subject: [PATCH 2/2] Review comments. --- src/swift/Data.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/swift/Data.swift b/src/swift/Data.swift index afd8b4d0a..1e7350463 100644 --- a/src/swift/Data.swift +++ b/src/swift/Data.swift @@ -72,7 +72,7 @@ public struct DispatchData : RandomAccessCollection { /// /// - parameter bytes: A buffer pointer containing the data. /// - parameter deallocator: Specifies the mechanism to free the indicated buffer. - @available(swift, deprecated: 4, message: "Use init(bytes: UnsafeRawBufferPointer, deallocater: Deallocator) instead") + @available(swift, deprecated: 4, message: "Use init(bytesNoCopy: UnsafeRawBufferPointer, deallocater: Deallocator) instead") public init(bytesNoCopy bytes: UnsafeBufferPointer, deallocator: Deallocator = .free) { let (q, b) = deallocator._deallocator let d = bytes.baseAddress == nil ? _swift_dispatch_data_empty() @@ -200,10 +200,11 @@ public struct DispatchData : RandomAccessCollection { /// Copy the contents of the data to a pointer. /// - /// - parameter pointer: A pointer to the buffer you wish to copy the bytes into. + /// - parameter pointer: A pointer to the buffer you wish to copy the bytes into. The buffer must be large + /// enough to hold `count` bytes. /// - parameter count: The number of bytes to copy. - /// - warning: This method does not verify that the contents at pointer have enough space to hold `count` bytes. public func copyBytes(to pointer: UnsafeMutableRawBufferPointer, count: Int) { + assert(count <= pointer.count, "Buffer too small to copy \(count) bytes") guard pointer.baseAddress != nil else { return } _copyBytesHelper(to: pointer.baseAddress!, from: 0..) { + assert(range.count <= pointer.count, "Buffer too small to copy \(range.count) bytes") guard pointer.baseAddress != nil else { return } _copyBytesHelper(to: pointer.baseAddress!, from: range) }