Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
NSFileManagerOOExtensions.m
Go to the documentation of this file.
1/*
2
3NSFileManagerOOExtensions.m
4
5This extends NSFileManager and adds some methods to insulate the
6main oolite code from the gory details of creating/chdiring to the
7commander save directory.
8
9Oolite
10Copyright (C) 2004-2013 Giles C Williams and contributors
11
12This program is free software; you can redistribute it and/or
13modify it under the terms of the GNU General Public License
14as published by the Free Software Foundation; either version 2
15of the License, or (at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25MA 02110-1301, USA.
26
27*/
28
29#include <stdlib.h>
30#import "ResourceManager.h"
31#import "OOPListParsing.h"
32#import "GameController.h"
34#import "unzip.h"
35
36@implementation NSFileManager (OOExtensions)
37
38- (NSArray *) commanderContentsOfPath:(NSString *)savePath
39{
40 BOOL pathIsDirectory = NO;
41 if ([[NSFileManager defaultManager] fileExistsAtPath:savePath isDirectory:&pathIsDirectory] && pathIsDirectory)
42 {
43 NSMutableArray *contents = [NSMutableArray arrayWithArray:[self oo_directoryContentsAtPath:savePath]];
44
45 // at this point we should strip out any files not loadable as Oolite saved games
46 unsigned i;
47 for (i = 0; i < [contents count]; i++)
48 {
49 NSString* path = [savePath stringByAppendingPathComponent: (NSString*)[contents objectAtIndex:i]];
50
51 // ensure it's not a directory
52 if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&pathIsDirectory] && pathIsDirectory)
53 {
54
55 // check file extension
56 if (![[path pathExtension] isEqual:@"oolite-save"])
57 {
58 [contents removeObjectAtIndex: i--];
59 continue;
60 }
61
62 // check to see if we can parse the file okay
63 NSDictionary *cdr = OODictionaryFromFile(path);
64 if (!cdr)
65 {
66 OOLog(@"savedGame.read.fail.notDictionary", @">>>> %@ could not be parsed as a saved game.", path);
67 [contents removeObjectAtIndex: i--];
68 continue;
69 }
70 }
71
72 // all okay - we can use this path!
73 [contents replaceObjectAtIndex: i withObject: path];
74
75 }
76
77 return contents;
78 }
79 else
80 {
81 OOLogERR(@"savedGame.read.fail.fileNotFound", @"File at path '%@' could not be found.", savePath);
82 return nil;
83 }
84}
85
86
87- (NSString *) defaultCommanderPath
88{
89 NSString *savedir = [NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR];
90 BOOL pathIsDirectory = NO;
91
92 // does it exist?
93 if (![[NSFileManager defaultManager] fileExistsAtPath:savedir isDirectory:&pathIsDirectory])
94 {
95 // it doesn't exist.
96 if([self oo_createDirectoryAtPath:savedir attributes:nil])
97 {
98 return savedir;
99 }
100 else
101 {
102 OOLogERR(@"savedGame.defaultPath.create.failed", @"Unable to create '%@'. Saved games will go to the home directory.", savedir);
103 return NSHomeDirectory();
104 }
105 }
106
107 // is it a directory?
108 if (!pathIsDirectory)
109 {
110 OOLogERR(@"savedGame.defaultPath.notDirectory", @"'%@' is not a directory, saved games will go to the home directory.", savedir);
111 return NSHomeDirectory();
112 }
113
114 return savedir;
115}
116
117
118#if OOLITE_MAC_OS_X
119
120- (NSArray *) oo_directoryContentsAtPath:(NSString *)path
121{
122 return [self contentsOfDirectoryAtPath:path error:NULL];
123}
124
125
126- (BOOL) oo_createDirectoryAtPath:(NSString *)path attributes:(NSDictionary *)attributes
127{
128 return [self createDirectoryAtPath:path withIntermediateDirectories:YES attributes:attributes error:NULL];
129}
130
131
132- (NSDictionary *) oo_fileAttributesAtPath:(NSString *)path traverseLink:(BOOL)traverseLink
133{
134 if (traverseLink)
135 {
136 NSString *linkDest = nil;
137 do
138 {
139 linkDest = [self destinationOfSymbolicLinkAtPath:path error:NULL];
140 if (linkDest != nil) path = linkDest;
141 } while (linkDest != nil);
142 }
143
144 return [self attributesOfItemAtPath:path error:NULL];
145}
146
147
148- (NSDictionary *) oo_fileSystemAttributesAtPath:(NSString *)path
149{
150 return [self attributesOfFileSystemForPath:path error:NULL];
151}
152
153
154- (BOOL) oo_removeItemAtPath:(NSString *)path
155{
156 return [self removeItemAtPath:path error:NULL];
157}
158
159
160- (BOOL) oo_moveItemAtPath:(NSString *)src toPath:(NSString *)dest
161{
162 return [self moveItemAtPath:src toPath:dest error:NULL];
163}
164
165#else
166
167- (NSArray *) oo_directoryContentsAtPath:(NSString *)path
168{
169 return [self directoryContentsAtPath:path];
170}
171
172
173- (BOOL) oo_createDirectoryAtPath:(NSString *)path attributes:(NSDictionary *)attributes
174{
175#if OOLITE_WINDOWS
176 return [self createDirectoryAtPath:path attributes:attributes];
177#else
178 // has been in GNUStep since 2008, so it's probably safe to use now.
179 // .... why do I say things like that, of course it's not safe - CIM
180 return [self createDirectoryAtPath:path withIntermediateDirectories:YES attributes:attributes error:NULL];
181#endif
182}
183
184
185- (NSDictionary *) oo_fileAttributesAtPath:(NSString *)path traverseLink:(BOOL)yorn
186{
187 return [self fileAttributesAtPath:path traverseLink:yorn];
188}
189
190
191- (NSDictionary *) oo_fileSystemAttributesAtPath:(NSString *)path
192{
193 return [self fileSystemAttributesAtPath:path];
194}
195
196
197- (BOOL) oo_removeItemAtPath:(NSString *)path
198{
199 return [self removeFileAtPath:path handler:nil];
200}
201
202
203- (BOOL) oo_moveItemAtPath:(NSString *)src toPath:(NSString *)dest
204{
205 return [self movePath:src toPath:dest handler:nil];
206}
207
208#endif
209
210
211#if OOLITE_SDL
212- (BOOL) chdirToSnapshotPath
213{
214 // SDL: the default path for snapshots is oolite.app/oolite-saves/snapshots
215 NSString *savedir = [[NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR];
216
217 if (![self changeCurrentDirectoryPath: savedir])
218 {
219 // it probably doesn't exist.
220 if (![self createDirectoryAtPath: savedir attributes: nil])
221 {
222 OOLog(@"savedSnapshot.defaultPath.create.failed", @"Unable to create directory %@", savedir);
223 return NO;
224 }
225 if (![self changeCurrentDirectoryPath: savedir])
226 {
227 OOLog(@"savedSnapshot.defaultPath.chdir.failed", @"Created %@ but couldn't make it the current directory.", savedir);
228 return NO;
229 }
230 }
231
232 return YES;
233}
234#endif
235
236- (BOOL) oo_oxzFileExistsAtPath:(NSString *)path
237{
238 NSUInteger i, cl;
239 NSArray *components = [path pathComponents];
240 cl = [components count];
241 for (i = 0 ; i < cl ; i++)
242 {
243 NSString *component = [components objectAtIndex:i];
244 if ([[[component pathExtension] lowercaseString] isEqualToString:@"oxz"])
245 {
246 break;
247 }
248 }
249 // if i == cl then the path is entirely uncompressed
250 if (i == cl)
251 {
252 BOOL directory = NO;
253 BOOL result = [self fileExistsAtPath:path isDirectory:&directory];
254 if (directory)
255 {
256 return NO;
257 }
258 return result;
259 }
260
261 NSRange range;
262 range.location = 0; range.length = i+1;
263 NSString *zipFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
264 range.location = i+1; range.length = cl-(i+1);
265 NSString *containedFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
266
267 unzFile uf = NULL;
268 const char* zipname = [zipFile cStringUsingEncoding:NSUTF8StringEncoding];
269 if (zipname != NULL)
270 {
271 uf = unzOpen64(zipname);
272 }
273 if (uf == NULL)
274 {
275 // no such zip file
276 return NO;
277 }
278 const char* filename = [containedFile cStringUsingEncoding:NSUTF8StringEncoding];
279 // unzLocateFile(*, *, 1) = case-sensitive extract
280 BOOL result = YES;
281 if (unzLocateFile(uf, filename, 1) != UNZ_OK)
282 {
283 result = NO;
284 }
285 else
286 {
287 int err = UNZ_OK;
288 unz_file_info64 file_info = {0};
289 err = unzGetCurrentFileInfo64(uf, &file_info, NULL, 0, NULL, 0, NULL, 0);
290 if (err != UNZ_OK)
291 {
292 result = NO;
293 }
294 else
295 {
296
297
298 }
299 }
300 unzClose(uf);
301 return result;
302}
303
304
305
306
307@end
308
309
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
#define OOLog(class, format,...)
Definition OOLogging.h:88
NSDictionary * OODictionaryFromFile(NSString *path)
return nil
NSArray * oo_directoryContentsAtPath:(NSString *path)
const char * filename
Definition ioapi.h:133
int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity)
Definition unzip.c:1238
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition unzip.c:1130
unzFile ZEXPORT unzOpen64(const void *path)
Definition unzip.c:801
int ZEXPORT unzClose(unzFile file)
Definition unzip.c:811
voidp unzFile
Definition unzip.h:70
#define UNZ_OK
Definition unzip.h:74