Skip to content

Instantly share code, notes, and snippets.

@epologee
Created January 26, 2012 23:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save epologee/6f3715753896ccf6fd35 to your computer and use it in GitHub Desktop.
Save epologee/6f3715753896ccf6fd35 to your computer and use it in GitHub Desktop.
Attempted ARC port of the MZAsync category on NSFileManager, for async file copying. (2nd gist)
//
// NSFileManager+MZAsync.h
// MetaZ
//
// Created by Brian Olsen on 07/01/10.
// Copyright 2010 Maven-Group. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MZAsyncOperation : NSObject
{
NSFileManager* fileManager;
FSFileOperationRef operation;
CFRunLoopRef runLoop;
CFStringRef runLoopMode;
}
@property (readonly) NSFileManager* fileManager;
@property (readonly) FSFileOperationRef operation;
- (id)initWithManager:(NSFileManager *)fileManager;
- (OSStatus)schedule;
- (OSStatus)unschedule;
- (OSStatus)cancel;
@end
@interface NSFileManager (MZAsync)
- (MZAsyncOperation*)copyItemAsyncAtPath:(NSString *)srcPath
toPath:(NSString *)dstPath
destName:(NSString *)destName
options:(int)flags
statusChangeInterval:(CFTimeInterval)statusChangeInterval
error:(NSError**)error;
- (MZAsyncOperation*)moveItemAsyncAtPath:(NSString *)srcPath
toPath:(NSString *)dstPath
destName:(NSString *)destName
options:(int)flags
statusChangeInterval:(CFTimeInterval)statusChangeInterval
error:(NSError**)error;
- (void)asyncCopyOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary;
- (void)asyncMoveOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary;
@end
@interface NSObject (MZAsyncOperationAdditions)
- (void)asyncCopyOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary;
- (void)asyncMoveOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary;
@end
//
// NSFileManager+MZAsync.m
// MetaZ
//
// Created by Brian Olsen on 07/01/10.
// Copyright 2010 Maven-Group. All rights reserved.
//
#import "NSFileManager+MZAsync.h"
NSError* status2Error(OSStatus status);
NSError* status2Error(OSStatus status)
{
return [NSError errorWithDomain:@"OSStatus" code:status userInfo:nil];
}
void MZCopyFSPathFileOperationStatusProc (
FSFileOperationRef fileOp,
const char *currentItem,
FSFileOperationStage stage,
OSStatus status,
CFDictionaryRef statusDictionary,
void *info);
void MZCopyFSPathFileOperationStatusProc (
FSFileOperationRef fileOp,
const char *currentItem,
FSFileOperationStage stage,
OSStatus status,
CFDictionaryRef statusDictionary,
void *info)
{
MZAsyncOperation* op = (__bridge MZAsyncOperation*)info;
NSString* strCurrentItem = [op.fileManager stringWithFileSystemRepresentation:currentItem length:strlen(currentItem)];
NSError* error = status2Error(status);
[op.fileManager asyncCopyOperation:op currentItem:strCurrentItem stage:stage error:error statusDictionary:(__bridge NSDictionary*)statusDictionary];
}
void MZMoveFSPathFileOperationStatusProc (
FSFileOperationRef fileOp,
const char *currentItem,
FSFileOperationStage stage,
OSStatus status,
CFDictionaryRef statusDictionary,
void *info);
void MZMoveFSPathFileOperationStatusProc (
FSFileOperationRef fileOp,
const char *currentItem,
FSFileOperationStage stage,
OSStatus status,
CFDictionaryRef statusDictionary,
void *info)
{
MZAsyncOperation* op = (__bridge MZAsyncOperation*)info;
NSString* strCurrentItem = [op.fileManager stringWithFileSystemRepresentation:currentItem length:strlen(currentItem)];
NSError* error = status2Error(status);
[op.fileManager asyncMoveOperation:op currentItem:strCurrentItem stage:stage error:error statusDictionary:(__bridge NSDictionary*)statusDictionary];
}
@implementation MZAsyncOperation
- (id)initWithManager:(NSFileManager *)theFileManager;
{
self = [super init];
if(self)
{
fileManager = theFileManager;
operation = FSFileOperationCreate(kCFAllocatorDefault);
}
return self;
}
- (void)dealloc
{
if(runLoop) CFRelease(runLoop);
if(runLoopMode) CFRelease(runLoopMode);
CFRelease(operation);
}
@synthesize fileManager;
@synthesize operation;
- (OSStatus)schedule
{
if(runLoop)
[self unschedule];
runLoop = (CFRunLoopRef)CFRetain(CFRunLoopGetCurrent());
runLoopMode = CFRetain(kCFRunLoopCommonModes);
return FSFileOperationScheduleWithRunLoop(operation, runLoop, runLoopMode);
}
- (OSStatus)unschedule
{
OSStatus status = FSFileOperationUnscheduleFromRunLoop(operation, runLoop, runLoopMode);
CFRelease(runLoop);
runLoop = NULL;
CFRelease(runLoopMode);
runLoopMode = NULL;
return status;
}
- (OSStatus)cancel
{
return FSFileOperationCancel(operation);
}
@end
@implementation NSFileManager (MZAsync)
- (MZAsyncOperation*)copyItemAsyncAtPath:(NSString *)srcPath
toPath:(NSString *)dstPath
destName:(NSString *)destName
options:(int)flags
statusChangeInterval:(CFTimeInterval)statusChangeInterval
error:(NSError**)error
{
const char* src = [self fileSystemRepresentationWithPath:srcPath];
const char* dst = [self fileSystemRepresentationWithPath:dstPath];
MZAsyncOperation* ret = [[MZAsyncOperation alloc] initWithManager:self];
FSFileOperationClientContext clientContext;
clientContext.version = 0;
clientContext.info = (__bridge void *)ret;
clientContext.retain = CFRetain;
clientContext.release = CFRelease;
clientContext.copyDescription = CFCopyDescription;
[ret schedule];
OSStatus status = FSPathCopyObjectAsync(
ret.operation,
src,
dst,
(__bridge CFStringRef)destName,
flags,
MZCopyFSPathFileOperationStatusProc,
statusChangeInterval,
&clientContext
);
if(status!=0)
{
if(error)
*error = status2Error(status);
return nil;
}
return ret;
}
- (MZAsyncOperation*)moveItemAsyncAtPath:(NSString *)srcPath
toPath:(NSString *)dstPath
destName:(NSString *)destName
options:(int)flags
statusChangeInterval:(CFTimeInterval)statusChangeInterval
error:(NSError**)error
{
const char* src = [self fileSystemRepresentationWithPath:srcPath];
const char* dst = [self fileSystemRepresentationWithPath:dstPath];
MZAsyncOperation* ret = [[MZAsyncOperation alloc] initWithManager:self];
FSFileOperationClientContext clientContext;
clientContext.version = 0;
clientContext.info = (__bridge void *)ret;
clientContext.retain = CFRetain;
clientContext.release = CFRelease;
clientContext.copyDescription = CFCopyDescription;
[ret schedule];
OSStatus status = FSPathMoveObjectAsync(
ret.operation,
src,
dst,
(__bridge CFStringRef)destName,
flags,
MZMoveFSPathFileOperationStatusProc,
statusChangeInterval,
&clientContext
);
if(status!=0)
{
if(error)
*error = status2Error(status);
return nil;
}
return ret;
}
- (void)asyncCopyOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary
{
[[self delegate] asyncCopyOperation:operation currentItem:currentItem stage:stage error:error statusDictionary:statusDictionary];
}
- (void)asyncMoveOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary;
{
[[self delegate] asyncMoveOperation:operation currentItem:currentItem stage:stage error:error statusDictionary:statusDictionary];
}
@end
@implementation NSObject (MZAsyncOperationAdditions)
- (void)asyncCopyOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary
{
}
- (void)asyncMoveOperation:(MZAsyncOperation *)operation
currentItem:(NSString *)currentItem
stage:(FSFileOperationStage)stage
error:(NSError*)error
statusDictionary:(NSDictionary*)statusDictionary
{
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment