66
77#import " LSFileWrapper.h"
88
9- @interface LSFileWrapper ()
10- @property (weak , nonatomic ) LSFileWrapper *parent;
11- @property (strong , nonatomic ) NSMutableDictionary *fileWrappers;
12- @property (strong , nonatomic ) NSString *filename;
13- @property (strong , nonatomic ) NSURL *writtenURL;
14- @property (strong , nonatomic ) id <NSObject > content;
15- @property (assign , nonatomic ) BOOL updated;
16- @property (assign , nonatomic ) BOOL deleted;
17- @property (assign , nonatomic ) BOOL cacheFile;
18- @end
19-
209@interface LSFileWrapper (Internal)
2110- (LSFileWrapper *)walkDirectoryPath : (NSString *)path create : (BOOL )create ;
2211- (NSString *)setFileWrapper : (LSFileWrapper *)fileWrapper filename : (NSString *)filename_ replace : (BOOL )replace ;
2312- (BOOL )getParentUpdates : (NSMutableArray *)updates withURL : (NSURL *)url ;
2413- (void )getUpdates : (NSMutableArray *)updates withURL : (NSURL *)url ;
14+ - (void )getAll : (NSMutableArray *)updates withURL : (NSURL *)url ;
2515- (BOOL )writeUpdates : (NSArray *)updates filemanager : (NSFileManager *)fileManager error : (NSError *__autoreleasing *)outError ;
2616@end
2717
@@ -90,10 +80,14 @@ - (NSData *)data
9080{
9181 if (content == nil && writtenURL != nil ) {
9282 content = [NSData dataWithContentsOfURL: writtenURL];
93- cacheFile = YES ;
83+ // cacheFile = YES;
9484 }
9585 if ([content isKindOfClass: [NSData class ]]) {
96- return (NSData *)content;
86+ NSData * contentAsData = (NSData *)content;
87+ if (!updated && writtenURL != nil ) {
88+ content = nil ;
89+ }
90+ return contentAsData;
9791 }
9892 return nil ;
9993}
@@ -179,6 +173,7 @@ - (void)updateContent:(id<NSObject>)content_
179173 }
180174 content = content_;
181175 updated = YES ;
176+ deleted = NO ;
182177}
183178
184179- (void )deleteContent
@@ -254,6 +249,29 @@ - (void)setFileWrapper:(LSFileWrapper *)fileWrapper withFilename:(NSString *)fil
254249 [self setFileWrapper: fileWrapper filename: filename_ replace: YES ];
255250}
256251
252+ - (void )removeFileWrapper : (LSFileWrapper *)fileWrapper {
253+ if (!isDirectory) {
254+ @throw [NSException exceptionWithName: NSInternalInconsistencyException
255+ reason: @" LSFileWrapper file is not a directory."
256+ userInfo: nil ];
257+ return ;
258+ }
259+ if (fileWrapper == self) {
260+ @throw [NSException exceptionWithName: NSInternalInconsistencyException
261+ reason: @" Cannot remove LSFileWrapper from itself."
262+ userInfo: nil ];
263+ return ;
264+ }
265+ LSFileWrapper *existing = [fileWrappers objectForKey: fileWrapper.filename];
266+ if (existing.writtenURL ) {
267+ existing.deleted = YES ;
268+ }
269+ else {
270+ [fileWrappers removeObjectForKey: fileWrapper.filename];
271+ }
272+ updated = YES ;
273+ }
274+
257275- (NSString *)addContent : (id <NSObject >)content_ withFilename : (NSString *)filename_
258276{
259277 LSFileWrapper *fileWrapper = [[LSFileWrapper alloc ] initFile ];
@@ -291,6 +309,19 @@ - (BOOL)writeUpdatesToURL:(NSURL *)url error:(NSError *__autoreleasing *)outErro
291309 return [self writeUpdates: updates filemanager: [[NSFileManager alloc ] init ] error: outError];
292310}
293311
312+ - (BOOL )writeToURL : (NSURL *)url error : (NSError *__autoreleasing *)outError {
313+ NSMutableArray *updates = [[NSMutableArray alloc ] init ];
314+
315+ if (parent) {
316+ @throw [NSException exceptionWithName: NSInternalInconsistencyException
317+ reason: @" LSFileWrapper child cannot be written to new URL"
318+ userInfo: nil ];
319+ }
320+
321+ [self getAll: updates withURL: url];
322+ return [self writeUpdates: updates filemanager: [[NSFileManager alloc ] init ] error: outError];
323+ }
324+
294325@end
295326
296327@implementation LSFileWrapper (Internal)
@@ -372,6 +403,7 @@ - (NSString *)setFileWrapper:(LSFileWrapper *)fileWrapper filename:(NSString *)f
372403 }
373404 fileWrapper.parent = self;
374405 fileWrapper.filename = filename_;
406+ fileWrapper.deleted = NO ;
375407 [fileWrappers setObject: fileWrapper forKey: filename_];
376408 }
377409 else if (replace) {
@@ -486,18 +518,29 @@ - (BOOL)getParentUpdates:(NSMutableArray *)updates withURL:(NSURL *)url
486518- (void )getUpdates : (NSMutableArray *)updates withURL : (NSURL *)url
487519{
488520 if (deleted) {
489- [updates addObject: @{@" url" : url, @" wrapper" :self}];
521+ [updates addObject: @{@" url" : url, @" wrapper" :self, @" shouldPopulateWrittenURL " : @ YES }];
490522 }
491523 else if (isDirectory) {
492524 if (!writtenURL) {
493- [updates addObject: @{@" url" : url, @" wrapper" :self}];
525+ [updates addObject: @{@" url" : url, @" wrapper" :self, @" shouldPopulateWrittenURL " : @ YES }];
494526 }
495527 for (LSFileWrapper *fileWrapper in [fileWrappers objectEnumerator ]) {
496528 [fileWrapper getUpdates: updates withURL: [url URLByAppendingPathComponent: fileWrapper.filename]];
497529 }
498530 }
499531 else if (updated && content) {
500- [updates addObject: @{@" url" : url, @" wrapper" :self}];
532+ [updates addObject: @{@" url" : url, @" wrapper" :self, @" shouldPopulateWrittenURL" : @YES }];
533+ }
534+ }
535+
536+ - (void )getAll : (NSMutableArray *)updates withURL : (NSURL *)url {
537+ if (!deleted) {
538+ [updates addObject: @{@" url" : url, @" wrapper" :self, @" shouldPopulateWrittenURL" : @NO }];
539+ if (isDirectory) {
540+ for (LSFileWrapper *fileWrapper in [fileWrappers objectEnumerator ]) {
541+ [fileWrapper getAll: updates withURL: [url URLByAppendingPathComponent: fileWrapper.filename]];
542+ }
543+ }
501544 }
502545}
503546
@@ -508,6 +551,11 @@ - (BOOL)writeUpdates:(NSArray *)updates filemanager:(NSFileManager *)fileManager
508551 for (NSDictionary *updateInfo in updates) {
509552 NSURL *fileURL = [updateInfo objectForKey: @" url" ];
510553 LSFileWrapper *fileWrapper = [updateInfo objectForKey: @" wrapper" ];
554+ // MARK: Don't change writtenURL for whole file write!
555+ BOOL shouldPopulateWrittenURL = [(NSNumber *)[updateInfo objectForKey: @" shouldPopulateWrittenURL" ] boolValue ];
556+ if (fileWrapper.content == nil && fileWrapper.writtenURL != nil ) {
557+ fileWrapper.content = [NSData dataWithContentsOfURL: fileWrapper.writtenURL];
558+ }
511559 NSObject *fileContent = fileWrapper.content ;
512560 BOOL success = YES ;
513561
@@ -524,6 +572,11 @@ - (BOOL)writeUpdates:(NSArray *)updates filemanager:(NSFileManager *)fileManager
524572 }
525573 }
526574 else if ([fileContent isKindOfClass: [NSData class ]]) {
575+ // Create the directories if they're missing
576+ NSURL * directoryURL = [fileURL URLByDeletingLastPathComponent ];
577+ if ([directoryURL checkResourceIsReachableAndReturnError: nil ] == NO ) {
578+ [[NSFileManager defaultManager ] createDirectoryAtURL: directoryURL withIntermediateDirectories: YES attributes: @{NSFileExtensionHidden : @YES } error: outError];
579+ }
527580 success = [(NSData *)fileContent writeToURL: fileURL options: NSDataWritingAtomic error: outError];
528581 }
529582 else if ([fileContent isKindOfClass: [NSString class ]]) {
@@ -555,11 +608,20 @@ - (BOOL)writeUpdates:(NSArray *)updates filemanager:(NSFileManager *)fileManager
555608 }
556609
557610 fileWrapper.filename = [fileURL lastPathComponent ];
558- fileWrapper.writtenURL = fileURL;
559- fileWrapper.updated = NO ;
560-
561- if (!cacheFile) {
562- fileWrapper.content = nil ;
611+ if (shouldPopulateWrittenURL) {
612+ fileWrapper.writtenURL = fileURL;
613+
614+ fileWrapper.updated = NO ;
615+
616+ if (!cacheFile) {
617+ fileWrapper.content = nil ;
618+ }
619+ } else {
620+ if (!fileWrapper.updated ) {
621+ if (!cacheFile) {
622+ fileWrapper.content = nil ;
623+ }
624+ }
563625 }
564626
565627 if (fileWrapper.deleted ) {
0 commit comments