Skip to content

Commit 34fb920

Browse files
committed
Merge branch 'master' of https://github.com/apple/swift-corelibs-foundation into URLResponse-NSCoding
2 parents 059b68a + df27829 commit 34fb920

13 files changed

+433
-55
lines changed

CoreFoundation/Locale.subproj/CFLocale.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,12 @@ static CFLocaleRef __CFLocaleCurrent = NULL;
280280

281281

282282
#if DEPLOYMENT_TARGET_MACOSX
283+
// Specify a default locale on Mac for Swift
284+
#if DEPLOYMENT_RUNTIME_SWIFT
285+
#define FALLBACK_LOCALE_NAME CFSTR("en_US")
286+
#else
283287
#define FALLBACK_LOCALE_NAME CFSTR("")
288+
#endif /* DEPLOYMENT_RUNTIME_SWIFT */
284289
#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
285290
#define FALLBACK_LOCALE_NAME CFSTR("en_US")
286291
#elif DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD

Docs/Status.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ There is no _Complete_ status for test coverage because there are always additio
5353
| `URLProtectionSpace` | Unimplemented | None | |
5454
| `URLProtocol` | Unimplemented | None | |
5555
| `URLProtocolClient` | Unimplemented | None | |
56-
| `NSURLRequest` | Mostly Complete | Incomplete | `NSCoding` remains unimplemented |
57-
| `NSMutableURLRequest` | Mostly Complete | Incomplete | `NSCoding` remains unimplemented |
56+
| `NSURLRequest` | Mostly Complete | Incomplete | |
57+
| `NSMutableURLRequest` | Mostly Complete | Incomplete | |
5858
| `URLResponse` | Mostly Complete | Incomplete | |
5959
| `NSHTTPURLResponse` | Mostly Complete | Substantial | |
6060
| `NSURL` | Mostly Complete | Substantial | `NSCoding` with non-keyed-coding archivers, `checkResourceIsReachable()`, and resource values remain unimplemented |

Foundation/NSData.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,12 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
217217
}
218218

219219
open var bytes: UnsafeRawPointer {
220-
return UnsafeRawPointer(CFDataGetBytePtr(_cfObject))
220+
guard let bytePtr = CFDataGetBytePtr(_cfObject) else {
221+
//This could occure on empty data being encoded.
222+
//TODO: switch with nil when signature is fixed
223+
return UnsafeRawPointer(bitPattern: 0xf00deadb0c0)! //would not result in 'nil unwrapped optional'
224+
}
225+
return UnsafeRawPointer(bytePtr)
221226
}
222227

223228

Foundation/NSJSONSerialization.swift

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,21 +270,21 @@ private struct JSONWriter {
270270
}
271271

