@@ -38,22 +38,6 @@ internal func __NSDataIsCompact(_ data: NSData) -> Bool {
38
38
import _SwiftFoundationOverlayShims
39
39
import _SwiftCoreFoundationOverlayShims
40
40
41
- internal func __NSDataIsCompact( _ data: NSData ) -> Bool {
42
- if #available( macOS 10 . 10 , iOS 9 . 0 , tvOS 9 . 0 , watchOS 2 . 0 , * ) {
43
- return data. _isCompact ( )
44
- } else {
45
- var compact = true
46
- let len = data. length
47
- data. enumerateBytes { ( _, byteRange, stop) in
48
- if byteRange. length != len {
49
- compact = false
50
- }
51
- stop. pointee = true
52
- }
53
- return compact
54
- }
55
- }
56
-
57
41
#endif
58
42
59
43
public final class _DataStorage {
@@ -143,7 +127,7 @@ public final class _DataStorage {
143
127
case . mutable:
144
128
return try apply ( UnsafeRawBufferPointer ( start: _bytes? . advanced ( by: range. lowerBound - _offset) , count: Swift . min ( range. count, _length) ) )
145
129
case . customReference( let d) :
146
- if __NSDataIsCompact ( d ) {
130
+ if d . _isCompact ( ) {
147
131
let len = d. length
148
132
guard len > 0 else {
149
133
return try apply ( UnsafeRawBufferPointer ( start: nil , count: 0 ) )
@@ -155,26 +139,28 @@ public final class _DataStorage {
155
139
let sliceRange = NSRange ( location: range. lowerBound - _offset, length: range. count)
156
140
var enumerated = 0
157
141
d. enumerateBytes { ( ptr, byteRange, stop) in
158
- if NSIntersectionRange ( sliceRange, byteRange) . length > 0 {
159
- let lower = Swift . max ( byteRange. location, sliceRange. location)
160
- let upper = Swift . min ( byteRange. location + byteRange. length, sliceRange. location + sliceRange. length)
161
- let offset = lower - byteRange. location
162
- let effectiveRange = NSRange ( location: lower, length: upper - lower)
163
- if effectiveRange == sliceRange {
164
- memcpy ( buffer. baseAddress!, ptr, effectiveRange. length)
142
+ if byteRange. upperBound - _offset < range. lowerBound {
143
+ // before the range that we are looking for...
144
+ } else if byteRange. lowerBound - _offset > range. upperBound {
145
+ stop. pointee = true // we are past the range in question so we need to stop
146
+ } else {
147
+ // the byteRange somehow intersects the range in question that we are looking for...
148
+ let lower = Swift . max ( byteRange. lowerBound - _offset, range. lowerBound)
149
+ let upper = Swift . min ( byteRange. upperBound - _offset, range. upperBound)
150
+
151
+ let len = upper - lower
152
+ memcpy ( buffer. baseAddress!. advanced ( by: enumerated) , ptr. advanced ( by: lower - ( byteRange. lowerBound - _offset) ) , len)
153
+ enumerated += len
154
+
155
+ if upper == range. upperBound {
165
156
stop. pointee = true
166
- } else {
167
- memcpy ( buffer. baseAddress!. advanced ( by: enumerated) , ptr, effectiveRange. length)
168
157
}
169
- enumerated += byteRange. length
170
- } else if sliceRange. location + sliceRange. length < byteRange. location {
171
- stop. pointee = true
172
158
}
173
159
}
174
160
return try apply ( UnsafeRawBufferPointer ( buffer) )
175
161
}
176
162
case . customMutableReference( let d) :
177
- if __NSDataIsCompact ( d ) {
163
+ if d . _isCompact ( ) {
178
164
let len = d. length
179
165
guard len > 0 else {
180
166
return try apply ( UnsafeRawBufferPointer ( start: nil , count: 0 ) )
@@ -186,19 +172,22 @@ public final class _DataStorage {
186
172
let sliceRange = NSRange ( location: range. lowerBound - _offset, length: range. count)
187
173
var enumerated = 0
188
174
d. enumerateBytes { ( ptr, byteRange, stop) in
189
- if NSIntersectionRange ( sliceRange, byteRange) . length > 0 {
190
- let lower = Swift . max ( byteRange. location, sliceRange. location)
191
- let upper = Swift . min ( byteRange. location + byteRange. length, sliceRange. location + sliceRange. length)
192
- let effectiveRange = NSRange ( location: lower, length: upper - lower)
193
- if effectiveRange == sliceRange {
194
- memcpy ( buffer. baseAddress!, ptr, effectiveRange. length)
175
+ if byteRange. upperBound - _offset < range. lowerBound {
176
+ // before the range that we are looking for...
177
+ } else if byteRange. lowerBound - _offset > range. upperBound {
178
+ stop. pointee = true // we are past the range in question so we need to stop
179
+ } else {
180
+ // the byteRange somehow intersects the range in question that we are looking for...
181
+ let lower = Swift . max ( byteRange. lowerBound - _offset, range. lowerBound)
182
+ let upper = Swift . min ( byteRange. upperBound - _offset, range. upperBound)
183
+
184
+ let len = upper - lower
185
+ memcpy ( buffer. baseAddress!. advanced ( by: enumerated) , ptr. advanced ( by: lower - ( byteRange. lowerBound - _offset) ) , len)
186
+ enumerated += len
187
+
188
+ if upper == range. upperBound {
195
189
stop. pointee = true
196
- } else {
197
- memcpy ( buffer. baseAddress!. advanced ( by: enumerated) , ptr, effectiveRange. length)
198
190
}
199
- enumerated += byteRange. length
200
- } else if sliceRange. location + sliceRange. length < byteRange. location {
201
- stop. pointee = true
202
191
}
203
192
}
204
193
return try apply ( UnsafeRawBufferPointer ( buffer) )
@@ -518,7 +507,7 @@ public final class _DataStorage {
518
507
case . mutable:
519
508
return _bytes!. advanced ( by: index - _offset) . assumingMemoryBound ( to: UInt8 . self) . pointee
520
509
case . customReference( let d) :
521
- if __NSDataIsCompact ( d ) {
510
+ if d . _isCompact ( ) {
522
511
return d. bytes. advanced ( by: index - _offset) . assumingMemoryBound ( to: UInt8 . self) . pointee
523
512
} else {
524
513
var byte : UInt8 = 0
@@ -532,7 +521,7 @@ public final class _DataStorage {
532
521
return byte
533
522
}
534
523
case . customMutableReference( let d) :
535
- if __NSDataIsCompact ( d ) {
524
+ if d . _isCompact ( ) {
536
525
return d. bytes. advanced ( by: index - _offset) . assumingMemoryBound ( to: UInt8 . self) . pointee
537
526
} else {
538
527
var byte : UInt8 = 0
@@ -1002,8 +991,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1002
991
public typealias Base64DecodingOptions = NSData . Base64DecodingOptions
1003
992
1004
993
public typealias Index = Int
1005
- // FIXME: switch back to Range once swift 5.0 branch has PR #13342
1006
- public typealias Indices = CountableRange < Int >
994
+ public typealias Indices = Range < Int >
1007
995
1008
996
@_versioned internal var _backing : _DataStorage
1009
997
@_versioned internal var _sliceRange : Range < Index >
@@ -1435,17 +1423,17 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1435
1423
let nsRange : NSRange
1436
1424
if let r = range {
1437
1425
_validateRange ( r)
1438
- nsRange = NSRange ( location: r. lowerBound, length: r. upperBound - r. lowerBound)
1426
+ nsRange = NSRange ( location: r. lowerBound - startIndex , length: r. upperBound - r. lowerBound)
1439
1427
} else {
1440
- nsRange = NSRange ( location: 0 , length: _backing . length )
1428
+ nsRange = NSRange ( location: 0 , length: count )
1441
1429
}
1442
1430
let result = _backing. withInteriorPointerReference ( _sliceRange) {
1443
1431
$0. range ( of: dataToFind, options: options, in: nsRange)
1444
1432
}
1445
1433
if result. location == NSNotFound {
1446
1434
return nil
1447
1435
}
1448
- return result. location..< ( result. location + result. length)
1436
+ return ( result. location + startIndex ) ..< ( ( result. location + startIndex ) + result. length)
1449
1437
}
1450
1438
1451
1439
/// Enumerate the contents of the data.
@@ -1744,7 +1732,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1744
1732
return i + 1
1745
1733
}
1746
1734
1747
- public var indices : CountableRange < Int > {
1735
+ public var indices : Range < Int > {
1748
1736
@inline ( __always)
1749
1737
get {
1750
1738
return startIndex..< endIndex
@@ -1772,14 +1760,23 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1772
1760
}
1773
1761
1774
1762
public struct Iterator : IteratorProtocol {
1775
- private let _data : Data
1763
+ // Both _data and _endIdx should be 'let' rather than 'var'.
1764
+ // They are 'var' so that the stored properties can be read
1765
+ // independently of the other contents of the struct. This prevents
1766
+ // an exclusivity violation when reading '_endIdx' and '_data'
1767
+ // while simultaneously mutating '_buffer' with the call to
1768
+ // withUnsafeMutablePointer(). Once we support accessing struct
1769
+ // let properties independently we should make these variables
1770
+ // 'let' again.
1771
+
1772
+ private var _data : Data
1776
1773
private var _buffer : (
1777
1774
UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 ,
1778
1775
UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 ,
1779
1776
UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 ,
1780
1777
UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 )
1781
1778
private var _idx : Data . Index
1782
- private let _endIdx : Data . Index
1779
+ private var _endIdx : Data . Index
1783
1780
1784
1781
fileprivate init ( _ data: Data ) {
1785
1782
_data = data
0 commit comments