Skip to content

Commit b0563dd

Browse files
committed
fix
[SR-431] expose _CFWriteStreamCreateFromFileDescriptor [SR-377] NSPropertyList accessors for use by NSKeyedArchiver w [SR-377] common Foundation class decoders/encoders See Docs/Archiving.md for further implementation status notes. x x Reproduce the _runtime(_ObjC) version of hasPrefix and hasSuffix Port of the prefix and suffix test from swift/test/1_stdlib/NSStringAPI.swift Correction: use bitwise or x Corrected bad wrong link to API design guidelines Link has probably been changed since the creation of the file. Disable test_completePathIntoString tests since it can take a very long time SR-644 to follow-up on this. Fix key's typo to NSFileGroupOwnerAccountName The key NSFileGroupOwnerAccountId is a typo as it is later overwritten by an NSNumber on line 381. The correct constant is NSFileGroupOwnerAccountName to correctly add the String of the account's name to the dictionary. Revert "Fix key's typo to NSFileGroupOwnerAccountName" Added few tests for NSMutableCharacterSet Implement NSTemporaryDirectory * Darwin should check against `confstr` using `_CS_DARWIN_USER_TEMP_DIR` * All platforms check against TMPDIR environment variable * Fall back to /tmp/ x Corrected bad wrong link to API design guidelines Link has probably been changed since the creation of the file. Disable test_completePathIntoString tests since it can take a very long time SR-644 to follow-up on this. Fix key's typo to NSFileGroupOwnerAccountName The key NSFileGroupOwnerAccountId is a typo as it is later overwritten by an NSNumber on line 381. The correct constant is NSFileGroupOwnerAccountName to correctly add the String of the account's name to the dictionary. Revert "Fix key's typo to NSFileGroupOwnerAccountName" Added few tests for NSMutableCharacterSet Implement NSTemporaryDirectory * Darwin should check against `confstr` using `_CS_DARWIN_USER_TEMP_DIR` * All platforms check against TMPDIR environment variable * Fall back to /tmp/ Addressing 32-bit issues with NSXMLNodeOptions
1 parent 4df89e5 commit b0563dd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4735
-366
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,13 @@ extern uint32_t _CFKeyedArchiverUIDGetValue(CFKeyedArchiverUIDRef uid);
234234

235235
extern CFIndex __CFBinaryPlistWriteToStream(CFPropertyListRef plist, CFTypeRef stream);
236236
extern CFDataRef _CFPropertyListCreateXMLDataWithExtras(CFAllocatorRef allocator, CFPropertyListRef propertyList);
237+
extern CFWriteStreamRef _CFWriteStreamCreateFromFileDescriptor(CFAllocatorRef alloc, int fd);
237238

238239
CF_PRIVATE CF_EXPORT char *_Nonnull*_Nonnull _CFEnviron(void);
239240

240241
CF_EXPORT void CFLog1(CFLogLevel lev, CFStringRef message);
241242

243+
242244
_CF_EXPORT_SCOPE_END
243245

244246
#endif /* __COREFOUNDATION_FORSWIFTFOUNDATIONONLY__ */

CoreFoundation/Stream.subproj/CFConcreteStreams.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ typedef struct {
5454

5555

5656
CONST_STRING_DECL(kCFStreamPropertyFileCurrentOffset, "kCFStreamPropertyFileCurrentOffset");
57-
#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
57+
#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
5858
CONST_STRING_DECL(_kCFStreamPropertyFileNativeHandle, "_kCFStreamPropertyFileNativeHandle");
5959
#endif
6060

@@ -87,7 +87,7 @@ static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *erro
8787
wchar_t path[CFMaxPathSize];
8888
flags |= (_O_BINARY|_O_NOINHERIT);
8989
if (_CFURLGetWideFileSystemRepresentation(fileStream->url, TRUE, path, CFMaxPathSize) == FALSE)
90-
#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
90+
#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
9191
char path[CFMaxPathSize];
9292
if (CFURLGetFileSystemRepresentation(fileStream->url, TRUE, (UInt8 *)path, CFMaxPathSize) == FALSE)
9393
#endif
@@ -102,7 +102,7 @@ static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *erro
102102
}
103103

104104
do {
105-
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
105+
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
106106
fileStream->fd = open((const char *)path, flags, 0666);
107107
#elif DEPLOYMENT_TARGET_WINDOWS
108108
fileStream->fd = _wopen(path, flags, 0666);
@@ -422,7 +422,7 @@ static CFTypeRef fileCopyProperty(struct _CFStream *stream, CFStringRef property
422422
if (fileStream->offset != -1) {
423423
result = CFNumberCreate(CFGetAllocator((CFTypeRef)stream), kCFNumberSInt64Type, &(fileStream->offset));
424424
}
425-
#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
425+
#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
426426
} else if (CFEqual(propertyName, _kCFStreamPropertyFileNativeHandle)) {
427427
int fd = fileStream->fd;
428428
if (fd != -1) {

Docs/Archiving.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Archiving Notes
2+
3+
There is a preliminary implementation of NSKeyedArchiver and NSKeyedUnarchiver which should be compatible with the OS X version.
4+
5+
* NSKeyedUnarchiver reads the entire plist into memory before constructing the object graph, it should construct it incrementally as does Foundation on OS X
6+
7+
* Paths that raise errors vs. calling _fatalError() need to be reviewed carefully
8+
9+
* The signature of the decoding APIs that take a class whitelist has changed from NSSet to [AnyClass] as AnyClass does not support Hashable. The API change has been marked Experimental.
10+
11+
* classForKeyed[Un]Archiver has moved into NSObject so it can be overridden, move this back into an extension eventually
12+
13+
# Classes
14+
15+
## Implemented
16+
17+
* NSArray
18+
* NSCalendar
19+
* NSCFArray (encodes as NSArray)
20+
* NSCFDictionary (encodes as NSDictionary)
21+
* NSCFSet (encodes as NSSet)
22+
* NSCFString (encodes as NSString)
23+
* NSConcreteValue
24+
* NSData
25+
* NSDate
26+
* NSDictionary
27+
* NSError
28+
* NSLocale
29+
* NSNotification
30+
* NSNull (no-op)
31+
* NSOrderedSet
32+
* NSPersonNameComponents
33+
* NSPort (not supported for keyed archiving)
34+
* NSSet
35+
* NSSpecialValue (for limited number of types)
36+
* NSString
37+
* NSTimeZone
38+
* NSURL
39+
* NSUUID
40+
* NSValue (via class cluster hack)
41+
42+
## TODO
43+
44+
### Pending actual class implementation
45+
46+
* NSAttributedString
47+
48+
### Pending coder implementation
49+
50+
* NSAffineTransform
51+
* NSCharacterSet
52+
* NSDecimalNumber
53+
* NSDecimalNumberHandler
54+
* NSExpression
55+
* NSIndexPath
56+
* NSIndexSet
57+
* NSPredicate
58+
* NSSortDescriptor
59+
* NSTextCheckingResult
60+
* NSURLAuthenticationChallenge
61+
* NSURLCache
62+
* NSURLCredential
63+
* NSURLProtectionSpace
64+
* NSURLRequest

Foundation.xcodeproj/project.pbxproj

Lines changed: 220 additions & 3 deletions
Large diffs are not rendered by default.

Foundation/NSArray.swift

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,45 @@ public class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NS
6666
}
6767

6868
public required convenience init?(coder aDecoder: NSCoder) {
69-
self.init(objects: nil, count: 0)
69+
if !aDecoder.allowsKeyedCoding {
70+
var cnt: UInt32 = 0
71+
// We're stuck with (int) here (rather than unsigned int)
72+
// because that's the way the code was originally written, unless
73+
// we go to a new version of the class, which has its own problems.
74+
withUnsafeMutablePointer(&cnt) { (ptr: UnsafeMutablePointer<UInt32>) -> Void in
75+
aDecoder.decodeValueOfObjCType("i", at: UnsafeMutablePointer<Void>(ptr))
76+
}
77+
let objects = UnsafeMutablePointer<AnyObject?>.alloc(Int(cnt))
78+
for idx in 0..<cnt {
79+
objects.advancedBy(Int(idx)).initialize(aDecoder.decodeObject())
80+
}
81+
self.init(objects: UnsafePointer<AnyObject?>(objects), count: Int(cnt))
82+
objects.destroy(Int(cnt))
83+
objects.dealloc(Int(cnt))
84+
} else if aDecoder.dynamicType == NSKeyedUnarchiver.self || aDecoder.containsValueForKey("NS.objects") {
85+
let objects = aDecoder._decodeArrayOfObjectsForKey("NS.objects")
86+
self.init(array: objects)
87+
} else {
88+
var objects = [AnyObject]()
89+
var count = 0
90+
while let object = aDecoder.decodeObjectForKey("NS.object.\(count)") {
91+
objects.append(object)
92+
count += 1
93+
}
94+
self.init(array: objects)
95+
}
7096
}
7197

7298
public func encodeWithCoder(aCoder: NSCoder) {
73-
99+
if let keyedArchiver = aCoder as? NSKeyedArchiver {
100+
keyedArchiver._encodeArrayOfObjects(self, forKey:"NS.objects")
101+
} else {
102+
for object in self {
103+
if let codable = object as? NSCoding {
104+
codable.encodeWithCoder(aCoder)
105+
}
106+
}
107+
}
74108
}
75109

76110
public static func supportsSecureCoding() -> Bool {
@@ -631,10 +665,6 @@ public class NSMutableArray : NSArray {
631665
}
632666
}
633667

634-
public required convenience init(coder: NSCoder) {
635-
self.init()
636-
}
637-
638668
public override subscript (idx: Int) -> AnyObject {
639669
get {
640670
return objectAtIndex(idx)

Foundation/NSCFArray.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ internal final class _NSCFArray : NSMutableArray {
4040
override func removeObjectAtIndex(index: Int) {
4141
CFArrayRemoveValueAtIndex(_cfMutableObject, index)
4242
}
43+
44+
override var classForCoder: AnyClass {
45+
return NSMutableArray.self
46+
}
4347
}
4448

4549
internal func _CFSwiftArrayGetCount(array: AnyObject) -> CFIndex {

Foundation/NSCFDictionary.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ internal final class _NSCFDictionary : NSMutableDictionary {
8787
override func setObject(anObject: AnyObject, forKey aKey: NSObject) {
8888
CFDictionarySetValue(_cfMutableObject, unsafeBitCast(aKey, UnsafePointer<Void>.self), unsafeBitCast(anObject, UnsafePointer<Void>.self))
8989
}
90+
91+
override var classForCoder: AnyClass {
92+
return NSMutableDictionary.self
93+
}
9094
}
9195

9296
internal func _CFSwiftDictionaryGetCount(dictionary: AnyObject) -> CFIndex {

Foundation/NSCFSet.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ internal final class _NSCFSet : NSMutableSet {
2727
required init(capacity numItems: Int) {
2828
fatalError()
2929
}
30+
31+
override var classForCoder: AnyClass {
32+
return NSMutableSet.self
33+
}
3034
}

Foundation/NSCFString.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ internal class _NSCFString : NSMutableString {
5151
override func replaceCharactersInRange(range: NSRange, withString aString: String) {
5252
CFStringReplace(unsafeBitCast(self, CFMutableStringRef.self), CFRangeMake(range.location, range.length), aString._cfObject)
5353
}
54+
55+
override var classForCoder: AnyClass {
56+
return NSMutableString.self
57+
}
5458
}
5559

5660
internal final class _NSCFConstantString : _NSCFString {
@@ -103,6 +107,10 @@ internal final class _NSCFConstantString : _NSCFString {
103107
override func replaceCharactersInRange(range: NSRange, withString aString: String) {
104108
fatalError()
105109
}
110+
111+
override var classForCoder: AnyClass {
112+
return NSString.self
113+
}
106114
}
107115

108116
internal func _CFSwiftStringGetLength(string: AnyObject) -> CFIndex {

Foundation/NSCalendar.swift

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,52 @@ public class NSCalendar : NSObject, NSCopying, NSSecureCoding {
106106
return unsafeBitCast(self, CFCalendarRef.self)
107107
}
108108

109-
public required init?(coder aDecoder: NSCoder) {
110-
NSUnimplemented()
109+
public convenience required init?(coder aDecoder: NSCoder) {
110+
if aDecoder.allowsKeyedCoding {
111+
guard let calendarIdentifier = aDecoder.decodeObjectOfClass(NSString.self, forKey: "NS.identifier") else {
112+
return nil
113+
}
114+
115+
self.init(calendarIdentifier: calendarIdentifier.bridge())
116+
117+
if let timeZone = aDecoder.decodeObjectOfClass(NSTimeZone.self, forKey: "NS.timezone") {
118+
self.timeZone = timeZone
119+
}
120+
if let locale = aDecoder.decodeObjectOfClass(NSLocale.self, forKey: "NS.locale") {
121+
self.locale = locale
122+
}
123+
self.firstWeekday = aDecoder.decodeIntegerForKey("NS.firstwkdy")
124+
self.minimumDaysInFirstWeek = aDecoder.decodeIntegerForKey("NS.mindays")
125+
if let startDate = aDecoder.decodeObjectOfClass(NSDate.self, forKey: "NS.gstartdate") {
126+
self._startDate = startDate
127+
}
128+
} else {
129+
NSUnimplemented()
130+
}
131+
}
132+
133+
private var _startDate : NSDate? {
134+
get {
135+
return CFCalendarCopyGregorianStartDate(self._cfObject)?._nsObject
136+
}
137+
set {
138+
if let startDate = newValue {
139+
CFCalendarSetGregorianStartDate(self._cfObject, startDate._cfObject)
140+
}
141+
}
111142
}
112143

113144
public func encodeWithCoder(aCoder: NSCoder) {
114-
NSUnimplemented()
145+
if aCoder.allowsKeyedCoding {
146+
aCoder.encodeObject(self.calendarIdentifier.bridge(), forKey: "NS.identifier")
147+
aCoder.encodeObject(self.timeZone, forKey: "NS.timezone")
148+
aCoder.encodeObject(self.locale, forKey: "NS.locale")
149+
aCoder.encodeInteger(self.firstWeekday, forKey: "NS.firstwkdy")
150+
aCoder.encodeInteger(self.minimumDaysInFirstWeek, forKey: "NS.mindays")
151+
aCoder.encodeObject(self._startDate, forKey: "NS.gstartdate");
152+
} else {
153+
NSUnimplemented()
154+
}
115155
}
116156

117157
static public func supportsSecureCoding() -> Bool {
@@ -167,7 +207,12 @@ public class NSCalendar : NSObject, NSCopying, NSSecureCoding {
167207
_CFDeinit(self)
168208
}
169209

170-
public var calendarIdentifier: String { NSUnimplemented() }
210+
public var calendarIdentifier: String {
211+
get {
212+
return CFCalendarGetIdentifier(_cfObject)._swiftObject
213+
}
214+
}
215+
171216
/*@NSCopying*/ public var locale: NSLocale? {
172217
get {
173218
return CFCalendarCopyLocale(_cfObject)._nsObject
@@ -1210,12 +1255,54 @@ public class NSDateComponents : NSObject, NSCopying, NSSecureCoding {
12101255
return false
12111256
}
12121257

1213-
public required init?(coder aDecoder: NSCoder) {
1214-
NSUnimplemented()
1258+
public convenience required init?(coder aDecoder: NSCoder) {
1259+
if aDecoder.allowsKeyedCoding {
1260+
self.init()
1261+
1262+
self.era = aDecoder.decodeIntegerForKey("NS.era")
1263+
self.year = aDecoder.decodeIntegerForKey("NS.year")
1264+
self.quarter = aDecoder.decodeIntegerForKey("NS.quarter")
1265+
self.month = aDecoder.decodeIntegerForKey("NS.month")
1266+
self.day = aDecoder.decodeIntegerForKey("NS.day")
1267+
self.hour = aDecoder.decodeIntegerForKey("NS.hour")
1268+
self.minute = aDecoder.decodeIntegerForKey("NS.minute")
1269+
self.second = aDecoder.decodeIntegerForKey("NS.second")
1270+
self.nanosecond = aDecoder.decodeIntegerForKey("NS.nanosec")
1271+
self.weekOfYear = aDecoder.decodeIntegerForKey("NS.weekOfYear")
1272+
self.weekOfMonth = aDecoder.decodeIntegerForKey("NS.weekOfMonth")
1273+
self.yearForWeekOfYear = aDecoder.decodeIntegerForKey("NS.yearForWOY")
1274+
self.weekday = aDecoder.decodeIntegerForKey("NS.weekday")
1275+
self.weekdayOrdinal = aDecoder.decodeIntegerForKey("NS.weekdayOrdinal")
1276+
self.leapMonth = aDecoder.decodeBoolForKey("NS.leapMonth")
1277+
self.calendar = aDecoder.decodeObjectOfClass(NSCalendar.self, forKey: "NS.calendar")
1278+
self.timeZone = aDecoder.decodeObjectOfClass(NSTimeZone.self, forKey: "NS.timezone")
1279+
} else {
1280+
NSUnimplemented()
1281+
}
12151282
}
12161283

12171284
public func encodeWithCoder(aCoder: NSCoder) {
1218-
NSUnimplemented()
1285+
if aCoder.allowsKeyedCoding {
1286+
aCoder.encodeInteger(self.era, forKey: "NS.era")
1287+
aCoder.encodeInteger(self.year, forKey: "NS.year")
1288+
aCoder.encodeInteger(self.quarter, forKey: "NS.quarter")
1289+
aCoder.encodeInteger(self.month, forKey: "NS.month")
1290+
aCoder.encodeInteger(self.day, forKey: "NS.day")
1291+
aCoder.encodeInteger(self.hour, forKey: "NS.hour")
1292+
aCoder.encodeInteger(self.minute, forKey: "NS.minute")
1293+
aCoder.encodeInteger(self.second, forKey: "NS.second")
1294+
aCoder.encodeInteger(self.nanosecond, forKey: "NS.nanosec")
1295+
aCoder.encodeInteger(self.weekOfYear, forKey: "NS.weekOfYear")
1296+
aCoder.encodeInteger(self.weekOfMonth, forKey: "NS.weekOfMonth")
1297+
aCoder.encodeInteger(self.yearForWeekOfYear, forKey: "NS.yearForWOY")
1298+
aCoder.encodeInteger(self.weekday, forKey: "NS.weekday")
1299+
aCoder.encodeInteger(self.weekdayOrdinal, forKey: "NS.weekdayOrdinal")
1300+
aCoder.encodeBool(self.leapMonth, forKey: "NS.leapMonth")
1301+
aCoder.encodeObject(self.calendar, forKey: "NS.calendar")
1302+
aCoder.encodeObject(self.timeZone, forKey: "NS.timezone")
1303+
} else {
1304+
NSUnimplemented()
1305+
}
12191306
}
12201307

12211308
static public func supportsSecureCoding() -> Bool {

0 commit comments

Comments
 (0)