@@ -604,7 +604,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
604
604
605
605
// MARK: - Base64 Methods
606
606
607
- private func estimateBase64Size( length: Int ) -> Int {
607
+ internal static func estimateBase64Size( length: Int ) -> Int {
608
608
// Worst case allow for 64bytes + \r\n per line 48 input bytes => 66 output bytes
609
609
return ( ( length + 47 ) * 66 ) / 48
610
610
}
@@ -614,11 +614,12 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
614
614
let dataLength = self . length
615
615
if dataLength == 0 { return " " }
616
616
617
- let capacity = estimateBase64Size ( length: dataLength)
617
+ let inputBuffer = UnsafeRawBufferPointer ( start: self . bytes, count: dataLength)
618
+ let capacity = NSData . estimateBase64Size ( length: dataLength)
618
619
let ptr = UnsafeMutableRawPointer . allocate ( byteCount: capacity, alignment: 4 )
619
620
defer { ptr. deallocate ( ) }
620
- let buffer = UnsafeMutableRawBufferPointer ( start: ptr, count: capacity)
621
- let length = NSData . base64EncodeBytes ( self , options: options, buffer: buffer )
621
+ let outputBuffer = UnsafeMutableRawBufferPointer ( start: ptr, count: capacity)
622
+ let length = NSData . base64EncodeBytes ( inputBuffer , options: options, buffer: outputBuffer )
622
623
623
624
return String ( decoding: UnsafeRawBufferPointer ( start: ptr, count: length) , as: Unicode . UTF8. self)
624
625
}
@@ -628,11 +629,13 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
628
629
let dataLength = self . length
629
630
if dataLength == 0 { return Data ( ) }
630
631
631
- let capacity = estimateBase64Size ( length: dataLength)
632
+ let inputBuffer = UnsafeRawBufferPointer ( start: self . bytes, count: self . length)
633
+
634
+ let capacity = NSData . estimateBase64Size ( length: dataLength)
632
635
let ptr = UnsafeMutableRawPointer . allocate ( byteCount: capacity, alignment: 4 )
633
- let buffer = UnsafeMutableRawBufferPointer ( start: ptr, count: capacity)
634
- let length = NSData . base64EncodeBytes ( self , options: options, buffer: buffer)
636
+ let outputBuffer = UnsafeMutableRawBufferPointer ( start: ptr, count: capacity)
635
637
638
+ let length = NSData . base64EncodeBytes ( inputBuffer, options: options, buffer: outputBuffer)
636
639
return Data ( bytesNoCopy: ptr, count: length, deallocator: . custom( { ( ptr, length) in
637
640
ptr. deallocate ( )
638
641
} ) )
@@ -761,13 +764,14 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
761
764
/**
762
765
This method encodes data in Base64.
763
766
764
- - parameter data: The NSData object you want to encode
767
+ - parameter dataBuffer: The UnsafeRawBufferPointer buffer to encode
765
768
- parameter options: Options for formatting the result
766
769
- parameter buffer: The buffer to write the bytes into
767
770
- returns: The number of bytes written into the buffer
768
- */
769
- private static func base64EncodeBytes( _ data: NSData , options: Base64EncodingOptions = [ ] , buffer: UnsafeMutableRawBufferPointer ) -> Int {
770
771
772
+ NOTE: dataBuffer would be better expressed as a <T: Collection> where T.Element == UInt8, T.Index == Int but this currently gives much poorer performance.
773
+ */
774
+ static func base64EncodeBytes( _ dataBuffer: UnsafeRawBufferPointer , options: Base64EncodingOptions = [ ] , buffer: UnsafeMutableRawBufferPointer ) -> Int {
771
775
// Use a StaticString for lookup of values 0-63 -> ASCII values
772
776
let base64Chars = StaticString ( " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ " )
773
777
assert ( base64Chars. utf8CodeUnitCount == 64 )
@@ -811,7 +815,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
811
815
}
812
816
813
817
// Read three bytes at a time, which convert to 4 ASCII characters, allowing for byte2 and byte3 being nil
814
- let dataBuffer = UnsafeRawBufferPointer ( start : data . bytes , count : data . length )
818
+
815
819
var inputIndex = 0
816
820
var outputIndex = 0
817
821
var bytesLeft = dataBuffer. count
0 commit comments