From 9c4d2ca98227b1b79adfc5ab615c2033ad717dcf Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 10 Aug 2019 01:40:09 -0400 Subject: [PATCH 1/4] Add NSProgress --- Headers/Foundation/Foundation.h | 1 + Headers/Foundation/MISSING | 5 -- Tests/base/NSProgress/TestInfo | 0 Tests/base/NSProgress/basic.m | 44 +++++++++++ Tests/base/NSProgress/basic.m~ | 133 ++++++++++++++++++++++++++++++++ 5 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 Tests/base/NSProgress/TestInfo create mode 100644 Tests/base/NSProgress/basic.m create mode 100644 Tests/base/NSProgress/basic.m~ diff --git a/Headers/Foundation/Foundation.h b/Headers/Foundation/Foundation.h index bd7933b50..b10fd1af2 100644 --- a/Headers/Foundation/Foundation.h +++ b/Headers/Foundation/Foundation.h @@ -104,6 +104,7 @@ #import #import #import +#import #import #import #import diff --git a/Headers/Foundation/MISSING b/Headers/Foundation/MISSING index 7dc50164d..d07ebf1de 100644 --- a/Headers/Foundation/MISSING +++ b/Headers/Foundation/MISSING @@ -90,11 +90,6 @@ NSAttributedString: - enumerateAttribute:inRange:options:usingBlock: ------------------------------------------------------------- NSBundle: - - bundleURL - - resourceURL - - executableURL - - URLForAuxiliaryExecutable: - - privateFrameworksURL - sharedFrameworksURL - sharedSupportURL - builtInPlugInsURL diff --git a/Tests/base/NSProgress/TestInfo b/Tests/base/NSProgress/TestInfo new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/base/NSProgress/basic.m b/Tests/base/NSProgress/basic.m new file mode 100644 index 000000000..a936d0cda --- /dev/null +++ b/Tests/base/NSProgress/basic.m @@ -0,0 +1,44 @@ +#import +#import +#import +#import "ObjectTesting.h" + +int main() +{ + id obj1; + id obj2; + NSMutableArray *testObjs = [[NSMutableArray alloc] init]; + NSAutoreleasePool *arp = [NSAutoreleasePool new]; + NSDictionary *dict = [NSDictionary dictionary]; + NSProgress *progress = [[NSProgress alloc] initWithParent: nil + userInfo: dict]; + PASS(progress != nil, "[NSProgress initWithParent:userInfo:] returns instance"); + + progress = [NSProgress discreteProgressWithTotalUnitCount:100]; + PASS(progress != nil, "[NSProgress discreteProgressWithTotalUnitCount:] returns instance"); + + progress = [NSProgress progressWithTotalUnitCount:100]; + PASS(progress != nil, "[NSProgress progressWithTotalUnitCount:] returns instance"); + + progress = [NSProgress progressWithTotalUnitCount:100 + parent:progress + pendingUnitCount:50]; + PASS(progress != nil, "[NSProgress progressWithTotalUnitCount:] returns instance"); + + [progress becomeCurrentWithPendingUnitCount:50]; + NSProgress *currentProgress = [NSProgress currentProgress]; + PASS(currentProgress == progress, "Correct progress object associated with current thread"); + + NSProgress *new_progress = [NSProgress progressWithTotalUnitCount:100 + parent:progress + pendingUnitCount:50]; + [new_progress addChild:[[NSProgress alloc] initWithParent: nil userInfo: nil] + withPendingUnitCount:50]; + + [currentProgress resignCurrent]; + + PASS([NSProgress currentProgress] == nil, "Current progress is nil after resign current"); + + [arp release]; arp = nil; + return 0; +} diff --git a/Tests/base/NSProgress/basic.m~ b/Tests/base/NSProgress/basic.m~ new file mode 100644 index 000000000..66c8ef1ad --- /dev/null +++ b/Tests/base/NSProgress/basic.m~ @@ -0,0 +1,133 @@ +#import +#import +#import +#import "ObjectTesting.h" + + +# ifndef __has_feature +# define __has_feature(x) 0 +# endif + +static BOOL blockDidRun = NO; + +int main() +{ + id obj1; + id obj2; + NSMutableArray *testObjs = [[NSMutableArray alloc] init]; + NSAutoreleasePool *arp = [NSAutoreleasePool new]; + + test_alloc(@"NSOperation"); + obj1 = [NSOperation new]; + PASS((obj1 != nil), "can create an operation"); + [testObjs addObject: obj1]; + test_NSObject(@"NSOperation", testObjs); + + PASS(([obj1 isReady] == YES), "operation is ready"); + PASS(([obj1 isConcurrent] == NO), "operation is not concurrent"); + PASS(([obj1 isCancelled] == NO), "operation is not cancelled"); + PASS(([obj1 isExecuting] == NO), "operation is not executing"); + PASS(([obj1 isFinished] == NO), "operation is not finished"); + PASS(([[obj1 dependencies] isEqual: [NSArray array]]), + "operation has no dependencies"); + PASS(([obj1 queuePriority] == NSOperationQueuePriorityNormal), + "operation has normal priority"); + [obj1 setQueuePriority: 10000]; + PASS(([obj1 queuePriority] == NSOperationQueuePriorityVeryHigh), + "operation has very high priority"); + + obj2 = [NSOperation new]; + [obj2 addDependency: obj1]; + PASS(([[obj2 dependencies] isEqual: testObjs]), + "operation has added dependency"); + PASS(([obj2 isReady] == NO), "operation with dependency is not ready"); + [obj1 cancel]; + PASS(([[obj2 dependencies] isEqual: testObjs]), + "cancelled dependency continues"); + PASS(([obj1 isCancelled] == YES), "operation is cancelled"); + PASS(([[obj2 dependencies] isEqual: testObjs]), + "cancelled dependency continues"); + PASS(([obj2 isReady] == NO), "operation with cancelled dependency not ready"); + [obj2 removeDependency: obj1]; + PASS(([[obj2 dependencies] isEqual: [NSArray array]]), + "dependency removal works"); + PASS(([obj2 isReady] == YES), "operation without dependency is ready"); + + [obj1 release]; + obj1 = [NSOperation new]; + [testObjs replaceObjectAtIndex: 0 withObject: obj1]; + [obj2 addDependency: obj1]; +# if __has_feature(blocks) + [obj1 setCompletionBlock: ^(void){blockDidRun = YES;}]; +# endif + [obj1 start]; + [NSThread sleepForTimeInterval: 1.0]; + PASS(([obj1 isFinished] == YES), "operation is finished"); + PASS(([obj1 isReady] == YES), "a finished operation is ready"); +# if __has_feature(blocks) + PASS(YES == blockDidRun, "completion block is executed"); +# endif + PASS(([[obj2 dependencies] isEqual: testObjs]), + "finished dependency continues"); + PASS(([obj2 isReady] == YES), "operation with finished dependency is ready"); + + [obj2 removeDependency: obj1]; + [obj1 release]; + obj1 = [NSOperation new]; + [testObjs replaceObjectAtIndex: 0 withObject: obj1]; + [obj2 addDependency: obj1]; + [obj2 cancel]; + PASS(([obj2 isReady] == YES), + "a cancelled object is ready even with a dependency"); + + [obj2 start]; + PASS(([obj2 isFinished] == YES), + "a cancelled object can finish"); + + PASS_EXCEPTION([obj2 start];, + NSInvalidArgumentException, + "NSOperation cannot be started twice"); + + PASS(([obj2 waitUntilFinished], YES), "wait returns at once"); + + + test_alloc(@"NSOperationQueue"); + obj1 = [NSOperationQueue new]; + PASS((obj1 != nil), "can create an operation queue"); + [testObjs removeAllObjects]; + [testObjs addObject: obj1]; + test_NSObject(@"NSOperationQueue", testObjs); + + PASS(([obj1 isSuspended] == NO), "not suspended by default"); + [obj1 setSuspended: YES]; + PASS(([obj1 isSuspended] == YES), "set suspended yes"); + [obj1 setSuspended: NO]; + PASS(([obj1 isSuspended] == NO), "set suspended no"); + + PASS(([[obj1 name] length] > 0), "name has a default"); + [obj1 setName: @"mine"]; + PASS(([[obj1 name] isEqual: @"mine"] == YES), "set name OK"); + [obj1 setName: nil]; + PASS(([[obj1 name] isEqual: @""]), "setting null name gives empty string"); + + PASS(([obj1 maxConcurrentOperationCount] == NSOperationQueueDefaultMaxConcurrentOperationCount), "max concurrent set by default"); + [obj1 setMaxConcurrentOperationCount: 1]; + PASS(([obj1 maxConcurrentOperationCount] == 1), "max concurrent set to one"); + [obj1 setMaxConcurrentOperationCount: 0]; + PASS(([obj1 maxConcurrentOperationCount] == 0), "max concurrent set to zero"); + [obj1 setMaxConcurrentOperationCount: 1000000]; + PASS(([obj1 maxConcurrentOperationCount] == 1000000), "max concurrent set to a million"); + [obj1 setMaxConcurrentOperationCount: NSOperationQueueDefaultMaxConcurrentOperationCount]; + PASS(([obj1 maxConcurrentOperationCount] == NSOperationQueueDefaultMaxConcurrentOperationCount), "max concurrent set to default"); + PASS_EXCEPTION([obj1 setMaxConcurrentOperationCount: -1000000];, + NSInvalidArgumentException, + "NSOperationQueue cannot be given negative count"); + + obj2 = [NSOperation new]; + [obj1 addOperation: obj2]; + [NSThread sleepForTimeInterval: 1.0]; + PASS(([obj2 isFinished] == YES), "queue ran operation"); + + [arp release]; arp = nil; + return 0; +} From 57f6c8b49117217e99843b2d3f64650f5b10ce5b Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Sat, 10 Aug 2019 01:40:44 -0400 Subject: [PATCH 2/4] Add NSProgress tests --- Tests/base/NSProgress/basic.m~ | 133 --------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 Tests/base/NSProgress/basic.m~ diff --git a/Tests/base/NSProgress/basic.m~ b/Tests/base/NSProgress/basic.m~ deleted file mode 100644 index 66c8ef1ad..000000000 --- a/Tests/base/NSProgress/basic.m~ +++ /dev/null @@ -1,133 +0,0 @@ -#import -#import -#import -#import "ObjectTesting.h" - - -# ifndef __has_feature -# define __has_feature(x) 0 -# endif - -static BOOL blockDidRun = NO; - -int main() -{ - id obj1; - id obj2; - NSMutableArray *testObjs = [[NSMutableArray alloc] init]; - NSAutoreleasePool *arp = [NSAutoreleasePool new]; - - test_alloc(@"NSOperation"); - obj1 = [NSOperation new]; - PASS((obj1 != nil), "can create an operation"); - [testObjs addObject: obj1]; - test_NSObject(@"NSOperation", testObjs); - - PASS(([obj1 isReady] == YES), "operation is ready"); - PASS(([obj1 isConcurrent] == NO), "operation is not concurrent"); - PASS(([obj1 isCancelled] == NO), "operation is not cancelled"); - PASS(([obj1 isExecuting] == NO), "operation is not executing"); - PASS(([obj1 isFinished] == NO), "operation is not finished"); - PASS(([[obj1 dependencies] isEqual: [NSArray array]]), - "operation has no dependencies"); - PASS(([obj1 queuePriority] == NSOperationQueuePriorityNormal), - "operation has normal priority"); - [obj1 setQueuePriority: 10000]; - PASS(([obj1 queuePriority] == NSOperationQueuePriorityVeryHigh), - "operation has very high priority"); - - obj2 = [NSOperation new]; - [obj2 addDependency: obj1]; - PASS(([[obj2 dependencies] isEqual: testObjs]), - "operation has added dependency"); - PASS(([obj2 isReady] == NO), "operation with dependency is not ready"); - [obj1 cancel]; - PASS(([[obj2 dependencies] isEqual: testObjs]), - "cancelled dependency continues"); - PASS(([obj1 isCancelled] == YES), "operation is cancelled"); - PASS(([[obj2 dependencies] isEqual: testObjs]), - "cancelled dependency continues"); - PASS(([obj2 isReady] == NO), "operation with cancelled dependency not ready"); - [obj2 removeDependency: obj1]; - PASS(([[obj2 dependencies] isEqual: [NSArray array]]), - "dependency removal works"); - PASS(([obj2 isReady] == YES), "operation without dependency is ready"); - - [obj1 release]; - obj1 = [NSOperation new]; - [testObjs replaceObjectAtIndex: 0 withObject: obj1]; - [obj2 addDependency: obj1]; -# if __has_feature(blocks) - [obj1 setCompletionBlock: ^(void){blockDidRun = YES;}]; -# endif - [obj1 start]; - [NSThread sleepForTimeInterval: 1.0]; - PASS(([obj1 isFinished] == YES), "operation is finished"); - PASS(([obj1 isReady] == YES), "a finished operation is ready"); -# if __has_feature(blocks) - PASS(YES == blockDidRun, "completion block is executed"); -# endif - PASS(([[obj2 dependencies] isEqual: testObjs]), - "finished dependency continues"); - PASS(([obj2 isReady] == YES), "operation with finished dependency is ready"); - - [obj2 removeDependency: obj1]; - [obj1 release]; - obj1 = [NSOperation new]; - [testObjs replaceObjectAtIndex: 0 withObject: obj1]; - [obj2 addDependency: obj1]; - [obj2 cancel]; - PASS(([obj2 isReady] == YES), - "a cancelled object is ready even with a dependency"); - - [obj2 start]; - PASS(([obj2 isFinished] == YES), - "a cancelled object can finish"); - - PASS_EXCEPTION([obj2 start];, - NSInvalidArgumentException, - "NSOperation cannot be started twice"); - - PASS(([obj2 waitUntilFinished], YES), "wait returns at once"); - - - test_alloc(@"NSOperationQueue"); - obj1 = [NSOperationQueue new]; - PASS((obj1 != nil), "can create an operation queue"); - [testObjs removeAllObjects]; - [testObjs addObject: obj1]; - test_NSObject(@"NSOperationQueue", testObjs); - - PASS(([obj1 isSuspended] == NO), "not suspended by default"); - [obj1 setSuspended: YES]; - PASS(([obj1 isSuspended] == YES), "set suspended yes"); - [obj1 setSuspended: NO]; - PASS(([obj1 isSuspended] == NO), "set suspended no"); - - PASS(([[obj1 name] length] > 0), "name has a default"); - [obj1 setName: @"mine"]; - PASS(([[obj1 name] isEqual: @"mine"] == YES), "set name OK"); - [obj1 setName: nil]; - PASS(([[obj1 name] isEqual: @""]), "setting null name gives empty string"); - - PASS(([obj1 maxConcurrentOperationCount] == NSOperationQueueDefaultMaxConcurrentOperationCount), "max concurrent set by default"); - [obj1 setMaxConcurrentOperationCount: 1]; - PASS(([obj1 maxConcurrentOperationCount] == 1), "max concurrent set to one"); - [obj1 setMaxConcurrentOperationCount: 0]; - PASS(([obj1 maxConcurrentOperationCount] == 0), "max concurrent set to zero"); - [obj1 setMaxConcurrentOperationCount: 1000000]; - PASS(([obj1 maxConcurrentOperationCount] == 1000000), "max concurrent set to a million"); - [obj1 setMaxConcurrentOperationCount: NSOperationQueueDefaultMaxConcurrentOperationCount]; - PASS(([obj1 maxConcurrentOperationCount] == NSOperationQueueDefaultMaxConcurrentOperationCount), "max concurrent set to default"); - PASS_EXCEPTION([obj1 setMaxConcurrentOperationCount: -1000000];, - NSInvalidArgumentException, - "NSOperationQueue cannot be given negative count"); - - obj2 = [NSOperation new]; - [obj1 addOperation: obj2]; - [NSThread sleepForTimeInterval: 1.0]; - PASS(([obj2 isFinished] == YES), "queue ran operation"); - - [arp release]; arp = nil; - return 0; -} From 0f09fefac3e917fb38de2661d1d6f4f02e68b2c0 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 14 Aug 2019 04:30:52 -0400 Subject: [PATCH 3/4] Fix crash due to dictionary --- Headers/Foundation/MISSING | 3 --- Headers/Foundation/NSProgress.h | 2 +- Source/NSProgress.m | 16 ++++++++++++---- Tests/base/NSProgress/basic.m | 3 --- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Headers/Foundation/MISSING b/Headers/Foundation/MISSING index d07ebf1de..8db8379ac 100644 --- a/Headers/Foundation/MISSING +++ b/Headers/Foundation/MISSING @@ -92,10 +92,7 @@ NSAttributedString: NSBundle: - sharedFrameworksURL - sharedSupportURL - - builtInPlugInsURL - appStoreReceiptURL - - pathForAuxiliaryExecutable: - - privateFrameworksPath - sharedFrameworksPath - sharedSupportPath + URLsForResourcesWithExtension:subdirectory:inBundleWithURL: diff --git a/Headers/Foundation/NSProgress.h b/Headers/Foundation/NSProgress.h index e34172ce7..5ee47ebdc 100644 --- a/Headers/Foundation/NSProgress.h +++ b/Headers/Foundation/NSProgress.h @@ -33,7 +33,7 @@ extern "C" { #endif - @class NSString, NSDictionary, NSArray, NSNumber, NSProgress; +@class NSString, NSDictionary, NSArray, NSNumber, NSURL, NSProgress; #if OS_API_VERSION(MAC_OS_X_VERSION_10_9, GS_API_LATEST) diff --git a/Source/NSProgress.m b/Source/NSProgress.m index a710fe02f..482027c6f 100644 --- a/Source/NSProgress.m +++ b/Source/NSProgress.m @@ -96,7 +96,7 @@ static NSMutableDictionary *__subscribers = nil; internal->_throughput = nil; internal->_totalUnitCount = 0; internal->_completedUnitCount = 0; - internal->_userInfo = [userInfo mutableCopy]; + internal->_userInfo = RETAIN([userInfo mutableCopy]); internal->_cancelled = NO; internal->_cancellable = NO; internal->_paused = NO; @@ -104,7 +104,6 @@ static NSMutableDictionary *__subscribers = nil; internal->_indeterminate = NO; internal->_finished = NO; internal->_parent = parent; // this is a weak reference and not retained. - internal->_userInfo = [[NSMutableDictionary alloc] initWithCapacity: 10]; } return self; } @@ -209,8 +208,12 @@ static NSMutableDictionary *__subscribers = nil; - (NSString *) localizedDescription { - return [NSString stringWithFormat: @"%f percent complete", - [self fractionCompleted]]; + return _localizedDescription; +} + +- (void) setLocalizedDescription: (NSString *)localDescription +{ + ASSIGNCOPY(_localizedDescription, localDescription); } - (NSString *) localizedAddtionalDescription @@ -219,6 +222,11 @@ static NSMutableDictionary *__subscribers = nil; [self estimatedTimeRemaining]]; } +- (void) setLocalizedAdditionalDescription: (NSString *)localDescription +{ + ASSIGNCOPY(_localizedAdditionalDescription, localDescription); +} + // Observing progress - (double) fractionCompleted { diff --git a/Tests/base/NSProgress/basic.m b/Tests/base/NSProgress/basic.m index a936d0cda..142ac2253 100644 --- a/Tests/base/NSProgress/basic.m +++ b/Tests/base/NSProgress/basic.m @@ -5,9 +5,6 @@ int main() { - id obj1; - id obj2; - NSMutableArray *testObjs = [[NSMutableArray alloc] init]; NSAutoreleasePool *arp = [NSAutoreleasePool new]; NSDictionary *dict = [NSDictionary dictionary]; NSProgress *progress = [[NSProgress alloc] initWithParent: nil From 5806cc483a50a5e38f79f000fd792ac0ad58dc40 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 14 Aug 2019 04:58:21 -0400 Subject: [PATCH 4/4] Fixes for existing issues reported by Algoriddim. --- Headers/Foundation/NSProgress.h | 2 +- Source/NSProgress.m | 57 +++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Headers/Foundation/NSProgress.h b/Headers/Foundation/NSProgress.h index 5ee47ebdc..b2652c46c 100644 --- a/Headers/Foundation/NSProgress.h +++ b/Headers/Foundation/NSProgress.h @@ -91,7 +91,7 @@ GS_NSProgress_IVARS; - (void) setCompletedUnitCount: (int64_t)unitCount; - (NSString *) localizedDescription; -- (NSString *) localizedAddtionalDescription; +- (NSString *) localizedAdditionalDescription; // Observing progress - (double) fractionCompleted; diff --git a/Source/NSProgress.m b/Source/NSProgress.m index 482027c6f..f8f8dd1b9 100644 --- a/Source/NSProgress.m +++ b/Source/NSProgress.m @@ -47,6 +47,8 @@ NSProgressUnpublishingHandler _unpublishingHandler; \ GSProgressPendingUnitCountBlock _pendingUnitCountHandler; \ GSProgressResumingHandler _resumingHandler; \ + NSString *_localizedDescription; \ + NSString *_localizedAdditionalDescription; \ NSProgress *_parent; #define EXPOSE_NSProgress_IVARS @@ -58,6 +60,7 @@ #import #import #import +#import #define GSInternal NSProgressInternal #include "GSInternal.h" @@ -103,6 +106,8 @@ static NSMutableDictionary *__subscribers = nil; internal->_pausable = NO; internal->_indeterminate = NO; internal->_finished = NO; + internal->_localizedDescription = nil; + internal->_localizedAdditionalDescription = nil; internal->_parent = parent; // this is a weak reference and not retained. } return self; @@ -118,6 +123,8 @@ static NSMutableDictionary *__subscribers = nil; RELEASE(internal->_fileTotalCount); RELEASE(internal->_throughput); RELEASE(internal->_userInfo); + RELEASE(internal->_localizedDescription); + RELEASE(internal->_localizedAdditionalDescription); [super dealloc]; } @@ -208,23 +215,22 @@ static NSMutableDictionary *__subscribers = nil; - (NSString *) localizedDescription { - return _localizedDescription; + return internal->_localizedDescription; } - (void) setLocalizedDescription: (NSString *)localDescription { - ASSIGNCOPY(_localizedDescription, localDescription); + ASSIGNCOPY(internal->_localizedDescription, localDescription); } -- (NSString *) localizedAddtionalDescription +- (NSString *) localizedAdditionalDescription { - return [NSString stringWithFormat: @"%@ minute(s) remaining", - [self estimatedTimeRemaining]]; + return internal->_localizedAdditionalDescription; } - (void) setLocalizedAdditionalDescription: (NSString *)localDescription { - ASSIGNCOPY(_localizedAdditionalDescription, localDescription); + ASSIGNCOPY(internal->_localizedAdditionalDescription, localDescription); } // Observing progress @@ -245,9 +251,17 @@ static NSMutableDictionary *__subscribers = nil; return internal->_cancelled; } +- (BOOL) cancelled +{ + return internal->_cancelled; +} + - (void) cancel { + [self willChangeValueForKey: @"cancelled"]; CALL_BLOCK_NO_ARGS(internal->_cancellationHandler); + internal->_cancelled = YES; + [self didChangeValueForKey: @"cancelled"]; } - (void) setCancellationHandler: (GSProgressCancellationHandler) handler @@ -267,8 +281,10 @@ static NSMutableDictionary *__subscribers = nil; - (void) pause { + [self willChangeValueForKey: @"paused"]; CALL_BLOCK_NO_ARGS(internal->_pausingHandler); internal->_paused = YES; + [self didChangeValueForKey: @"paused"]; } - (void) setPausingHandler: (GSProgressPausingHandler) handler @@ -292,9 +308,16 @@ static NSMutableDictionary *__subscribers = nil; return internal->_indeterminate; } +- (BOOL) indeterminate +{ + return internal->_indeterminate; +} + - (void) setIndeterminate: (BOOL)flag { + [self willChangeValueForKey: @"indeterminate"]; internal->_indeterminate = flag; + [self didChangeValueForKey: @"indeterminate"]; } - (NSProgressKind) kind @@ -304,7 +327,9 @@ static NSMutableDictionary *__subscribers = nil; - (void) setKind: (NSProgressKind)k { + [self willChangeValueForKey: @"kind"]; ASSIGN(internal->_kind, k); + [self didChangeValueForKey: @"kind"]; } - (void)setUserInfoObject: (id)obj @@ -316,7 +341,9 @@ static NSMutableDictionary *__subscribers = nil; // Instance property accessors... - (void) setFileOperationKind: (NSProgressFileOperationKind)k; { + [self willChangeValueForKey: @"fileOperationKind"]; ASSIGN(internal->_fileOperationKind, k); + [self didChangeValueForKey: @"fileOperationKind"]; } - (NSProgressFileOperationKind) fileOperationKind @@ -326,7 +353,9 @@ static NSMutableDictionary *__subscribers = nil; - (void) setFileUrl: (NSURL *)u { + [self willChangeValueForKey: @"fileUrl"]; ASSIGN(internal->_fileUrl, u); + [self didChangeValueForKey: @"fileUrl"]; } - (NSURL*) fileUrl @@ -339,14 +368,26 @@ static NSMutableDictionary *__subscribers = nil; return internal->_finished; } +- (BOOL) finished +{ + return internal->_finished; +} + - (BOOL) isOld { return internal->_old; } +- (BOOL) old +{ + return internal->_old; +} + - (void) setEstimatedTimeRemaining: (NSNumber *)n { + [self willChangeValueForKey: @"estimatedTimeRemaining"]; ASSIGNCOPY(internal->_estimatedTimeRemaining, n); + [self didChangeValueForKey: @"estimatedTimeRemaining"]; } - (NSNumber *) estimatedTimeRemaining @@ -366,7 +407,9 @@ static NSMutableDictionary *__subscribers = nil; - (void) setFileTotalCount: (NSNumber *)n { + [self willChangeValueForKey: @"fileTotalCount"]; ASSIGNCOPY(internal->_fileTotalCount, n); + [self didChangeValueForKey: @"fileTotalCount"]; } - (NSNumber *) fileTotalCount @@ -376,7 +419,9 @@ static NSMutableDictionary *__subscribers = nil; - (void) setThroughput: (NSNumber *)n { + [self willChangeValueForKey: @"throughput"]; ASSIGNCOPY(internal->_throughput, n); + [self didChangeValueForKey: @"throughput"]; } - (NSNumber *) throughtput