Skip to content

Commit a42026b

Browse files
committed
Initial draft of DataProtocol ContiguousCollection and new inline Data
1 parent 44e52d0 commit a42026b

File tree

8 files changed

+2379
-995
lines changed

8 files changed

+2379
-995
lines changed

Darwin/Foundation-swiftoverlay-Tests/TestData.swift

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -805,14 +805,6 @@ class TestData : TestDataSuper {
805805
object.verifier.reset()
806806
expectTrue(data.count == object.length)
807807
expectFalse(object.verifier.wasCopied, "Expected an invocation to copy")
808-
809-
object.verifier.reset()
810-
data.append("test", count: 4)
811-
expectTrue(object.verifier.wasMutableCopied, "Expected an invocation to mutableCopy")
812-
813-
let d = data as NSData
814-
let preservedObjectness = d is ImmutableDataVerifier
815-
expectTrue(preservedObjectness, "Expected ImmutableDataVerifier but got \(object_getClass(d))")
816808
}
817809

818810
func test_basicMutableDataMutation() {
@@ -826,20 +818,6 @@ class TestData : TestDataSuper {
826818
object.verifier.reset()
827819
expectTrue(data.count == object.length)
828820
expectFalse(object.verifier.wasCopied, "Expected an invocation to copy")
829-
830-
object.verifier.reset()
831-
data.append("test", count: 4)
832-
expectTrue(object.verifier.wasMutableCopied, "Expected an invocation to mutableCopy")
833-
object.verifier.dump()
834-
835-
let d = data as NSData
836-
let preservedObjectness = d is ImmutableDataVerifier
837-
expectTrue(preservedObjectness, "Expected ImmutableDataVerifier but got \(object_getClass(d))")
838-
}
839-
840-
func test_roundTrip() {
841-
let data = returnsData()
842-
expectTrue(identityOfData(data))
843821
}
844822

845823
func test_passing() {
@@ -966,12 +944,13 @@ class TestData : TestDataSuper {
966944
}
967945

968946
func test_noCopyBehavior() {
969-
let ptr = UnsafeMutableRawPointer(bitPattern: 0x1)!
947+
let ptr = UnsafeMutableRawPointer.allocate(byteCount: 17, alignment: 1)
970948

971949
var deallocated = false
972950
autoreleasepool {
973-
let data = Data(bytesNoCopy: ptr, count: 1, deallocator: .custom({ (bytes, length) in
951+
let data = Data(bytesNoCopy: ptr, count: 17, deallocator: .custom({ (bytes, length) in
974952
deallocated = true
953+
ptr.deallocate()
975954
}))
976955
expectFalse(deallocated)
977956
let equal = data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Bool in
@@ -980,7 +959,6 @@ class TestData : TestDataSuper {
980959

981960
expectTrue(equal)
982961
}
983-
984962
expectTrue(deallocated)
985963
}
986964

@@ -1013,10 +991,6 @@ class TestData : TestDataSuper {
1013991
for i in 0..<d.count {
1014992
for j in i..<d.count {
1015993
let slice = d[i..<j]
1016-
if i == 1 && j == 2 {
1017-
print("here")
1018-
1019-
}
1020994
expectEqual(slice.count, j - i, "where index range is \(i)..<\(j)")
1021995
expectEqual(slice.map { $0 }, a[i..<j].map { $0 }, "where index range is \(i)..<\(j)")
1022996
expectEqual(slice.startIndex, i, "where index range is \(i)..<\(j)")
@@ -3641,28 +3615,6 @@ class TestData : TestDataSuper {
36413615
expectEqual(data, Data(bytes: [4, 5, 6, 7, 0, 0]))
36423616
}
36433617

3644-
func test_sliceEnumeration() {
3645-
var base = DispatchData.empty
3646-
let bytes: [UInt8] = [0, 1, 2, 3, 4]
3647-
base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
3648-
base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
3649-
base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
3650-
let data = ((base as AnyObject) as! Data)[3..<11]
3651-
var regionRanges: [Range<Int>] = []
3652-
var regionData: [Data] = []
3653-
data.enumerateBytes { (buffer, index, _) in
3654-
regionData.append(Data(bytes: buffer.baseAddress!, count: buffer.count))
3655-
regionRanges.append(index..<index + buffer.count)
3656-
}
3657-
expectEqual(regionRanges.count, 3)
3658-
expectEqual(3..<5, regionRanges[0])
3659-
expectEqual(5..<10, regionRanges[1])
3660-
expectEqual(10..<11, regionRanges[2])
3661-
expectEqual(Data(bytes: [3, 4]), regionData[0]) //fails
3662-
expectEqual(Data(bytes: [0, 1, 2, 3, 4]), regionData[1]) //passes
3663-
expectEqual(Data(bytes: [0]), regionData[2]) //fails
3664-
}
3665-
36663618
func test_hashEmptyData() {
36673619
let d1 = Data()
36683620
let h1 = d1.hashValue
@@ -3783,7 +3735,6 @@ DataTests.test("test_writeFailure") { TestData().test_writeFailure() }
37833735
DataTests.test("test_genericBuffers") { TestData().test_genericBuffers() }
37843736
DataTests.test("test_basicDataMutation") { TestData().test_basicDataMutation() }
37853737
DataTests.test("test_basicMutableDataMutation") { TestData().test_basicMutableDataMutation() }
3786-
DataTests.test("test_roundTrip") { TestData().test_roundTrip() }
37873738
DataTests.test("test_passing") { TestData().test_passing() }
37883739
DataTests.test("test_bufferSizeCalculation") { TestData().test_bufferSizeCalculation() }
37893740
DataTests.test("test_classForCoder") { TestData().test_classForCoder() }
@@ -4056,7 +4007,6 @@ DataTests.test("test_validateMutation_slice_cow_customMutableBacking_replaceSubr
40564007
DataTests.test("test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes") { TestData().test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes() }
40574008
DataTests.test("test_sliceHash") { TestData().test_sliceHash() }
40584009
DataTests.test("test_slice_resize_growth") { TestData().test_slice_resize_growth() }
4059-
DataTests.test("test_sliceEnumeration") { TestData().test_sliceEnumeration() }
40604010
DataTests.test("test_hashEmptyData") { TestData().test_hashEmptyData() }
40614011
DataTests.test("test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound() }
40624012
DataTests.test("test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
//===--- DataProtocol -----------------------------------------------------===//
14+
15+
extension Array: DataProtocol where Element == UInt8 {
16+
public var regions: CollectionOfOne<Array<UInt8>> {
17+
return CollectionOfOne(self)
18+
}
19+
}
20+
21+
extension ArraySlice: DataProtocol where Element == UInt8 {
22+
public var regions: CollectionOfOne<ArraySlice<UInt8>> {
23+
return CollectionOfOne(self)
24+
}
25+
}
26+
27+
extension ContiguousArray: DataProtocol where Element == UInt8 {
28+
public var regions: CollectionOfOne<ContiguousArray<UInt8>> {
29+
return CollectionOfOne(self)
30+
}
31+
}
32+
33+
// FIXME: This currently crashes compilation in the Late Inliner.
34+
// extension CollectionOfOne : DataProtocol where Element == UInt8 {
35+
// public typealias Regions = CollectionOfOne<Data>
36+
//
37+
// public var regions: CollectionOfOne<Data> {
38+
// return CollectionOfOne<Data>(Data(self))
39+
// }
40+
// }
41+
42+
extension EmptyCollection : DataProtocol where Element == UInt8 {
43+
public var regions: EmptyCollection<Data> {
44+
return EmptyCollection<Data>()
45+
}
46+
}
47+
48+
extension Repeated: DataProtocol where Element == UInt8 {
49+
public typealias Regions = Repeated<Data>
50+
51+
public var regions: Repeated<Data> {
52+
guard self.count > 0 else { return repeatElement(Data(), count: 0) }
53+
return repeatElement(Data(CollectionOfOne(self.first!)), count: self.count)
54+
}
55+
}
56+
57+
//===--- MutableDataProtocol ----------------------------------------------===//
58+
59+
extension Array: MutableDataProtocol where Element == UInt8 { }
60+
61+
extension ContiguousArray: MutableDataProtocol where Element == UInt8 { }
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
//===--- ContiguousBytes --------------------------------------------------===//
14+
15+
/// Indicates that the conforming type is a contiguous collection of raw bytes
16+
/// whose underlying storage is directly accessible by withUnsafeBytes.
17+
public protocol ContiguousBytes {
18+
/// Calls the given closure with the contents of underlying storage.
19+
///
20+
/// - note: Calling `withUnsafeBytes` multiple times does not guarantee that
21+
/// the same buffer pointer will be passed in every time.
22+
/// - warning: The buffer argument to the body should not be stored or used
23+
/// outside of the lifetime of the call to the closure.
24+
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
25+
}
26+
27+
//===--- Collection Conformances ------------------------------------------===//
28+
29+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
30+
extension Array : ContiguousBytes where Element == UInt8 { }
31+
32+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
33+
extension ArraySlice : ContiguousBytes where Element == UInt8 { }
34+
35+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
36+
extension ContiguousArray : ContiguousBytes where Element == UInt8 { }
37+
38+
//===--- Pointer Conformances ---------------------------------------------===//
39+
40+
extension UnsafeRawBufferPointer : ContiguousBytes {
41+
@inlinable
42+
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
43+
return try body(self)
44+
}
45+
}
46+
47+
extension UnsafeMutableRawBufferPointer : ContiguousBytes {
48+
@inlinable
49+
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
50+
return try body(UnsafeRawBufferPointer(self))
51+
}
52+
}
53+
54+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
55+
extension UnsafeBufferPointer : ContiguousBytes where Element == UInt8 {
56+
@inlinable
57+
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
58+
return try body(UnsafeRawBufferPointer(self))
59+
}
60+
}
61+
62+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
63+
extension UnsafeMutableBufferPointer : ContiguousBytes where Element == UInt8 {
64+
@inlinable
65+
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
66+
return try body(UnsafeRawBufferPointer(self))
67+
}
68+
}
69+
70+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
71+
extension EmptyCollection : ContiguousBytes where Element == UInt8 {
72+
@inlinable
73+
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
74+
return try body(UnsafeRawBufferPointer(start: nil, count: 0))
75+
}
76+
}
77+
78+
// FIXME: When possible, expand conformance to `where Element : Trivial`.
79+
extension CollectionOfOne : ContiguousBytes where Element == UInt8 {
80+
@inlinable
81+
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
82+
let element = self.first!
83+
return try Swift.withUnsafeBytes(of: element) {
84+
return try body($0)
85+
}
86+
}
87+
}
88+
89+
//===--- Conditional Conformances -----------------------------------------===//
90+
91+
extension Slice : ContiguousBytes where Base : ContiguousBytes {
92+
public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
93+
let offset = base.distance(from: base.startIndex, to: self.startIndex)
94+
return try base.withUnsafeBytes { ptr in
95+
let slicePtr = ptr.baseAddress?.advanced(by: offset)
96+
let sliceBuffer = UnsafeRawBufferPointer(start: slicePtr, count: self.count)
97+
return try body(sliceBuffer)
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)