Skip to content

Commit 9a33db9

Browse files
authored
Merge pull request swiftlang#33 from swiftwasm/master
[pull] swiftwasm from master
2 parents 9f82849 + 84f581d commit 9a33db9

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

Sources/Foundation/NSData.swift

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,9 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
217217
return nil
218218
}
219219
super.init()
220-
_init(bytes: &decodedBytes, length: decodedBytes.count, copy: true)
220+
_init(bytes: decodedBytes.baseAddress!, length: decodedBytes.count, copy: false, deallocator: { (ptr, length) in
221+
ptr.deallocate()
222+
})
221223
}
222224

223225
/// Initializes a data object with the given Base64 encoded data.
@@ -226,7 +228,9 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
226228
return nil
227229
}
228230
super.init()
229-
_init(bytes: &decodedBytes, length: decodedBytes.count, copy: true)
231+
_init(bytes: decodedBytes.baseAddress!, length: decodedBytes.count, copy: false, deallocator: { (ptr, length) in
232+
ptr.deallocate()
233+
})
230234
}
231235

232236
deinit {
@@ -647,7 +651,7 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
647651
- parameter options: Options for handling invalid input
648652
- returns: The decoded bytes.
649653
*/
650-
private static func base64DecodeBytes<T: Collection>(_ bytes: T, options: Base64DecodingOptions = []) -> [UInt8]? where T.Element == UInt8 {
654+
private static func base64DecodeBytes<T: Collection>(_ bytes: T, options: Base64DecodingOptions = []) -> UnsafeMutableRawBufferPointer? where T.Element == UInt8 {
651655

652656
// This table maps byte values 0-127, input bytes >127 are always invalid.
653657
// Map the ASCII characters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -> 0...63
@@ -672,14 +676,21 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
672676
return nil
673677
}
674678

675-
var decodedBytes: [UInt8] = []
676679
let capacity = (bytes.count * 3) / 4 // Every 4 valid ASCII bytes maps to 3 output bytes.
677-
decodedBytes.reserveCapacity(capacity)
680+
let buffer = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: 1)
681+
var outputIndex = 0
682+
683+
func append(_ byte: UInt8) {
684+
assert(outputIndex < capacity)
685+
buffer.storeBytes(of: byte, toByteOffset: outputIndex, as: UInt8.self)
686+
outputIndex += 1
687+
}
678688

679689
var currentByte: UInt8 = 0
680690
var validCharacterCount = 0
681691
var paddingCount = 0
682692
var index = 0
693+
var error = false
683694

684695
for base64Char in bytes {
685696
var value: UInt8 = 0
@@ -703,30 +714,32 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
703714
if ignoreUnknown {
704715
continue
705716
} else {
706-
return nil
717+
error = true
718+
break
707719
}
708720
}
709721
validCharacterCount += 1
710722

711723
// Padding found in the middle of the sequence is invalid.
712724
if paddingCount > 0 {
713-
return nil
725+
error = true
726+
break
714727
}
715728

716729
switch index {
717730
case 0:
718731
currentByte = (value << 2)
719732
case 1:
720733
currentByte |= (value >> 4)
721-
decodedBytes.append(currentByte)
734+
append(currentByte)
722735
currentByte = (value << 4)
723736
case 2:
724737
currentByte |= (value >> 2)
725-
decodedBytes.append(currentByte)
738+
append(currentByte)
726739
currentByte = (value << 6)
727740
case 3:
728741
currentByte |= value
729-
decodedBytes.append(currentByte)
742+
append(currentByte)
730743
index = -1
731744
default:
732745
fatalError()
@@ -735,11 +748,12 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
735748
index += 1
736749
}
737750

738-
guard (validCharacterCount + paddingCount) % 4 == 0 else {
751+
guard error == false && (validCharacterCount + paddingCount) % 4 == 0 else {
739752
// Invalid character count of valid input characters.
753+
buffer.deallocate()
740754
return nil
741755
}
742-
return decodedBytes
756+
return UnsafeMutableRawBufferPointer(start: buffer, count: outputIndex)
743757
}
744758

745759
/**

0 commit comments

Comments
 (0)