Skip to content

Commit c12f650

Browse files
saiHemakianpartridge
authored andcommitted
Aligning Data in into sync with the version in the overlay (#1494)
1 parent 4f2ca47 commit c12f650

File tree

2 files changed

+368
-59
lines changed

2 files changed

+368
-59
lines changed

Foundation/Data.swift

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,6 @@ internal func __NSDataIsCompact(_ data: NSData) -> Bool {
3838
import _SwiftFoundationOverlayShims
3939
import _SwiftCoreFoundationOverlayShims
4040

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-
5741
#endif
5842

5943
public final class _DataStorage {
@@ -143,7 +127,7 @@ public final class _DataStorage {
143127
case .mutable:
144128
return try apply(UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, _length)))
145129
case .customReference(let d):
146-
if __NSDataIsCompact(d) {
130+
if d._isCompact() {
147131
let len = d.length
148132
guard len > 0 else {
149133
return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
@@ -155,26 +139,28 @@ public final class _DataStorage {
155139
let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
156140
var enumerated = 0
157141
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 {
165156
stop.pointee = true
166-
} else {
167-
memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr, effectiveRange.length)
168157
}
169-
enumerated += byteRange.length
170-
} else if sliceRange.location + sliceRange.length < byteRange.location {
171-
stop.pointee = true
172158
}
173159
}
174160
return try apply(UnsafeRawBufferPointer(buffer))
175161
}
176162
case .customMutableReference(let d):
177-
if __NSDataIsCompact(d) {
163+
if d._isCompact() {
178164
let len = d.length
179165
guard len > 0 else {
180166
return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
@@ -186,19 +172,22 @@ public final class _DataStorage {
186172
let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
187173
var enumerated = 0
188174
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 {
195189
stop.pointee = true
196-
} else {
197-
memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr, effectiveRange.length)
198190
}
199-
enumerated += byteRange.length
200-
} else if sliceRange.location + sliceRange.length < byteRange.location {
201-
stop.pointee = true
202191
}
203192
}
204193
return try apply(UnsafeRawBufferPointer(buffer))
@@ -518,7 +507,7 @@ public final class _DataStorage {
518507
case .mutable:
519508
return _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
520509
case .customReference(let d):
521-
if __NSDataIsCompact(d) {
510+
if d._isCompact() {
522511
return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
523512
} else {
524513
var byte: UInt8 = 0
@@ -532,7 +521,7 @@ public final class _DataStorage {
532521
return byte
533522
}
534523
case .customMutableReference(let d):
535-
if __NSDataIsCompact(d) {
524+
if d._isCompact() {
536525
return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
537526
} else {
538527
var byte: UInt8 = 0
@@ -1002,8 +991,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1002991
public typealias Base64DecodingOptions = NSData.Base64DecodingOptions
1003992

1004993
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>
1007995

1008996
@_versioned internal var _backing : _DataStorage
1009997
@_versioned internal var _sliceRange: Range<Index>
@@ -1435,17 +1423,17 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14351423
let nsRange : NSRange
14361424
if let r = range {
14371425
_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)
14391427
} else {
1440-
nsRange = NSRange(location: 0, length: _backing.length)
1428+
nsRange = NSRange(location: 0, length: count)
14411429
}
14421430
let result = _backing.withInteriorPointerReference(_sliceRange) {
14431431
$0.range(of: dataToFind, options: options, in: nsRange)
14441432
}
14451433
if result.location == NSNotFound {
14461434
return nil
14471435
}
1448-
return result.location..<(result.location + result.length)
1436+
return (result.location + startIndex)..<((result.location + startIndex) + result.length)
14491437
}
14501438

14511439
/// Enumerate the contents of the data.
@@ -1744,7 +1732,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
17441732
return i + 1
17451733
}
17461734

1747-
public var indices: CountableRange<Int> {
1735+
public var indices: Range<Int> {
17481736
@inline(__always)
17491737
get {
17501738
return startIndex..<endIndex
@@ -1772,14 +1760,23 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
17721760
}
17731761

17741762
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
17761773
private var _buffer: (
17771774
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
17781775
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
17791776
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
17801777
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
17811778
private var _idx: Data.Index
1782-
private let _endIdx: Data.Index
1779+
private var _endIdx: Data.Index
17831780

17841781
fileprivate init(_ data: Data) {
17851782
_data = data

0 commit comments

Comments
 (0)