@@ -271,11 +271,13 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
271
271
272
272
/// The number of bytes contained by the data object.
273
273
open var length : Int {
274
+ requireFunnelOverridden ( )
274
275
return CFDataGetLength ( _cfObject)
275
276
}
276
277
277
278
/// A pointer to the data object's contents.
278
279
open var bytes : UnsafeRawPointer {
280
+ requireFunnelOverridden ( )
279
281
guard let bytePtr = CFDataGetBytePtr ( _cfObject) else {
280
282
//This could occure on empty data being encoded.
281
283
//TODO: switch with nil when signature is fixed
@@ -520,14 +522,29 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
520
522
// MARK: - Bytes
521
523
/// Copies a number of bytes from the start of the data object into a given buffer.
522
524
open func getBytes( _ buffer: UnsafeMutableRawPointer , length: Int ) {
523
- let bytePtr = buffer. bindMemory ( to: UInt8 . self, capacity: length)
524
- CFDataGetBytes ( _cfObject, CFRangeMake ( 0 , length) , bytePtr)
525
+ if funnelsAreAbstract {
526
+ let actualCount = Swift . min ( length, self . length)
527
+ let sourceBuffer = UnsafeRawBufferPointer ( start: bytes, count: actualCount)
528
+ let destinationBuffer = UnsafeMutableRawBufferPointer ( start: buffer, count: actualCount)
529
+ sourceBuffer. copyBytes ( to: destinationBuffer)
530
+ } else {
531
+ let bytePtr = buffer. bindMemory ( to: UInt8 . self, capacity: length)
532
+ CFDataGetBytes ( _cfObject, CFRangeMake ( 0 , length) , bytePtr)
533
+ }
525
534
}
526
535
527
536
/// Copies a range of bytes from the data object into a given buffer.
528
537
open func getBytes( _ buffer: UnsafeMutableRawPointer , range: NSRange ) {
529
- let bytePtr = buffer. bindMemory ( to: UInt8 . self, capacity: range. length)
530
- CFDataGetBytes ( _cfObject, CFRangeMake ( range. location, range. length) , bytePtr)
538
+ if funnelsAreAbstract {
539
+ precondition ( range. location >= 0 && range. length >= 0 )
540
+ let actualCount = Swift . min ( range. length, self . length - range. location)
541
+ let sourceBuffer = UnsafeRawBufferPointer ( start: bytes. advanced ( by: range. location) , count: actualCount)
542
+ let destinationBuffer = UnsafeMutableRawBufferPointer ( start: buffer, count: actualCount)
543
+ sourceBuffer. copyBytes ( to: destinationBuffer)
544
+ } else {
545
+ let bytePtr = buffer. bindMemory ( to: UInt8 . self, capacity: range. length)
546
+ CFDataGetBytes ( _cfObject, CFRangeMake ( range. location, range. length) , bytePtr)
547
+ }
531
548
}
532
549
533
550
/// Returns a new data object containing the data object's bytes that fall within the limits specified by a given range.
@@ -930,15 +947,18 @@ open class NSMutableData : NSData {
930
947
// MARK: - Funnel Methods
931
948
/// A pointer to the data contained by the mutable data object.
932
949
open var mutableBytes : UnsafeMutableRawPointer {
950
+ requireFunnelOverridden ( )
933
951
return UnsafeMutableRawPointer ( CFDataGetMutableBytePtr ( _cfMutableObject) )
934
952
}
935
953
936
954
/// The number of bytes contained in the mutable data object.
937
955
open override var length : Int {
938
956
get {
957
+ requireFunnelOverridden ( )
939
958
return CFDataGetLength ( _cfObject)
940
959
}
941
960
set {
961
+ requireFunnelOverridden ( )
942
962
CFDataSetLength ( _cfMutableObject, newValue)
943
963
}
944
964
}
@@ -951,8 +971,15 @@ open class NSMutableData : NSData {
951
971
// MARK: - Mutability
952
972
/// Appends to the data object a given number of bytes from a given buffer.
953
973
open func append( _ bytes: UnsafeRawPointer , length: Int ) {
954
- let bytePtr = bytes. bindMemory ( to: UInt8 . self, capacity: length)
955
- CFDataAppendBytes ( _cfMutableObject, bytePtr, length)
974
+ guard length > 0 else { return }
975
+
976
+ if funnelsAreAbstract {
977
+ self . length += length
978
+ UnsafeRawBufferPointer ( start: bytes, count: length) . copyBytes ( to: UnsafeMutableRawBufferPointer ( start: mutableBytes, count: length) )
979
+ } else {
980
+ let bytePtr = bytes. bindMemory ( to: UInt8 . self, capacity: length)
981
+ CFDataAppendBytes ( _cfMutableObject, bytePtr, length)
982
+ }
956
983
}
957
984
958
985
/// Appends the content of another data object to the data object.
@@ -965,13 +992,21 @@ open class NSMutableData : NSData {
965
992
966
993
/// Increases the length of the data object by a given number of bytes.
967
994
open func increaseLength( by extraLength: Int ) {
968
- CFDataSetLength ( _cfMutableObject, CFDataGetLength ( _cfObject) + extraLength)
995
+ if funnelsAreAbstract {
996
+ self . length += extraLength
997
+ } else {
998
+ CFDataSetLength ( _cfMutableObject, CFDataGetLength ( _cfObject) + extraLength)
999
+ }
969
1000
}
970
1001
971
1002
/// Replaces with a given set of bytes a given range within the contents of the data object.
972
1003
open func replaceBytes( in range: NSRange , withBytes bytes: UnsafeRawPointer ) {
973
- let bytePtr = bytes. bindMemory ( to: UInt8 . self, capacity: length)
974
- CFDataReplaceBytes ( _cfMutableObject, CFRangeMake ( range. location, range. length) , bytePtr, length)
1004
+ if funnelsAreAbstract {
1005
+ replaceBytes ( in: range, withBytes: bytes, length: range. length)
1006
+ } else {
1007
+ let bytePtr = bytes. bindMemory ( to: UInt8 . self, capacity: length)
1008
+ CFDataReplaceBytes ( _cfMutableObject, CFRangeMake ( range. location, range. length) , bytePtr, length)
1009
+ }
975
1010
}
976
1011
977
1012
/// Replaces with zeroes the contents of the data object in a given range.
@@ -989,8 +1024,22 @@ open class NSMutableData : NSData {
989
1024
990
1025
/// Replaces with a given set of bytes a given range within the contents of the data object.
991
1026
open func replaceBytes( in range: NSRange , withBytes replacementBytes: UnsafeRawPointer ? , length replacementLength: Int ) {
992
- let bytePtr = replacementBytes? . bindMemory ( to: UInt8 . self, capacity: replacementLength)
993
- CFDataReplaceBytes ( _cfMutableObject, CFRangeMake ( range. location, range. length) , bytePtr, replacementLength)
1027
+ precondition ( range. location + range. length <= self . length)
1028
+ if funnelsAreAbstract {
1029
+ let delta = replacementLength - range. length
1030
+ if delta != 0 {
1031
+ let originalLength = self . length
1032
+ self . length += delta
1033
+
1034
+ if delta > 0 {
1035
+ UnsafeRawBufferPointer ( start: mutableBytes. advanced ( by: range. location) , count: originalLength) . copyBytes ( to: UnsafeMutableRawBufferPointer ( start: mutableBytes. advanced ( by: range. location + range. length) , count: originalLength) )
1036
+ }
1037
+ }
1038
+ UnsafeRawBufferPointer ( start: replacementBytes, count: replacementLength) . copyBytes ( to: UnsafeMutableRawBufferPointer ( start: mutableBytes. advanced ( by: range. location) , count: replacementLength) )
1039
+ } else {
1040
+ let bytePtr = replacementBytes? . bindMemory ( to: UInt8 . self, capacity: replacementLength)
1041
+ CFDataReplaceBytes ( _cfMutableObject, CFRangeMake ( range. location, range. length) , bytePtr, replacementLength)
1042
+ }
994
1043
}
995
1044
}
996
1045
@@ -1014,6 +1063,50 @@ extension NSData : _StructTypeBridgeable {
1014
1063
}
1015
1064
}
1016
1065
1017
- internal func _CFSwiftDataCreateCopy( _ data: AnyObject ) -> Unmanaged < AnyObject > {
1066
+ internal func _CFSwiftDataCreateCopy( _ data: CFTypeRef ) -> Unmanaged < AnyObject > {
1018
1067
return Unmanaged< AnyObject> . passRetained( ( data as! NSData ) . copy ( ) as! NSObject )
1019
1068
}
1069
+
1070
+ internal func _CFSwiftDataGetLength( _ data: CFTypeRef ) -> CFIndex {
1071
+ return ( data as! NSData ) . length
1072
+ }
1073
+
1074
+ internal func _CFSwiftDataGetBytesPtr( _ data: CFTypeRef ) -> UnsafeRawPointer ? {
1075
+ return ( data as! NSData ) . bytes
1076
+ }
1077
+
1078
+ internal func _CFSwiftDataGetMutableBytesPtr( _ data: CFTypeRef ) -> UnsafeMutableRawPointer ? {
1079
+ return ( data as! NSMutableData ) . mutableBytes
1080
+ }
1081
+
1082
+ internal func _CFSwiftDataGetBytes( _ data: CFTypeRef , _ range: CFRange , _ buffer: UnsafeMutableRawPointer ) -> Void {
1083
+ ( data as! NSData ) . getBytes ( buffer, range: NSMakeRange ( range. location, range. length) )
1084
+ }
1085
+
1086
+ internal func _CFSwiftDataSetLength( _ data: CFTypeRef , _ newLength: CFIndex ) {
1087
+ ( data as! NSMutableData ) . length = newLength
1088
+ }
1089
+
1090
+ internal func _CFSwiftDataIncreaseLength( _ data: CFTypeRef , _ extraLength: CFIndex ) {
1091
+ ( data as! NSMutableData ) . increaseLength ( by: extraLength)
1092
+ }
1093
+
1094
+ internal func _CFSwiftDataAppendBytes( _ data: CFTypeRef , _ buffer: UnsafeRawPointer , length: CFIndex ) {
1095
+ ( data as! NSMutableData ) . append ( buffer, length: length)
1096
+ }
1097
+
1098
+ internal func _CFSwiftDataReplaceBytes( _ data: CFTypeRef , _ range: CFRange , _ buffer: UnsafeRawPointer ? , _ count: CFIndex ) {
1099
+ ( data as! NSMutableData ) . replaceBytes ( in: NSMakeRange ( range. location, range. length) , withBytes: buffer, length: count)
1100
+ }
1101
+
1102
+ extension NSData {
1103
+ var funnelsAreAbstract : Bool {
1104
+ return type ( of: self ) != NSData . self && type ( of: self ) != NSMutableData . self
1105
+ }
1106
+
1107
+ func requireFunnelOverridden( ) {
1108
+ if funnelsAreAbstract {
1109
+ NSRequiresConcreteImplementation ( )
1110
+ }
1111
+ }
1112
+ }
0 commit comments