272272
mutating func serializeJSON(_ obj: Any) throws {
273-
274-
if let str = obj as? String {
273+
274+
switch (obj) {
275+
case let str as String:
275276
try serializeString(str)
276-
} else if let num = _SwiftValue.store(obj) as? NSNumber {
277-
try serializeNumber(num)
278-
} else if let array = obj as? Array<Any> {
277+
case let boolValue as Bool:
278+
serializeBool(boolValue)
279+
case _ where _SwiftValue.store(obj) is NSNumber:
280+
try serializeNumber(_SwiftValue.store(obj) as! NSNumber)
281+
case let array as Array<Any>:
279282
try serializeArray(array)
280-
} else if let dict = obj as? Dictionary<AnyHashable, Any> {
283+
case let dict as Dictionary<AnyHashable, Any>:
281284
try serializeDictionary(dict)
282-
} else if let null = obj as? NSNull {
285+
case let null as NSNull:
283286
try serializeNull(null)
284-
} else if let boolVal = obj as? Bool {
285-
try serializeNumber(NSNumber(value: boolVal))
286-
}
287-
else {
287+
default:
288288
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Invalid object cannot be serialized"])
289289
}
290290
}
@@ -319,15 +319,26 @@ private struct JSONWriter {
319319
writer("\"")
320320
}
321321

322+
func serializeBool(_ bool: Bool) {
323+
switch bool {
324+
case true:
325+
writer("true")
326+
case false:
327+
writer("false")
328+
}
329+
}
330+
322331
mutating func serializeNumber(_ num: NSNumber) throws {
323332
if num.doubleValue.isInfinite || num.doubleValue.isNaN {
324333
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Number cannot be infinity or NaN"])
325334
}
326335

327-
// Cannot detect type information (e.g. bool) as there is no objCType property on NSNumber in Swift
328-
// So, just print the number
329-
330-
writer(_serializationString(for: num))
336+
switch num._objCType {
337+
case .Bool:
338+
serializeBool(num.boolValue)
339+
default:
340+
writer(_serializationString(for: num))
341+
}
331342
}
332343

333344
mutating func serializeArray(_ array: [Any]) throws {

Foundation/NSNumber.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@ open class NSNumber : NSValue {
200200
// This layout MUST be the same as CFNumber so that they are bridgeable
201201
private var _base = _CFInfo(typeID: CFNumberGetTypeID())
202202
private var _pad: UInt64 = 0
203-
203+
204+
internal let _objCType: _NSSimpleObjCType
205+
204206
internal var _cfObject: CFType {
205207
return unsafeBitCast(self, to: CFType.self)
206208
}
@@ -221,77 +223,95 @@ open class NSNumber : NSValue {
221223
}
222224
return false
223225
}
226+
227+
open override var objCType: UnsafePointer<Int8> {
228+
return UnsafePointer<Int8>(bitPattern: UInt(_objCType.rawValue.value))!
229+
}
224230

225231
deinit {
226232
_CFDeinit(self)
227233
}
228234

229235
public init(value: Int8) {
236+
_objCType = .Char
230237
super.init()
231238
_CFNumberInitInt8(_cfObject, value)
232239
}
233240

234241
public init(value: UInt8) {
242+
_objCType = .UChar
235243
super.init()
236244
_CFNumberInitUInt8(_cfObject, value)
237245
}
238246

239247
public init(value: Int16) {
248+
_objCType = .Short
240249
super.init()
241250
_CFNumberInitInt16(_cfObject, value)
242251
}
243252

244253
public init(value: UInt16) {
254+
_objCType = .UShort
245255
super.init()
246256
_CFNumberInitUInt16(_cfObject, value)
247257
}
248258

249259
public init(value: Int32) {
260+
_objCType = .Long
250261
super.init()
251262
_CFNumberInitInt32(_cfObject, value)
252263
}
253264

254265
public init(value: UInt32) {
266+
_objCType = .ULong
255267
super.init()
256268
_CFNumberInitUInt32(_cfObject, value)
257269
}
258270

259271
public init(value: Int) {
272+
_objCType = .Int
260273
super.init()
261274
_CFNumberInitInt(_cfObject, value)
262275
}
263276

264277
public init(value: UInt) {
278+
_objCType = .UInt
265279
super.init()
266280
_CFNumberInitUInt(_cfObject, value)
267281
}
268282

269283
public init(value: Int64) {
284+
_objCType = .LongLong
270285
super.init()
271286
_CFNumberInitInt64(_cfObject, value)
272287
}
273288

274289
public init(value: UInt64) {
290+
_objCType = .ULongLong
275291
super.init()
276292
_CFNumberInitUInt64(_cfObject, value)
277293
}
278294

279295
public init(value: Float) {
296+
_objCType = .Float
280297
super.init()
281298
_CFNumberInitFloat(_cfObject, value)
282299
}
283300

284301
public init(value: Double) {
302+
_objCType = .Double
285303
super.init()
286304
_CFNumberInitDouble(_cfObject, value)
287305
}
288306

289307
public init(value: Bool) {
308+
_objCType = .Bool
290309
super.init()
291310
_CFNumberInitBool(_cfObject, value)
292311
}
293312

294313
override internal init() {
314+
_objCType = .Undef
295315
super.init()
296316
}
297317

Foundation/NSNumberFormatter.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ open class NumberFormatter : Formatter {
7070

7171
let obj = CFNumberFormatterCreate(kCFAllocatorSystemDefault, locale._cfObject, numberStyle)!
7272
_setFormatterAttributes(obj)
73+
if let format = _format {
74+
CFNumberFormatterSetFormat(obj, format._cfObject)
75+
}
7376
_currentCfFormatter = obj
7477
return obj
7578
}
@@ -99,12 +102,13 @@ open class NumberFormatter : Formatter {
99102
open func number(from string: String) -> NSNumber? {
100103
var range = CFRange(location: 0, length: string.length)
101104
let number = withUnsafeMutablePointer(to: &range) { (rangePointer: UnsafeMutablePointer<CFRange>) -> NSNumber? in
102-
105+
103106
#if os(OSX) || os(iOS)
104-
let result = CFNumberFormatterCreateNumberFromString(kCFAllocatorSystemDefault, _cfFormatter, string._cfObject, rangePointer, CFNumberFormatterOptionFlags.parseIntegersOnly.rawValue)
107+
let parseOption = allowsFloats ? 0 : CFNumberFormatterOptionFlags.parseIntegersOnly.rawValue
105108
#else
106-
let result = CFNumberFormatterCreateNumberFromString(kCFAllocatorSystemDefault, _cfFormatter, string._cfObject, rangePointer, CFOptionFlags(kCFNumberFormatterParseIntegersOnly))
109+
let parseOption = allowsFloats ? 0 : CFOptionFlags(kCFNumberFormatterParseIntegersOnly)
107110
#endif
111+
let result = CFNumberFormatterCreateNumberFromString(kCFAllocatorSystemDefault, _cfFormatter, string._cfObject, rangePointer, parseOption)
108112

109113
return result?._nsObject
110114
}
@@ -157,7 +161,7 @@ open class NumberFormatter : Formatter {
157161
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterPerMillSymbol, value: _percentSymbol?._cfObject)
158162
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterInternationalCurrencySymbol, value: _internationalCurrencySymbol?._cfObject)
159163
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencyGroupingSeparator, value: _currencyGroupingSeparator?._cfObject)
160-
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterIsLenient, value: kCFBooleanTrue)
164+
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterIsLenient, value: _lenient._cfObject)
161165
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterUseSignificantDigits, value: _usesSignificantDigits._cfObject)
162166
if _usesSignificantDigits {
163167
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinSignificantDigits, value: _minimumSignificantDigits._bridgeToObjectiveC()._cfObject)
@@ -182,7 +186,7 @@ open class NumberFormatter : Formatter {
182186
switch newValue {
183187
case .none, .ordinal, .spellOut:
184188
_usesSignificantDigits = false
185-
189+
186190
case .currency, .currencyPlural, .currencyISOCode, .currencyAccounting:
187191
_usesSignificantDigits = false
188192
_usesGroupingSeparator = true
@@ -838,10 +842,10 @@ open class NumberFormatter : Formatter {
838842

839843
//
840844

841-
internal var _format: String = "#;0;#"
845+
internal var _format: String?
842846
open var format: String {
843847
get {
844-
return _format
848+
return _format ?? "#;0;#"
845849
}
846850
set {
847851
_reset()

Foundation/NSPredicate.swift

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ open class NSPredicate : NSObject, NSSecureCoding, NSCopying {
1515
private enum PredicateKind {
1616
case boolean(Bool)
1717
case block((Any?, [String : Any]?) -> Bool)
18-
// TODO: case for init(format:argumentArray:)
19-
// TODO: case for init(fromMetadataQueryString:)
18+
case format(String)
19+
case metadataQuery(String)
2020
}
2121

2222
private let kind: PredicateKind
@@ -26,19 +26,72 @@ open class NSPredicate : NSObject, NSSecureCoding, NSCopying {
2626
}
2727

2828
public required init?(coder aDecoder: NSCoder) {
29-
NSUnimplemented()
29+
guard aDecoder.allowsKeyedCoding else {
30+
preconditionFailure("Unkeyed coding is unsupported.")
31+
}
32+
33+
let encodedBool = aDecoder.decodeBool(forKey: "NS.boolean.value")
34+
self.kind = .boolean(encodedBool)
35+
36+
super.init()
3037
}
3138

3239
open func encode(with aCoder: NSCoder) {
33-
NSUnimplemented()
40+
guard aCoder.allowsKeyedCoding else {
41+
preconditionFailure("Unkeyed coding is unsupported.")
42+
}
43+
44+
//TODO: store kind key for .boolean, .format, .metadataQuery
45+
46+
switch self.kind {
47+
case .boolean(let value):
48+
aCoder.encode(value, forKey: "NS.boolean.value")
49+
case .block:
50+
preconditionFailure("NSBlockPredicate cannot be encoded or decoded.")
51+
case .format:
52+
NSUnimplemented()
53+
case .metadataQuery:
54+
NSUnimplemented()
55+
}
3456
}
3557

3658
open override func copy() -> Any {
3759
return copy(with: nil)
3860
}
3961

4062
open func copy(with zone: NSZone? = nil) -> Any {
41-
NSUnimplemented()
63+
switch self.kind {
64+
case .boolean(let value):
65+
return NSPredicate(value: value)
66+
case .block(let block):
67+
return NSPredicate(block: block)
68+
case .format:
69+
NSUnimplemented()
70+
case .metadataQuery:
71+
NSUnimplemented()
72+
}
73+
}
74+
75+
open override func isEqual(_ object: Any?) -> Bool {
76+
if let other = object as? NSPredicate {
77+
if other === self {
78+
return true
79+
} else {
80+
switch (other.kind, self.kind) {
81+
case (.boolean(let otherBool), .boolean(let selfBool)):
82+
return otherBool == selfBool
83+
case (.format, .format):
84+
NSUnimplemented()
85+
case (.metadataQuery, .metadataQuery):
86+
NSUnimplemented()
87+
default:
88+
// NSBlockPredicate returns false even for copy
89+
return false
90+
}
91+
}
92+
}
93+
94+
return false
4295
}
4396

4497
// Parse predicateFormat and return an appropriate predicate
@@ -58,7 +111,21 @@ open class NSPredicate : NSObject, NSSecureCoding, NSCopying {
58111
super.init()
59112
}
60113

61-
open var predicateFormat: String { NSUnimplemented() } // returns the format string of the predicate
114+
open var predicateFormat: String {
115+
switch self.kind {
116+
case .boolean(let value):
117+
return value ? "TRUEPREDICATE" : "FALSEPREDICATE"
118+
case .block:
119+
// TODO: Bring NSBlockPredicate's predicateFormat to macOS's Foundation version
120+
// let address = unsafeBitCast(block, to: Int.self)
121+
// return String(format:"BLOCKPREDICATE(%2X)", address)
122+
return "BLOCKPREDICATE"
123+
case .format:
124+
NSUnimplemented()
125+
case .metadataQuery:
126+
NSUnimplemented()
127+
}
128+
}
62129

63130
open func withSubstitutionVariables(_ variables: [String : Any]) -> Self { NSUnimplemented() } // substitute constant values for variables
64131

@@ -76,6 +143,10 @@ open class NSPredicate : NSObject, NSSecureCoding, NSCopying {
76143
return value
77144
case let .block(block):
78145
return block(object, bindings)
146+
case .format:
147+
NSUnimplemented()
148+
case .metadataQuery:
149+
NSUnimplemented()
79150
}
80151
} // single pass evaluation substituting variables from the bindings dictionary for any variable expressions encountered
81152

0 commit comments

Comments
 (0)