Merge pull request #1204 from ianpartridge/nsnumber-se-0170
diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c
index 6dd5564..896193f 100644
--- a/CoreFoundation/Base.subproj/CFPlatform.c
+++ b/CoreFoundation/Base.subproj/CFPlatform.c
@@ -1301,7 +1301,7 @@
return (CFTypeRef)pthread_getspecific(key);
}
-void _CThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) {
+void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) {
if (value != NULL) {
swift_retain((void *)value);
pthread_setspecific(key, value);
diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
index ea62f88..a3063c2 100644
--- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
+++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
@@ -301,7 +301,7 @@
typedef pthread_key_t _CFThreadSpecificKey;
CF_EXPORT CFTypeRef _Nullable _CFThreadSpecificGet(_CFThreadSpecificKey key);
-CF_EXPORT void _CThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value);
+CF_EXPORT void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value);
CF_EXPORT _CFThreadSpecificKey _CFThreadSpecificKeyCreate(void);
typedef pthread_attr_t _CFThreadAttributes;
diff --git a/Foundation/JSONSerialization.swift b/Foundation/JSONSerialization.swift
index f74932d..c624e7a 100644
--- a/Foundation/JSONSerialization.swift
+++ b/Foundation/JSONSerialization.swift
@@ -512,7 +512,7 @@
} else {
throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "NSDictionary key must be NSString"])
}
- pretty ? writer(": ") : writer(":")
+ pretty ? writer(" : ") : writer(":")
try serializeJSON(value)
}
diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift
index 710d046..7dc8cc8 100644
--- a/Foundation/NSNumber.swift
+++ b/Foundation/NSNumber.swift
@@ -825,6 +825,12 @@
CFNumberGetValue(_cfObject, kCFNumberSInt128Type, &value)
return .init(truncatingIfNeeded: value.low)
}
+
+ private var int128Value: CFSInt128Struct {
+ var value = CFSInt128Struct(high: 0, low: 0)
+ CFNumberGetValue(_cfObject, kCFNumberSInt128Type, &value)
+ return value
+ }
open var floatValue: Float {
var value: Float = 0
@@ -881,22 +887,26 @@
}
open func compare(_ otherNumber: NSNumber) -> ComparisonResult {
- switch (objCType.pointee, otherNumber.objCType.pointee) {
- case (0x66, _), (_, 0x66), (0x66, 0x66): fallthrough // 'f' float
- case (0x64, _), (_, 0x64), (0x64, 0x64): // 'd' double
+ switch (_cfNumberType(), otherNumber._cfNumberType()) {
+ case (kCFNumberFloatType, _), (_, kCFNumberFloatType): fallthrough
+ case (kCFNumberDoubleType, _), (_, kCFNumberDoubleType):
let (lhs, rhs) = (doubleValue, otherNumber.doubleValue)
+ // Apply special handling for NaN as <, >, == always return false
+ // when comparing with NaN
+ if lhs.isNaN && rhs.isNaN { return .orderedSame }
+ if lhs.isNaN { return .orderedAscending }
+ if rhs.isNaN { return .orderedDescending }
+
if lhs < rhs { return .orderedAscending }
if lhs > rhs { return .orderedDescending }
return .orderedSame
- case (0x51, _), (_, 0x51), (0x51, 0x51): // 'q' unsigned long long
- let (lhs, rhs) = (uint64Value, otherNumber.uint64Value)
- if lhs < rhs { return .orderedAscending }
- if lhs > rhs { return .orderedDescending }
- return .orderedSame
- case (_, _):
- let (lhs, rhs) = (int64Value, otherNumber.int64Value)
- if lhs < rhs { return .orderedAscending }
- if lhs > rhs { return .orderedDescending }
+
+ default: // For signed and unsigned integers expand upto S128Int
+ let (lhs, rhs) = (int128Value, otherNumber.int128Value)
+ if lhs.high < rhs.high { return .orderedAscending }
+ if lhs.high > rhs.high { return .orderedDescending }
+ if lhs.low < rhs.low { return .orderedAscending }
+ if lhs.low > rhs.low { return .orderedDescending }
return .orderedSame
}
}
diff --git a/Foundation/Thread.swift b/Foundation/Thread.swift
index 340ec7f..402294d 100644
--- a/Foundation/Thread.swift
+++ b/Foundation/Thread.swift
@@ -23,13 +23,13 @@
return specific as! T
} else {
let value = generator()
- _CThreadSpecificSet(key, value)
+ _CFThreadSpecificSet(key, value)
return value
}
}
internal func set(_ value: T) {
- _CThreadSpecificSet(key, value)
+ _CFThreadSpecificSet(key, value)
}
}
diff --git a/Foundation/URLSession/URLSession.swift b/Foundation/URLSession/URLSession.swift
index 3a07673..7690cc4 100644
--- a/Foundation/URLSession/URLSession.swift
+++ b/Foundation/URLSession/URLSession.swift
@@ -406,9 +406,11 @@
fileprivate extension URLSession {
func createNextTaskIdentifier() -> Int {
- let i = nextTaskIdentifier
- nextTaskIdentifier += 1
- return i
+ return workQueue.sync {
+ let i = nextTaskIdentifier
+ nextTaskIdentifier += 1
+ return i
+ }
}
}
diff --git a/TestFoundation/TestJSONSerialization.swift b/TestFoundation/TestJSONSerialization.swift
index a07eba4..dabcf7f 100644
--- a/TestFoundation/TestJSONSerialization.swift
+++ b/TestFoundation/TestJSONSerialization.swift
@@ -989,6 +989,7 @@
("test_serialize_dictionaryWithDecimal", test_serialize_dictionaryWithDecimal),
("test_serializeDecimalNumberJSONObject", test_serializeDecimalNumberJSONObject),
("test_serializeSortedKeys", test_serializeSortedKeys),
+ ("test_serializePrettyPrinted", test_serializePrettyPrinted),
]
}
@@ -1479,6 +1480,11 @@
XCTAssertEqual(try trySerialize(dict, options: .sortedKeys), "{\"a\":{\"a\":1,\"b\":1,\"c\":1},\"b\":{\"a\":1,\"b\":1,\"c\":1},\"c\":{\"a\":1,\"b\":1,\"c\":1}}")
}
+ func test_serializePrettyPrinted() {
+ let dictionary = ["key": 4]
+ XCTAssertEqual(try trySerialize(dictionary, options: .prettyPrinted), "{\n \"key\" : 4\n}")
+ }
+
fileprivate func createTestFile(_ path: String,_contents: Data) -> String? {
let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
do {
diff --git a/TestFoundation/TestNSNumber.swift b/TestFoundation/TestNSNumber.swift
index 0e3ac08..b34d45c 100644
--- a/TestFoundation/TestNSNumber.swift
+++ b/TestFoundation/TestNSNumber.swift
@@ -1133,5 +1133,29 @@
XCTAssertTrue(NSNumber(value: UInt16.min) == NSNumber(value: Float(0)))
XCTAssertTrue(NSNumber(value: UInt16.max) == NSNumber(value: Double(65535)))
XCTAssertTrue(NSNumber(value: 1.1) != NSNumber(value: Int64(1)))
+ let num = NSNumber(value: Int8.min)
+ XCTAssertFalse(num == NSNumber(value: num.uint64Value))
+
+ let num1 = NSNumber(value: Float.nan)
+ XCTAssertEqual(num1.compare(num1), ComparisonResult.orderedSame)
+
+ let num2 = NSNumber(value: num1.uint8Value) // 0
+ XCTAssertFalse(num1 == num2)
+ XCTAssertFalse(num2 == num1)
+ XCTAssertEqual(num1.compare(num2), ComparisonResult.orderedAscending)
+ XCTAssertEqual(num2.compare(num1), ComparisonResult.orderedDescending)
+
+ let num3 = NSNumber(value: Double.nan)
+ XCTAssertEqual(num3.compare(num3), ComparisonResult.orderedSame)
+
+ let num4 = NSNumber(value: num3.intValue) // 0
+ XCTAssertFalse(num3 == num2)
+ XCTAssertFalse(num4 == num3)
+ XCTAssertEqual(num3.compare(num4), ComparisonResult.orderedAscending)
+ XCTAssertEqual(num4.compare(num3), ComparisonResult.orderedDescending)
+
+ XCTAssertEqual(NSNumber(value: Double.leastNonzeroMagnitude).compare(NSNumber(value: 0)), ComparisonResult.orderedDescending)
+ XCTAssertEqual(NSNumber(value: Double.greatestFiniteMagnitude).compare(NSNumber(value: 0)), ComparisonResult.orderedDescending)
+ XCTAssertTrue(NSNumber(value: Double(-0.0)) == NSNumber(value: Double(0.0)))
}
}