Skip to content

Commit e09e811

Browse files
committed
Build FoundationNetworking
1 parent 9fc5349 commit e09e811

27 files changed

+291
-40
lines changed

Package.swift

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ let buildSettings: [CSetting] = [
3535
.unsafeFlags(["-I/usr/lib/swift"], .when(platforms: [.linux, .android])) // dispatch
3636
]
3737

38-
let xmlInterfaceBuildSettings: [CSetting] = [
38+
// For _CFURLSessionInterface, _CFXMLInterface
39+
let interfaceBuildSettings: [CSetting] = [
3940
.headerSearchPath("../CoreFoundation/internalInclude"),
4041
.headerSearchPath("../CoreFoundation/include"),
4142
.define("DEBUG", .when(configuration: .debug)),
@@ -95,12 +96,24 @@ let package = Package(
9596
name: "FoundationXML",
9697
dependencies: [
9798
.product(name: "FoundationEssentials", package: "swift-foundation"),
99+
"Foundation",
98100
"CoreFoundationPackage",
99-
"CFXMLInterface"
101+
"_CFXMLInterface"
100102
],
101103
path: "Sources/FoundationXML",
102104
swiftSettings: [.define("DEPLOYMENT_RUNTIME_SWIFT")]
103105
),
106+
.target(
107+
name: "FoundationNetworking",
108+
dependencies: [
109+
.product(name: "FoundationEssentials", package: "swift-foundation"),
110+
"Foundation",
111+
"CoreFoundationPackage",
112+
"_CFURLSessionInterface"
113+
],
114+
path: "Sources/FoundationNetworking",
115+
swiftSettings: [.define("DEPLOYMENT_RUNTIME_SWIFT")]
116+
),
104117
.target(
105118
name: "CoreFoundationPackage",
106119
dependencies: [
@@ -111,13 +124,22 @@ let package = Package(
111124
cSettings: buildSettings
112125
),
113126
.target(
114-
name: "CFXMLInterface",
127+
name: "_CFXMLInterface",
115128
dependencies: [
116129
"CoreFoundationPackage",
117130
"Clibxml2",
118131
],
119-
path: "Sources/CFXMLInterface",
120-
cSettings: xmlInterfaceBuildSettings
132+
path: "Sources/_CFXMLInterface",
133+
cSettings: interfaceBuildSettings
134+
),
135+
.target(
136+
name: "_CFURLSessionInterface",
137+
dependencies: [
138+
"CoreFoundationPackage",
139+
"Clibcurl",
140+
],
141+
path: "Sources/_CFURLSessionInterface",
142+
cSettings: interfaceBuildSettings
121143
),
122144
.systemLibrary(
123145
name: "Clibxml2",

Sources/CFXMLInterface/module.map

Lines changed: 0 additions & 3 deletions
This file was deleted.

Sources/CoreFoundation/url-module.map

Lines changed: 0 additions & 3 deletions
This file was deleted.

Sources/Foundation/Boxing.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if NS_BUILDING_FOUNDATION_NETWORKING
14-
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
15-
import SwiftFoundation
16-
#else
17-
import Foundation
18-
#endif
19-
#endif
13+
// This file is for internal use of Foundation
2014

2115
/// A class type which acts as a handle (pointer-to-pointer) to a Foundation reference type which has only a mutable class (e.g., NSURLComponents).
2216
///
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// This file is for internal use of FoundationNetworking
14+
15+
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
16+
import SwiftFoundation
17+
#else
18+
import Foundation
19+
#endif
20+
21+
/// A class type which acts as a handle (pointer-to-pointer) to a Foundation reference type which has only a mutable class (e.g., NSURLComponents).
22+
///
23+
/// Note: This assumes that the result of calling copy() is mutable. The documentation says that classes which do not have a mutable/immutable distinction should just adopt NSCopying instead of NSMutableCopying.
24+
internal final class _MutableHandle<MutableType : NSObject> where MutableType : NSCopying {
25+
@usableFromInline internal var _pointer : MutableType
26+
27+
init(reference : MutableType) {
28+
_pointer = reference.copy() as! MutableType
29+
}
30+
31+
init(adoptingReference reference: MutableType) {
32+
_pointer = reference
33+
}
34+
35+
/// Apply a closure to the reference type.
36+
func map<ReturnType>(_ whatToDo : (MutableType) throws -> ReturnType) rethrows -> ReturnType {
37+
return try whatToDo(_pointer)
38+
}
39+
40+
func _copiedReference() -> MutableType {
41+
return _pointer.copy() as! MutableType
42+
}
43+
44+
func _uncopiedReference() -> MutableType {
45+
return _pointer
46+
}
47+
}
48+
49+
/// Describes common operations for Foundation struct types that are bridged to a mutable object (e.g. NSURLComponents).
50+
internal protocol _MutableBoxing : ReferenceConvertible {
51+
var _handle : _MutableHandle<ReferenceType> { get set }
52+
53+
/// Apply a mutating closure to the reference type, regardless if it is mutable or immutable.
54+
///
55+
/// This function performs the correct copy-on-write check for efficient mutation.
56+
mutating func _applyMutation<ReturnType>(_ whatToDo : (ReferenceType) -> ReturnType) -> ReturnType
57+
}
58+
59+
extension _MutableBoxing {
60+
@inline(__always)
61+
mutating func _applyMutation<ReturnType>(_ whatToDo : (ReferenceType) -> ReturnType) -> ReturnType {
62+
// Only create a new box if we are not uniquely referenced
63+
if !isKnownUniquelyReferenced(&_handle) {
64+
let ref = _handle._pointer
65+
_handle = _MutableHandle(reference: ref)
66+
}
67+
return whatToDo(_handle._pointer)
68+
}
69+
}
70+
71+
internal enum _MutableUnmanagedWrapper<ImmutableType : NSObject, MutableType : NSObject> where MutableType : NSMutableCopying {
72+
case Immutable(Unmanaged<ImmutableType>)
73+
case Mutable(Unmanaged<MutableType>)
74+
}
75+
76+
internal protocol _SwiftNativeFoundationType: AnyObject {
77+
associatedtype ImmutableType : NSObject
78+
associatedtype MutableType : NSObject, NSMutableCopying
79+
var __wrapped : _MutableUnmanagedWrapper<ImmutableType, MutableType> { get }
80+
81+
init(unmanagedImmutableObject: Unmanaged<ImmutableType>)
82+
init(unmanagedMutableObject: Unmanaged<MutableType>)
83+
84+
func mutableCopy(with zone : NSZone) -> Any
85+
86+
func hash(into hasher: inout Hasher)
87+
var hashValue: Int { get }
88+
89+
var description: String { get }
90+
var debugDescription: String { get }
91+
92+
func releaseWrappedObject()
93+
}
94+
95+
extension _SwiftNativeFoundationType {
96+
97+
@inline(__always)
98+
func _mapUnmanaged<ReturnType>(_ whatToDo : (ImmutableType) throws -> ReturnType) rethrows -> ReturnType {
99+
defer { _fixLifetime(self) }
100+
101+
switch __wrapped {
102+
case .Immutable(let i):
103+
return try i._withUnsafeGuaranteedRef {
104+
_onFastPath()
105+
return try whatToDo($0)
106+
}
107+
case .Mutable(let m):
108+
return try m._withUnsafeGuaranteedRef {
109+
_onFastPath()
110+
return try whatToDo(_unsafeReferenceCast($0, to: ImmutableType.self))
111+
}
112+
}
113+
}
114+
115+
func releaseWrappedObject() {
116+
switch __wrapped {
117+
case .Immutable(let i):
118+
i.release()
119+
case .Mutable(let m):
120+
m.release()
121+
}
122+
}
123+
124+
func mutableCopy(with zone : NSZone) -> Any {
125+
return _mapUnmanaged { ($0 as NSObject).mutableCopy() }
126+
}
127+
128+
func hash(into hasher: inout Hasher) {
129+
_mapUnmanaged { hasher.combine($0) }
130+
}
131+
132+
var hashValue: Int {
133+
return _mapUnmanaged { return $0.hashValue }
134+
}
135+
136+
var description: String {
137+
return _mapUnmanaged { return $0.description }
138+
}
139+
140+
var debugDescription: String {
141+
return _mapUnmanaged { return $0.debugDescription }
142+
}
143+
144+
func isEqual(_ other: AnyObject) -> Bool {
145+
return _mapUnmanaged { return $0.isEqual(other) }
146+
}
147+
}
148+
149+
internal protocol _MutablePairBoxing {
150+
associatedtype WrappedSwiftNSType : _SwiftNativeFoundationType
151+
var _wrapped : WrappedSwiftNSType { get set }
152+
}
153+
154+
extension _MutablePairBoxing {
155+
@inline(__always)
156+
func _mapUnmanaged<ReturnType>(_ whatToDo : (WrappedSwiftNSType.ImmutableType) throws -> ReturnType) rethrows -> ReturnType {
157+
// We are using Unmanaged. Make sure that the owning container class
158+
// 'self' is guaranteed to be alive by extending the lifetime of 'self'
159+
// to the end of the scope of this function.
160+
// Note: At the time of this writing using withExtendedLifetime here
161+
// instead of _fixLifetime causes different ARC pair matching behavior
162+
// foiling optimization. This is why we explicitly use _fixLifetime here
163+
// instead.
164+
defer { _fixLifetime(self) }
165+
166+
let unmanagedHandle = Unmanaged.passUnretained(_wrapped)
167+
let wrapper = unmanagedHandle._withUnsafeGuaranteedRef { $0.__wrapped }
168+
switch (wrapper) {
169+
case .Immutable(let i):
170+
return try i._withUnsafeGuaranteedRef {
171+
return try whatToDo($0)
172+
}
173+
case .Mutable(let m):
174+
return try m._withUnsafeGuaranteedRef {
175+
return try whatToDo(_unsafeReferenceCast($0, to: WrappedSwiftNSType.ImmutableType.self))
176+
}
177+
}
178+
}
179+
180+
@inline(__always)
181+
mutating func _applyUnmanagedMutation<ReturnType>(_ whatToDo : (WrappedSwiftNSType.MutableType) throws -> ReturnType) rethrows -> ReturnType {
182+
// We are using Unmanaged. Make sure that the owning container class
183+
// 'self' is guaranteed to be alive by extending the lifetime of 'self'
184+
// to the end of the scope of this function.
185+
// Note: At the time of this writing using withExtendedLifetime here
186+
// instead of _fixLifetime causes different ARC pair matching behavior
187+
// foiling optimization. This is why we explicitly use _fixLifetime here
188+
// instead.
189+
defer { _fixLifetime(self) }
190+
191+
var unique = true
192+
let _unmanagedHandle = Unmanaged.passUnretained(_wrapped)
193+
let wrapper = _unmanagedHandle._withUnsafeGuaranteedRef { $0.__wrapped }
194+
195+
// This check is done twice because: <rdar://problem/24939065> Value kept live for too long causing uniqueness check to fail
196+
switch (wrapper) {
197+
case .Immutable:
198+
break
199+
case .Mutable:
200+
unique = isKnownUniquelyReferenced(&_wrapped)
201+
}
202+
203+
switch (wrapper) {
204+
case .Immutable(let i):
205+
// We need to become mutable; by creating a new instance we also become unique
206+
let copy = Unmanaged.passRetained(i._withUnsafeGuaranteedRef {
207+
return _unsafeReferenceCast($0.mutableCopy(), to: WrappedSwiftNSType.MutableType.self) }
208+
)
209+
210+
// Be sure to set the var before calling out; otherwise references to the struct in the closure may be looking at the old value
211+
_wrapped = WrappedSwiftNSType(unmanagedMutableObject: copy)
212+
return try copy._withUnsafeGuaranteedRef {
213+
_onFastPath()
214+
return try whatToDo($0)
215+
}
216+
case .Mutable(let m):
217+
// Only create a new box if we are not uniquely referenced
218+
if !unique {
219+
let copy = Unmanaged.passRetained(m._withUnsafeGuaranteedRef {
220+
return _unsafeReferenceCast($0.mutableCopy(), to: WrappedSwiftNSType.MutableType.self)
221+
})
222+
_wrapped = WrappedSwiftNSType(unmanagedMutableObject: copy)
223+
return try copy._withUnsafeGuaranteedRef {
224+
_onFastPath()
225+
return try whatToDo($0)
226+
}
227+
} else {
228+
return try m._withUnsafeGuaranteedRef {
229+
_onFastPath()
230+
return try whatToDo($0)
231+
}
232+
}
233+
}
234+
}
235+
}

Sources/FoundationNetworking/URLCache.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class StoredCachedURLResponse: NSObject, NSSecureCoding {
5252

5353
func encode(with aCoder: NSCoder) {
5454
aCoder.encode(cachedURLResponse.response, forKey: "response")
55-
aCoder.encode(cachedURLResponse.data as NSData, forKey: "data")
55+
aCoder.encode(cachedURLResponse.data._bridgeToObjectiveC(), forKey: "data")
5656
aCoder.encode(Int(bitPattern: cachedURLResponse.storagePolicy.rawValue), forKey: "storagePolicy")
5757
aCoder.encode(cachedURLResponse.userInfo as NSDictionary?, forKey: "userInfo")
5858
aCoder.encode(cachedURLResponse.date as NSDate, forKey: "date")
@@ -68,7 +68,7 @@ class StoredCachedURLResponse: NSObject, NSSecureCoding {
6868

6969
let userInfo = aDecoder.decodeObject(of: NSDictionary.self, forKey: "userInfo") as? [AnyHashable: Any]
7070

71-
cachedURLResponse = CachedURLResponse(response: response, data: data as Data, userInfo: userInfo, storagePolicy: storagePolicy)
71+
cachedURLResponse = CachedURLResponse(response: response, data: Data(data), userInfo: userInfo, storagePolicy: storagePolicy)
7272
cachedURLResponse.date = date as Date
7373
}
7474

Sources/FoundationNetworking/URLSession/BodySource.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Foundation
2323
#endif
2424

2525
@_implementationOnly import CoreFoundation
26-
@_implementationOnly import CFURLSessionInterface
26+
@_implementationOnly import _CFURLSessionInterface
2727
import Dispatch
2828

2929

Sources/FoundationNetworking/URLSession/HTTP/HTTPURLProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Foundation
1414
#endif
1515

1616
@_implementationOnly import CoreFoundation
17-
@_implementationOnly import CFURLSessionInterface
17+
@_implementationOnly import _CFURLSessionInterface
1818
import Dispatch
1919

2020
internal class _HTTPURLProtocol: _NativeProtocol {

Sources/FoundationNetworking/URLSession/NetworkingSpecific.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class _NSNonfileURLContentLoader: _NSNonfileURLContentLoading {
8585
switch statusCode {
8686
// These are the only valid response codes that data will be returned for, all other codes will be treated as error.
8787
case 101, 200...399, 401, 407:
88-
return (data as NSData, urlResponse?.textEncodingName)
88+
return (NSData(data: data), urlResponse?.textEncodingName)
8989

9090
default:
9191
break

Sources/FoundationNetworking/URLSession/WebSocket/WebSocketURLProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Foundation
1414
#endif
1515

1616
@_implementationOnly import CoreFoundation
17-
@_implementationOnly import CFURLSessionInterface
17+
@_implementationOnly import _CFURLSessionInterface
1818
import Dispatch
1919

2020
internal class _WebSocketURLProtocol: _HTTPURLProtocol {

Sources/FoundationNetworking/URLSession/libcurl/EasyHandle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Foundation
2424
#endif
2525

2626
@_implementationOnly import CoreFoundation
27-
@_implementationOnly import CFURLSessionInterface
27+
@_implementationOnly import _CFURLSessionInterface
2828
import Dispatch
2929

3030

Sources/FoundationNetworking/URLSession/libcurl/MultiHandle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Foundation
2323
#endif
2424

2525
@_implementationOnly import CoreFoundation
26-
@_implementationOnly import CFURLSessionInterface
26+
@_implementationOnly import _CFURLSessionInterface
2727
import Dispatch
2828

2929

0 commit comments

Comments
 (0)