Skip to content

Commit 9fbad13

Browse files
committed
[Foundation] Correct sequence initializers for Data when repeating:count: is called and add a memset fast-path
1 parent 125af80 commit 9fbad13

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

stdlib/public/SDK/Foundation/Data.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,17 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
10101010
return _DataStorage(bytes: $0.baseAddress, length: $0.count)
10111011
}
10121012
}
1013+
1014+
/// Initialze a `Data` with a repeating byte pattern
1015+
///
1016+
/// - parameter repeatedValue: A byte to initialze the pattern
1017+
/// - parameter count: The number of bytes the data initially contains initialzed to the repeatedValue
1018+
public init(repeating repeatedValue: UInt8, count: Int) {
1019+
self.init(count: count)
1020+
withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in
1021+
memset(bytes, Int32(repeatedValue), count)
1022+
}
1023+
}
10131024

10141025
/// Initialize a `Data` with the specified size.
10151026
///
@@ -1330,9 +1341,12 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
13301341
}
13311342
count += estimatedCount
13321343
for byte in newElements {
1344+
let newIndex = idx + 1
1345+
if newIndex > count {
1346+
count = newIndex
1347+
}
13331348
self[idx] = byte
1334-
idx += 1
1335-
count = idx
1349+
idx = newIndex
13361350
}
13371351
}
13381352

test/stdlib/TestData.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,20 @@ class TestData : TestDataSuper {
907907
}
908908
expectEqual(len, 1)
909909
}
910+
911+
func test_repeatingValueInitialization() {
912+
var d = Data(repeating: 0x01, count: 3)
913+
let elements = repeatElement(UInt8(0x02), count: 3) // ensure we fall into the sequence case
914+
d.append(contentsOf: elements)
915+
916+
expectEqual(d[0], 0x01)
917+
expectEqual(d[1], 0x01)
918+
expectEqual(d[2], 0x01)
919+
920+
expectEqual(d[3], 0x02)
921+
expectEqual(d[4], 0x02)
922+
expectEqual(d[5], 0x02)
923+
}
910924
}
911925

912926
#if !FOUNDATION_XCTEST
@@ -951,6 +965,7 @@ DataTests.test("test_AnyHashableContainingData") { TestData().test_AnyHashableCo
951965
DataTests.test("test_AnyHashableCreatedFromNSData") { TestData().test_AnyHashableCreatedFromNSData() }
952966
DataTests.test("test_noCopyBehavior") { TestData().test_noCopyBehavior() }
953967
DataTests.test("test_doubleDeallocation") { TestData().test_doubleDeallocation() }
968+
DataTests.test("test_repeatingValueInitialization") { TestData().test_repeatingValueInitialization() }
954969

955970
// XCTest does not have a crash detection, whereas lit does
956971
DataTests.test("bounding failure subdata") {

0 commit comments

Comments
 (0)