@@ -210,7 +210,9 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
210
210
return nil
211
211
}
212
212
super. init ( )
213
- _init ( bytes: & decodedBytes, length: decodedBytes. count, copy: true )
213
+ _init ( bytes: decodedBytes. baseAddress!, length: decodedBytes. count, copy: false , deallocator: { ( ptr, length) in
214
+ ptr. deallocate ( )
215
+ } )
214
216
}
215
217
216
218
/// Initializes a data object with the given Base64 encoded data.
@@ -219,7 +221,9 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
219
221
return nil
220
222
}
221
223
super. init ( )
222
- _init ( bytes: & decodedBytes, length: decodedBytes. count, copy: true )
224
+ _init ( bytes: decodedBytes. baseAddress!, length: decodedBytes. count, copy: false , deallocator: { ( ptr, length) in
225
+ ptr. deallocate ( )
226
+ } )
223
227
}
224
228
225
229
deinit {
@@ -634,7 +638,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
634
638
- parameter options: Options for handling invalid input
635
639
- returns: The decoded bytes.
636
640
*/
637
- private static func base64DecodeBytes< T: Collection > ( _ bytes: T , options: Base64DecodingOptions = [ ] ) -> [ UInt8 ] ? where T. Element == UInt8 {
641
+ private static func base64DecodeBytes< T: Collection > ( _ bytes: T , options: Base64DecodingOptions = [ ] ) -> UnsafeMutableRawBufferPointer ? where T. Element == UInt8 {
638
642
639
643
// This table maps byte values 0-127, input bytes >127 are always invalid.
640
644
// Map the ASCII characters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -> 0...63
@@ -659,14 +663,21 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
659
663
return nil
660
664
}
661
665
662
- var decodedBytes : [ UInt8 ] = [ ]
663
666
let capacity = ( bytes. count * 3 ) / 4 // Every 4 valid ASCII bytes maps to 3 output bytes.
664
- decodedBytes. reserveCapacity ( capacity)
667
+ let buffer = UnsafeMutableRawPointer . allocate ( byteCount: capacity, alignment: 1 )
668
+ var outputIndex = 0
669
+
670
+ func append( _ byte: UInt8 ) {
671
+ assert ( outputIndex < capacity)
672
+ buffer. storeBytes ( of: byte, toByteOffset: outputIndex, as: UInt8 . self)
673
+ outputIndex += 1
674
+ }
665
675
666
676
var currentByte : UInt8 = 0
667
677
var validCharacterCount = 0
668
678
var paddingCount = 0
669
679
var index = 0
680
+ var error = false
670
681
671
682
for base64Char in bytes {
672
683
var value : UInt8 = 0
@@ -690,30 +701,32 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
690
701
if ignoreUnknown {
691
702
continue
692
703
} else {
693
- return nil
704
+ error = true
705
+ break
694
706
}
695
707
}
696
708
validCharacterCount += 1
697
709
698
710
// Padding found in the middle of the sequence is invalid.
699
711
if paddingCount > 0 {
700
- return nil
712
+ error = true
713
+ break
701
714
}
702
715
703
716
switch index {
704
717
case 0 :
705
718
currentByte = ( value << 2 )
706
719
case 1 :
707
720
currentByte |= ( value >> 4 )
708
- decodedBytes . append ( currentByte)
721
+ append ( currentByte)
709
722
currentByte = ( value << 4 )
710
723
case 2 :
711
724
currentByte |= ( value >> 2 )
712
- decodedBytes . append ( currentByte)
725
+ append ( currentByte)
713
726
currentByte = ( value << 6 )
714
727
case 3 :
715
728
currentByte |= value
716
- decodedBytes . append ( currentByte)
729
+ append ( currentByte)
717
730
index = - 1
718
731
default :
719
732
fatalError ( )
@@ -722,11 +735,12 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
722
735
index += 1
723
736
}
724
737
725
- guard ( validCharacterCount + paddingCount) % 4 == 0 else {
738
+ guard error == false && ( validCharacterCount + paddingCount) % 4 == 0 else {
726
739
// Invalid character count of valid input characters.
740
+ buffer. deallocate ( )
727
741
return nil
728
742
}
729
- return decodedBytes
743
+ return UnsafeMutableRawBufferPointer ( start : buffer , count : outputIndex )
730
744
}
731
745
732
746
/**
0 commit comments