Skip to content

Commit 4071cdd

Browse files
committed
Improved content caching and file deletion
1 parent d5e7f8b commit 4071cdd

File tree

3 files changed

+97
-22
lines changed

3 files changed

+97
-22
lines changed

LSFileWrapper.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,27 @@ FOUNDATION_EXPORT const unsigned char LSFileWrapperVersionString[];
4545

4646
- (NSString *)addFileWrapper:(LSFileWrapper *)fileWrapper withFilename:(NSString *)filename;
4747
- (void)setFileWrapper:(LSFileWrapper *)fileWrapper withFilename:(NSString *)filename;
48+
- (void)removeFileWrapper:(LSFileWrapper *)fileWrapper;
4849
- (NSString *)addContent:(id<NSObject>)content_ withFilename:(NSString *)filename;
4950
- (void)setContent:(id<NSObject>)content_ withFilename:(NSString *)filename;
5051

5152
- (BOOL)writeUpdatesToURL:(NSURL *)url error:(NSError *__autoreleasing *)outError;
53+
- (BOOL)writeToURL:(NSURL *)url error:(NSError *__autoreleasing *)outError;
5254

5355
@property (readonly, strong, nonatomic) NSString *filename;
5456
@property (readonly, strong, nonatomic) NSString *fileType;
5557
@property (readonly, nonatomic) BOOL updated;
5658
@property (readonly, nonatomic) BOOL isDirectory;
5759
@property (assign, nonatomic) NSInteger reserve;
5860
@end
61+
62+
@interface LSFileWrapper ()
63+
@property (weak, nonatomic) LSFileWrapper *parent;
64+
@property (strong, nonatomic) NSMutableDictionary<NSString*, LSFileWrapper*> *fileWrappers;
65+
@property (strong, nonatomic) NSString *filename;
66+
@property (strong, nonatomic) NSURL *writtenURL;
67+
@property (strong, nonatomic) id<NSObject> content;
68+
@property (assign, nonatomic) BOOL updated;
69+
@property (assign, nonatomic) BOOL deleted;
70+
@property (assign, nonatomic) BOOL cacheFile;
71+
@end

LSFileWrapper.m

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,12 @@
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) {

macOS/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919
<key>CFBundleVersion</key>
2020
<string>$(CURRENT_PROJECT_VERSION)</string>
2121
<key>NSHumanReadableCopyright</key>
22-
<string>Copyright © 2019 Adam Kopeć. All rights reserved.</string>
22+
<string>Copyright © 2013 Luke Scott. Copyright © 2019 Adam Kopeć. All rights reserved.</string>
2323
</dict>
2424
</plist>

0 commit comments

Comments
 (0)