Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
efb4e11
(161108781) Add FoundationPreview 6.4 availability (#1516)
jmschonfeld Sep 22, 2025
b60b37e
Merge pull request #1517 from swiftlang/automerge/merge-main-2025-09-…
parkera Sep 24, 2025
e6dfded
Merge pull request #1522 from swiftlang/automerge/merge-main-2025-09-…
parkera Sep 25, 2025
a402ee0
Merge pull request #1524 from swiftlang/automerge/merge-main-2025-09-…
parkera Sep 26, 2025
221ece3
Merge pull request #1529 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 1, 2025
8eeaa86
Merge pull request #1532 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 2, 2025
bf578a1
Merge pull request #1534 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 3, 2025
aa3a457
Merge pull request #1537 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 9, 2025
a07efec
Add LargeData internal initializer entrypoint (#1538)
jmschonfeld Oct 9, 2025
344f413
Merge pull request #1540 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 10, 2025
5ef0061
Merge pull request #1542 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 12, 2025
4273e23
[Implementation] ProgressManager v6 implementation (#1468)
chloe-yeo Oct 14, 2025
a601cb9
(161424331) Change Data hashing to full bytes (#1546)
jmschonfeld Oct 14, 2025
e4ef061
Merge pull request #1549 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 15, 2025
835789d
(162698092) Micro Optimization: Elide overflow checking in Data.bytes…
jmschonfeld Oct 15, 2025
6bd48d5
Merge pull request #1552 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 17, 2025
1aac1b5
Merge pull request #1555 from swiftlang/automerge/merge-main-2025-10-…
jmschonfeld Oct 23, 2025
cc94421
Refactor Data implementation into separate chunks (#1563)
jmschonfeld Oct 29, 2025
3b7d7c8
Assorted minor data updates (#1564)
jmschonfeld Oct 29, 2025
0b7c267
(163677167) Switch swift-founation Data allocation to typed malloc (#…
jmschonfeld Oct 31, 2025
bfdb63b
Merge pull request #1569 from swiftlang/automerge/merge-main-2025-11-…
jmschonfeld Nov 2, 2025
1ac5330
Remove expensive availability checks from Data replaceSubrange (#1571)
jmschonfeld Nov 4, 2025
6abc853
Fix Data-related Android build failures (#1572)
jmschonfeld Nov 4, 2025
6aa02a0
Merge pull request #1574 from swiftlang/automerge/merge-main-2025-11-…
jmschonfeld Nov 4, 2025
f819caa
Minor Updates to `ProgressManager` API (#1559)
chloe-yeo Nov 5, 2025
245ec37
Merge pull request #1575 from swiftlang/automerge/merge-main-2025-11-…
jmschonfeld Nov 6, 2025
3c602cd
Move Data Hashable/Equatable conformance back to struct (#1579)
jmschonfeld Nov 6, 2025
cff1f3e
Refactor data bridging and move to swift-foundation (#1578)
jmschonfeld Nov 7, 2025
de6ca57
Merge pull request #1580 from swiftlang/automerge/merge-main-2025-11-…
jmschonfeld Nov 7, 2025
bb52b40
Use updated spelling for lifetime annotations.
glessard Nov 7, 2025
4bf6ba8
Adopt span in Data IO implementation (#1576)
jmschonfeld Nov 8, 2025
0bd543d
Merge branch 'future' into update-lifetimes-feature
glessard Nov 10, 2025
b9bdc6f
Use updated spelling for lifetime annotations.
glessard Nov 10, 2025
6487b05
weak attempt at clarifying compiler error
glessard Nov 10, 2025
b9dfce8
Resolve a few Data warnings (#1583)
jmschonfeld Nov 10, 2025
d9366d6
Merge pull request #1590 from glessard/update-lifetimes-feature
jmschonfeld Nov 10, 2025
600e8f1
Merge branch 'future' into automerge/merge-main-2025-11-11_09-05
glessard Nov 11, 2025
33a0ecb
Revert "weak attempt at clarifying compiler error"
glessard Nov 11, 2025
aa5dd1c
Merge pull request #1592 from swiftlang/automerge/merge-main-2025-11-…
jmschonfeld Nov 11, 2025
4dcbbcc
Merge pull request #1595 from swiftlang/automerge/merge-main-2025-11-…
jmschonfeld Nov 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ list(APPEND _SwiftFoundation_versions
"6.1"
"6.2"
"6.3"
"6.4"
)

# Each availability name to define
Expand Down
7 changes: 4 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import CompilerPluginSupport
let availabilityTags: [_Availability] = [
_Availability("FoundationPreview"), // Default FoundationPreview availability
]
let versionNumbers = ["6.0.2", "6.1", "6.2", "6.3"]
let versionNumbers = ["6.0.2", "6.1", "6.2", "6.3", "6.4"]

// Availability Macro Utilities

Expand Down Expand Up @@ -140,7 +140,8 @@ let package = Package(
"ProcessInfo/CMakeLists.txt",
"FileManager/CMakeLists.txt",
"URL/CMakeLists.txt",
"NotificationCenter/CMakeLists.txt"
"NotificationCenter/CMakeLists.txt",
"ProgressManager/CMakeLists.txt",
],
cSettings: [
.define("_GNU_SOURCE", .when(platforms: [.linux]))
Expand Down Expand Up @@ -185,7 +186,7 @@ let package = Package(
"Locale/CMakeLists.txt",
"Calendar/CMakeLists.txt",
"CMakeLists.txt",
"Predicate/CMakeLists.txt"
"Predicate/CMakeLists.txt",
],
cSettings: wasiLibcCSettings,
swiftSettings: [
Expand Down
2 changes: 2 additions & 0 deletions Sources/FoundationEssentials/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ add_library(FoundationEssentials
Logging.swift
OutputBuffer.swift
Platform.swift
Progress+Stub.swift
SortComparator.swift
UUID_Wrappers.swift
UUID.swift
Expand All @@ -45,6 +46,7 @@ add_subdirectory(Locale)
add_subdirectory(NotificationCenter)
add_subdirectory(Predicate)
add_subdirectory(ProcessInfo)
add_subdirectory(ProgressManager)
add_subdirectory(PropertyList)
add_subdirectory(String)
add_subdirectory(TimeZone)
Expand Down
16 changes: 13 additions & 3 deletions Sources/FoundationEssentials/Data/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
##
## This source file is part of the Swift open source project
##
## Copyright (c) 2024 Apple Inc. and the Swift project authors
## Copyright (c) 2024-2025 Apple Inc. and the Swift project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
Expand All @@ -13,13 +13,23 @@
##===----------------------------------------------------------------------===##

target_sources(FoundationEssentials PRIVATE
Representations/Data+Inline.swift
Representations/Data+InlineSlice.swift
Representations/Data+LargeSlice.swift
Representations/Data+Representation.swift
Representations/DataStorage.swift

Collections+DataProtocol.swift
ContiguousBytes.swift
Data.swift
Data+Base64.swift
Data+Bridging.swift
Data+Deprecated.swift
Data+Error.swift
Data+Iterator.swift
Data+Reading.swift
Data+Stub.swift
Data+Searching.swift
Data+Writing.swift
Data.swift
DataProtocol.swift
PathOrURL.swift
Pointers+DataProtocol.swift)
5 changes: 4 additions & 1 deletion Sources/FoundationEssentials/Data/ContiguousBytes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2018 Apple Inc. and the Swift project authors
// Copyright (c) 2018-2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -39,6 +39,9 @@ extension ArraySlice : ContiguousBytes where Element == UInt8 { }
@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension ContiguousArray : ContiguousBytes where Element == UInt8 { }

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension Data : ContiguousBytes { }

//===--- Pointer Conformances ---------------------------------------------===//

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
Expand Down
52 changes: 51 additions & 1 deletion Sources/FoundationEssentials/Data/Data+Base64.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2023-2024 Apple Inc. and the Swift project authors
// Copyright (c) 2023-2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand All @@ -25,6 +25,56 @@ import WinSDK
import WASILibc
#endif

#if !FOUNDATION_FRAMEWORK
extension Data {

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
public struct Base64EncodingOptions : OptionSet, Sendable {
public let rawValue: UInt

public init(rawValue: UInt) {
self.rawValue = rawValue
}
/// Set the maximum line length to 64 characters, after which a line ending is inserted.
public static let lineLength64Characters = Base64EncodingOptions(rawValue: 1 << 0)
/// Set the maximum line length to 76 characters, after which a line ending is inserted.
public static let lineLength76Characters = Base64EncodingOptions(rawValue: 1 << 1)
/// When a maximum line length is set, specify that the line ending to insert should include a carriage return.
public static let endLineWithCarriageReturn = Base64EncodingOptions(rawValue: 1 << 4)
/// When a maximum line length is set, specify that the line ending to insert should include a line feed.
public static let endLineWithLineFeed = Base64EncodingOptions(rawValue: 1 << 5)
}

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
public struct Base64DecodingOptions : OptionSet, Sendable {
public let rawValue: UInt

public init(rawValue: UInt) {
self.rawValue = rawValue
}
/// Modify the decoding algorithm so that it ignores unknown non-Base-64 bytes, including line ending characters.
public static let ignoreUnknownCharacters = Base64DecodingOptions(rawValue: 1 << 0)
}
}
#else
@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension Data {
// These types are typealiased to the `NSData` options for framework builds only.
public typealias Base64EncodingOptions = NSData.Base64EncodingOptions
public typealias Base64DecodingOptions = NSData.Base64DecodingOptions
}
#endif //!FOUNDATION_FRAMEWORK

extension Data.Base64EncodingOptions {
/// Use the base64url alphabet to encode the data
@available(FoundationPreview 6.3, *)
public static let base64URLAlphabet = Self(rawValue: 1 << 6)

/// Omit the `=` padding characters in the end of the base64 encoded result
@available(FoundationPreview 6.3, *)
public static let omitPaddingCharacter = Self(rawValue: 1 << 7)
}

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension Data {

Expand Down
119 changes: 119 additions & 0 deletions Sources/FoundationEssentials/Data/Data+Bridging.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

#if FOUNDATION_FRAMEWORK

internal import _ForSwiftFoundation

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension __DataStorage {
@inline(never) // This is not @inlinable to avoid emission of the private `__NSSwiftData` class name into clients.
@usableFromInline
func bridgedReference(_ range: Range<Int>) -> AnyObject {
if range.isEmpty {
return NSData() // zero length data can be optimized as a singleton
}

return __NSSwiftData(backing: self, range: range)
}
}

// NOTE: older overlays called this _NSSwiftData. The two must
// coexist, so it was renamed. The old name must not be used in the new
// runtime.
internal final class __NSSwiftData : NSData {
var _backing: __DataStorage!
var _range: Range<Data.Index>!

convenience init(backing: __DataStorage, range: Range<Data.Index>) {
self.init()
_backing = backing
_range = range
}
@objc override var length: Int {
return _range.upperBound - _range.lowerBound
}

@objc override var bytes: UnsafeRawPointer {
// NSData's byte pointer methods are not annotated for nullability correctly
// (but assume non-null by the wrapping macro guards). This placeholder value
// is to work-around this bug. Any indirection to the underlying bytes of an NSData
// with a length of zero would have been a programmer error anyhow so the actual
// return value here is not needed to be an allocated value. This is specifically
// needed to live like this to be source compatible with Swift3. Beyond that point
// this API may be subject to correction.
guard let bytes = _backing.bytes else {
return UnsafeRawPointer(bitPattern: 0xBAD0)!
}

return bytes.advanced(by: _range.lowerBound)
}

@objc override func copy(with zone: NSZone? = nil) -> Any {
if _backing._copyWillRetain {
return self
} else {
return NSData(bytes: bytes, length: length)
}

}

@objc override func mutableCopy(with zone: NSZone? = nil) -> Any {
return NSMutableData(bytes: bytes, length: length)
}

@objc override
func _isCompact() -> Bool {
return true
}

@objc override
func _bridgingCopy(_ bytes: UnsafeMutablePointer<UnsafeRawPointer?>, length: UnsafeMutablePointer<Int>) -> Data? {
fatalError("Unexpected call to __NSSwiftData._bridgingCopy(_:length:)")
}
}

extension Data {
internal func _bridgeToObjectiveCImpl() -> AnyObject {
switch _representation {
case .empty: return NSData()
case .inline(let inline):
return inline.withUnsafeBytes {
return NSData(bytes: $0.baseAddress, length: $0.count)
}
case .slice(let slice):
return slice.storage.bridgedReference(slice.range)
case .large(let slice):
return slice.storage.bridgedReference(slice.range)
}
}

internal static func _bridgeFromObjectiveCAdoptingNativeStorageOf(_ source: AnyObject) -> Data? {
guard object_getClass(source) == __NSSwiftData.self else { return nil }

let swiftData = unsafeDowncast(source, to: __NSSwiftData.self)
let range = swiftData._range!
let originalBacking = swiftData._backing!

// (rdar://162776451) Some clients assume that the double-bridged Data's start index is 0 due to historical behavior. We need to make sure the created Data's indices begin at 0 rather than preserving the original offset/slice range here. This requires creating a new __DataStorage instead of using the existing one.
// (rdar://121865256) We also need to make sure that we don't create a new __DataStorage that holds on to the original via the deallocator. If a value is double bridged repeatedly (as is the case in some clients), unwinding in the dealloc can cause a stack overflow. This requires either using the existing __DataStorage, or creating a new one with a copy of the bytes to avoid a deallocator chain.
// Based on the two constraints above, we perform a copy here. Ideally in the future if we remove the first constraint we could re-use the existing originalBacking to avoid the copy.
let newBacking = __DataStorage(bytes: originalBacking.mutableBytes?.advanced(by: range.lowerBound), length: range.count)

if InlineSlice.canStore(count: newBacking.length) {
return Data(representation: .slice(InlineSlice(newBacking, count: newBacking.length)))
} else {
return Data(representation: .large(LargeSlice(newBacking, count: newBacking.length)))
}
}
}

#endif
63 changes: 63 additions & 0 deletions Sources/FoundationEssentials/Data/Data+Deprecated.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension Data {
@available(swift, introduced: 4.2)
@available(swift, deprecated: 5, message: "use `init(_:)` instead")
public init<S: Sequence>(bytes elements: S) where S.Iterator.Element == UInt8 {
self.init(elements)
}

@available(swift, obsoleted: 4.2)
public init(bytes: Array<UInt8>) {
self.init(bytes)
}

@available(swift, obsoleted: 4.2)
public init(bytes: ArraySlice<UInt8>) {
self.init(bytes)
}

/// Access the bytes in the data.
///
/// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.
@available(swift, deprecated: 5, message: "use `withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R` instead")
public func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
return try self.withUnsafeBytes {
return try body($0.baseAddress?.assumingMemoryBound(to: ContentType.self) ?? UnsafePointer<ContentType>(bitPattern: 0xBAD0)!)
}
}

/// Mutate the bytes in the data.
///
/// This function assumes that you are mutating the contents.
/// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.
@available(swift, deprecated: 5, message: "use `withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R` instead")
public mutating func withUnsafeMutableBytes<ResultType, ContentType>(_ body: (UnsafeMutablePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
return try self.withUnsafeMutableBytes {
return try body($0.baseAddress?.assumingMemoryBound(to: ContentType.self) ?? UnsafeMutablePointer<ContentType>(bitPattern: 0xBAD0)!)
}
}

/// Enumerate the contents of the data.
///
/// In some cases, (for example, a `Data` backed by a `dispatch_data_t`, the bytes may be stored discontinuously. In those cases, this function invokes the closure for each contiguous region of bytes.
/// - parameter block: The closure to invoke for each region of data. You may stop the enumeration by setting the `stop` parameter to `true`.
@available(swift, deprecated: 5, message: "use `regions` or `for-in` instead")
public func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Index, _ stop: inout Bool) -> Void) {
self.withUnsafeBytes {
var stop = false
block($0.assumingMemoryBound(to: UInt8.self), 0, &stop)
}
}
}
Loading