Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
JAPersistentFileReference.m
Go to the documentation of this file.
1/*
2
3JAPersistentFileReference.m
4
5
6Copyright (C) 2010-2013 Jens Ayton
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25
26*/
27
29#import <CoreServices/CoreServices.h>
30
31
32#define kURLKey @"url"
33#define kAliasKey @"alias"
34#define kBookmarkKey @"bookmark"
35
36
37#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
38#define BookmarkDataSupported() (YES)
39#else
40#if __ppc__ || __ppc64__
41// Bookmark data is only available in Snow Leopard and later, which excludes PPC systems.
42#define BookmarkDataSupported() (NO)
43#else
44#define BookmarkDataSupported() ([NSURL instancesRespondToSelector:@selector(bookmarkDataWithOptions:includingResourceValuesForKeys:relativeToURL:error:)])
45#endif
46
47
48#if MAC_OS_X_VERSION_10_6 > MAC_OS_X_VERSION_MAX_ALLOWED
49
50@interface NSURL (SnowLeopardMethods)
51
52- (NSData *)bookmarkDataWithOptions:(unsigned long)options includingResourceValuesForKeys:(NSArray *)keys relativeToURL:(NSURL *)relativeURL error:(NSError **)error;
53- (NSURL *)fileReferenceURL;
54- (NSURL *)filePathURL;
55- (BOOL)isFileReferenceURL;
56+ (id)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(unsigned long)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error;
57
58@end
59
60
61enum
62{
63 NSURLBookmarkResolutionWithoutUI = ( 1UL << 8 ),
64 NSURLBookmarkResolutionWithoutMounting = ( 1UL << 9 ),
65};
66
67#endif
68#endif
69
70
71NSDictionary *JAPersistentFileReferenceFromURL(NSURL *url)
72{
73 if (url == nil) return nil;
74
75 NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:3];
76 [result setObject:[url absoluteString] forKey:kURLKey];
77
78 if ([url isFileURL])
79 {
80 FSRef fsRef;
81 if (CFURLGetFSRef((CFURLRef)[url absoluteURL], &fsRef))
82 {
83 AliasHandle alias = NULL;
84 if (FSNewAlias(NULL, &fsRef, &alias) == noErr)
85 {
86 NSData *aliasData = [NSData dataWithBytes:*alias length:GetAliasSize(alias)];
87 if (aliasData != NULL)
88 {
89 [result setObject:aliasData forKey:kAliasKey];
90 }
91 DisposeHandle((Handle)alias);
92 }
93 }
94 }
95
97 {
98 NSURL *refURL = [url fileReferenceURL];
99 if (refURL != nil)
100 {
101 NSData *bookmarkData = [refURL bookmarkDataWithOptions:0
102 includingResourceValuesForKeys:nil
103 relativeToURL:nil
104 error:NULL];
105 if (bookmarkData != nil)
106 {
107 [result setObject:bookmarkData forKey:kBookmarkKey];
108 }
109 }
110 }
111
112 return result;
113}
114
115
117{
118 unsigned long result = 0;
119 if (flags & kJAPersistentFileReferenceWithoutUI) result |= NSURLBookmarkResolutionWithoutUI;
120 if (flags & NSURLBookmarkResolutionWithoutMounting) result |= NSURLBookmarkResolutionWithoutMounting;
121 return result;
122}
123
124
126{
127 unsigned long result = 0;
128 if (flags & kJAPersistentFileReferenceWithoutUI) result |= kResolveAliasFileNoUI;
129 return result;
130}
131
132
133NSURL *JAURLFromPersistentFileReference(NSDictionary *fileRef, JAPersistentFileReferenceResolveFlags flags, BOOL *isStale)
134{
135 NSURL *result = nil;
136 BOOL stale = NO, staleIfFile = NO;
137
138 // Try bookmark.
140 {
141 NSData *bookmarkData = [fileRef objectForKey:kBookmarkKey];
142 if ([bookmarkData isKindOfClass:[NSData class]])
143 {
144 result = [NSURL URLByResolvingBookmarkData:bookmarkData
145 options:BookmarkOptionsFromFlags(flags)
146 relativeToURL:nil
147 bookmarkDataIsStale:&stale
148 error:NULL];
149 }
150 else staleIfFile = YES;
151 }
152
153 // Try alias.
154 if (result == nil)
155 {
156 NSData *aliasData = [fileRef objectForKey:kAliasKey];
157 if ([aliasData isKindOfClass:[NSData class]])
158 {
159 size_t size = [aliasData length];
160 AliasHandle alias = (AliasHandle)NewHandle(size);
161 if (alias != NULL)
162 {
163 memcpy(*alias, [aliasData bytes], size);
164 FSRef fsRef;
165
166 Boolean carbonStale;
167 if (FSResolveAliasWithMountFlags(NULL, alias, &fsRef, &carbonStale, AliasMountFlagsFromFlags(flags)) == noErr)
168 {
169 stale = carbonStale;
170 result = (NSURL *)CFURLCreateFromFSRef(kCFAllocatorDefault, &fsRef);
171#if 1050 <= MAC_OS_X_VERSION_MAX_ALLOWED
172 CFMakeCollectable((CFURLRef)result);
173#endif
174 [result autorelease];
175 }
176 DisposeHandle((Handle)alias);
177 }
178 }
179 else staleIfFile = YES;
180 }
181
182 // Try URL.
183 if (result == nil)
184 {
185 NSString *urlString = [fileRef objectForKey:kURLKey];
186 if ([urlString isKindOfClass:[NSString class]])
187 {
188 result = [NSURL URLWithString:urlString relativeToURL:nil];
189 if ([result isFileURL] && ![[NSFileManager defaultManager] fileExistsAtPath:[result path]])
190 {
191 result = nil;
192 }
193 }
194 }
195
196 // If we got nothing, it's definitely stale.
197 if (result == nil)
198 {
199 stale = YES;
200 }
201 else
202 {
203 if ([result isFileURL] && staleIfFile) stale = YES;
204
205 // Convert to/from file reference URL as appropriate.
207 {
209 {
210 if (![result isFileReferenceURL] && [result isFileURL])
211 {
212 NSURL *refURL = [result fileReferenceURL];
213 if (refURL != nil) result = refURL;
214 }
215 }
216 else
217 {
218 if ([result isFileReferenceURL])
219 {
220 NSURL *pathURL = [result filePathURL];
221 if (pathURL != nil) result = pathURL;
222 }
223 }
224 }
225 }
226
227
228 if (isStale != NULL) *isStale = stale;
229 return result;
230}
231
232
233NSDictionary *JAPersistentFileReferenceFromPath(NSString *path)
234{
235 return JAPersistentFileReferenceFromURL([NSURL fileURLWithPath:path]);
236}
237
238
239NSString *JAPathFromPersistentFileReference(NSDictionary *fileRef, JAPersistentFileReferenceResolveFlags flags, BOOL *isStale)
240{
242 if ([url isFileURL]) return [url path];
243 return nil;
244}
@ kJAPersistentFileReferenceReturnReferenceURL
@ kJAPersistentFileReferenceWithoutUI
NSString * JAPathFromPersistentFileReference(NSDictionary *fileRef, JAPersistentFileReferenceResolveFlags flags, BOOL *isStale)
NSURL * JAURLFromPersistentFileReference(NSDictionary *fileRef, JAPersistentFileReferenceResolveFlags flags, BOOL *isStale)
NSDictionary * JAPersistentFileReferenceFromURL(NSURL *url)
NSDictionary * JAPersistentFileReferenceFromPath(NSString *path)
uint32_t JAPersistentFileReferenceResolveFlags
static unsigned long AliasMountFlagsFromFlags(JAPersistentFileReferenceResolveFlags flags)
#define BookmarkDataSupported()
static unsigned long BookmarkOptionsFromFlags(JAPersistentFileReferenceResolveFlags flags)
return nil
voidpf void uLong size
Definition ioapi.h:134