-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBCFileUtilities.m
247 lines (148 loc) · 8.5 KB
/
BCFileUtilities.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
//
// BCRelativePath.m
// MindsEye
//
// Created by Tom Houpt on 11/5/7.
// Copyright 2011 BehavioralCybernetics LLC. All rights reserved.
//
#import "BCFileUtilities.h"
NSString *RelativePathFromAbsoluteFilePath(NSString *filePath, NSString *baseFilePath) {
NSInteger level_of_base_directory;
NSInteger deepest_common_directory_level;
NSInteger number_of_doubledots;
NSInteger i;
NSArray *baseFilePathComponents = [baseFilePath pathComponents];
NSArray *filePathComponents = [filePath pathComponents];
// [baseFilePathComponents count] - 1 == the base file
// [baseFilePathComponents count] - 2 == the base directory
level_of_base_directory = [baseFilePathComponents count] - 2;
#define BASEPATHDIRECTORY ((NSString *)[baseFilePathComponents objectAtIndex:deepest_common_directory_level])
#define FILEPATHDIRECTORY ((NSString *)[filePathComponents objectAtIndex:deepest_common_directory_level])
deepest_common_directory_level = 0; // start at top of paths
while ([BASEPATHDIRECTORY isEqualToString:FILEPATHDIRECTORY]) {
deepest_common_directory_level++;
if (deepest_common_directory_level == [baseFilePathComponents count]) break;
if (deepest_common_directory_level == [filePathComponents count]) break;
}
deepest_common_directory_level--; // need to substract 1 to correct for 0 indexing
NSString *relativePath = [[NSString alloc] init];
if (deepest_common_directory_level == level_of_base_directory) {
// if (deepest_common_directory_level == level_of_base_directory)
// then the rest of the pathDirectory is inside the basePathDirectory, so add a single dot
// append @"." (single dot) to relative path
relativePath = [relativePath stringByAppendingPathComponent:@"."];
}
else if (deepest_common_directory_level < level_of_base_directory) {
// if (deepest_common_directory_level < level_of_base_directory)
// then we need to add double-dots to get up to the common_directory from the base_directoy
number_of_doubledots = level_of_base_directory - deepest_common_directory_level;
for (i=0; i< number_of_doubledots; i++) {
// append @".." (double dot) to relative path
relativePath = [relativePath stringByAppendingPathComponent:@".."];
}
}
// append all the remaining path components from (deepest_common_directory_level+1) thru ([filepathComponents count] -1);
for (i= (deepest_common_directory_level+1); i < [filePathComponents count]; i++) {
// append [filepathComponents objectAtIndex:i] to relativePath
relativePath = [relativePath stringByAppendingPathComponent:(NSString *)[filePathComponents objectAtIndex:i]];
}
return relativePath;
}
NSString *AbsolutePathFromRelativeFilePath(NSString *relativePath, NSString *baseFilePath) {
// get the path to the directory which contains the baseFile
NSString *basePathDirectory = [baseFilePath stringByDeletingLastPathComponent];
// the absolute path is the base directory + the relative path
NSString *absoluteFilePath = [basePathDirectory stringByAppendingPathComponent:relativePath];
// resolve any double-dots with the standardizing path method
absoluteFilePath = [absoluteFilePath stringByStandardizingPath];
return absoluteFilePath;
}
NSSavePanel *SavePanelForFilenameAndType(NSString *currentFilename, NSString *typeUTI) {
// Build a new name for the file using the current name and
// the filename extension associated with the specified UTI.
// if the specificed UTI is "nil", then assume that name already has its extension, and set our extension to empty string @""
NSString* newName ;
NSString *extension;
if (nil != typeUTI) {
CFStringRef newExtensionRef = UTTypeCopyPreferredTagWithClass((CFStringRef)CFBridgingRetain(typeUTI),
kUTTagClassFilenameExtension);
if (nil != newExtensionRef) {
extension = (__bridge NSString *)newExtensionRef;
newName = [[currentFilename stringByDeletingPathExtension]
stringByAppendingPathExtension:extension];
}
else {
extension = typeUTI;
newName = [[currentFilename stringByDeletingPathExtension]
stringByAppendingPathExtension:typeUTI];
}
}
else {
newName = [currentFilename copy];
extension = @"";
}
// CFRelease(newExtension); // already released in newName declaration
// Set the default name for the file and show the panel.
NSSavePanel* panel = [NSSavePanel savePanel];
[panel setAllowedFileTypes:@[extension]];
[panel setNameFieldStringValue:newName];
return panel;
}
void MakeTemporaryBackupCopyOfFileAtURL(NSURL *srcURL, NSError **error) {
// given at file at srcURL, make a copy named "Backup of ..."
// calls NSFileManager copyItemAtURL:toURL:error:
if ([[NSFileManager defaultManager] fileExistsAtPath:[srcURL path]]) {
NSString *backupFileName = [NSString stringWithFormat: @"Temporary Backup of %@", [srcURL lastPathComponent]];
NSURL *dstURL = [[srcURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:backupFileName];
// if there is already a "Temporary Backup of..." file then delete it
// to make room for the new temporary backup
if ([[NSFileManager defaultManager] fileExistsAtPath:[dstURL path]]) {
[[NSFileManager defaultManager] removeItemAtURL:dstURL error:error];
}
// make a copy of the current file with name "Temporary Backup of ..."
[[NSFileManager defaultManager] copyItemAtURL:srcURL toURL:dstURL error:error ];
}
}
void FinalizeTemporaryBackup(NSURL *srcURL, NSError **error) {
// given at temporary backup of the file at srcURL, rename the temporary backup to "Backup of ..."
// if an old "Backup of ..." file exists, then delete it prior to renaming temporary backup
// calls NSFileManager moveItemAtURL:toURL:error:
NSString *tempBackupFileName = [NSString stringWithFormat: @"Temporary Backup of %@", [srcURL lastPathComponent]];
NSString *backupFileName = [NSString stringWithFormat: @"Backup of %@", [srcURL lastPathComponent]];
NSURL *tempURL = [[srcURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:tempBackupFileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:[tempURL path]]) {
NSURL *finalURL = [[srcURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:backupFileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:[finalURL path]]) {
[[NSFileManager defaultManager] removeItemAtURL:finalURL error:error];
}
[[NSFileManager defaultManager] moveItemAtURL:tempURL toURL:finalURL error:error ];
}
}
void RestoreFromTemporaryBackup(NSURL *srcURL, NSError **error) {
// given at temporary backup of the file at srcURL, rename the temporary backup to the original filename
// calls NSFileManager moveItemAtURL:toURL:error:
NSString *tempBackupFileName = [NSString stringWithFormat: @"Temporary Backup of %@", [srcURL lastPathComponent]];
NSURL *tempURL = [[srcURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:tempBackupFileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:[tempURL path]]) {
[[NSFileManager defaultManager] moveItemAtURL:tempURL toURL:srcURL error:error ];
}
}
NSString *GenerateUniqueFileNameAtPath(NSString *path, NSString *basename, NSString *extension) {
NSString *filename = [NSString stringWithFormat:@"%@.%@", basename, extension];
NSString *result = [path stringByAppendingPathComponent:filename];
NSInteger i = 1;
while ([[NSFileManager defaultManager] fileExistsAtPath:result]) {
filename = [NSString stringWithFormat:@"%@ %ld.%@", basename, (long)i, extension];
result = [path stringByAppendingPathComponent:filename];
i++;
}
return result;
}
NSArray *ArrayOfMissingDataLabels(void) {
// @"<none>", @"--", @"nd", @"n.d.", @"n.a.", @".", @"null", @"nil", @"nan"
return ( [NSArray arrayWithObjects:@"<none>", @"--", @"—", @"nd", @"n.d.", @"na", @"n.a.", @".", @"null", @"nil",@"nan", nil]);
}
//(NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error
//NSFileImmutable
//NSFileBusy
//NSFileAppendOnly