@@ -38,6 +38,22 @@ 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( OSX 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
+
41
57
@_silgen_name ( " __NSDataWriteToURL " )
42
58
internal func __NSDataWriteToURL( _ data: NSData , _ url: NSURL , _ options: UInt , _ error: NSErrorPointer ) -> Bool
43
59
@@ -130,7 +146,7 @@ public final class _DataStorage {
130
146
case . mutable:
131
147
return try apply ( UnsafeRawBufferPointer ( start: _bytes? . advanced ( by: range. lowerBound - _offset) , count: Swift . min ( range. count, _length) ) )
132
148
case . customReference( let d) :
133
- if d . _isCompact ( ) {
149
+ if __NSDataIsCompact ( d ) {
134
150
let len = d. length
135
151
guard len > 0 else {
136
152
return try apply ( UnsafeRawBufferPointer ( start: nil , count: 0 ) )
@@ -161,7 +177,7 @@ public final class _DataStorage {
161
177
return try apply ( UnsafeRawBufferPointer ( buffer) )
162
178
}
163
179
case . customMutableReference( let d) :
164
- if d . _isCompact ( ) {
180
+ if __NSDataIsCompact ( d ) {
165
181
let len = d. length
166
182
guard len > 0 else {
167
183
return try apply ( UnsafeRawBufferPointer ( start: nil , count: 0 ) )
@@ -505,7 +521,7 @@ public final class _DataStorage {
505
521
case . mutable:
506
522
return _bytes!. advanced ( by: index - _offset) . assumingMemoryBound ( to: UInt8 . self) . pointee
507
523
case . customReference( let d) :
508
- if d . _isCompact ( ) {
524
+ if __NSDataIsCompact ( d ) {
509
525
return d. bytes. advanced ( by: index - _offset) . assumingMemoryBound ( to: UInt8 . self) . pointee
510
526
} else {
511
527
var byte : UInt8 = 0
@@ -519,7 +535,7 @@ public final class _DataStorage {
519
535
return byte
520
536
}
521
537
case . customMutableReference( let d) :
522
- if d . _isCompact ( ) {
538
+ if __NSDataIsCompact ( d ) {
523
539
return d. bytes. advanced ( by: index - _offset) . assumingMemoryBound ( to: UInt8 . self) . pointee
524
540
} else {
525
541
var byte : UInt8 = 0
@@ -1626,9 +1642,11 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1626
1642
public var hashValue : Int {
1627
1643
var hashValue = 0
1628
1644
let hashRange : Range < Int > = _sliceRange. lowerBound..< Swift . min ( _sliceRange. lowerBound + 80 , _sliceRange. upperBound)
1629
- _withStackOrHeapBuffer ( hashRange. count) { buffer in
1630
- _backing. withUnsafeBytes ( in: hashRange) {
1631
- memcpy ( buffer. pointee. memory, $0. baseAddress!, hashRange. count)
1645
+ _withStackOrHeapBuffer ( hashRange. count + 1 ) { buffer in
1646
+ if hashRange. count > 0 {
1647
+ _backing. withUnsafeBytes ( in: hashRange) {
1648
+ memcpy ( buffer. pointee. memory, $0. baseAddress!, hashRange. count)
1649
+ }
1632
1650
}
1633
1651
hashValue = Int ( bitPattern: CFHashBytes ( buffer. pointee. memory. assumingMemoryBound ( to: UInt8 . self) , hashRange. count) )
1634
1652
}
0 commit comments