source: trunk/Cocoa/Pester/Source/BDAlias.m@ 536

Last change on this file since 536 was 53, checked in by Nicholas Riley, 22 years ago

Updated for Pester 1.1a5 (very limited release).

Pester 1.1a4 was never released.

File size: 8.8 KB
Line 
1/*
2 Copyright (c) 2001, bDistributed.com, Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or
6 without modification, are permitted provided that the following
7 conditions are met:
8
9 * Redistributions of source code must retain the above
10 copyright notice, this list of conditions and the following
11 disclaimer.
12
13 * Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following
15 disclaimer in the documentation and/or other materials
16 provided with the distribution.
17
18 * Neither the name of bDistributed.com, Inc. nor the names of
19 its contributors may be used to endorse or promote products
20 derived from this software without specific prior written
21 permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
28 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
29 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
31 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36*/
37
38#include <assert.h>
39
40#import "BDAlias.h"
41
42
43static Handle DataToHandle(CFDataRef inData);
44static CFDataRef HandleToData(Handle inHandle);
45
46static OSStatus PathToFSRef(CFStringRef inPath, FSRef *outRef);
47static CFStringRef FSRefToPathCopy(const FSRef *inRef);
48
49
50static Handle DataToHandle(CFDataRef inData)
51{
52 CFIndex len;
53 Handle handle = NULL;
54
55 if (inData == NULL) {
56 return NULL;
57 }
58
59 len = CFDataGetLength(inData);
60
61 handle = NewHandle(len);
62
63 if ((handle != NULL) && (len > 0)) {
64 HLock(handle);
65 BlockMoveData(CFDataGetBytePtr(inData), *handle, len);
66 HUnlock(handle);
67 }
68
69 return handle;
70}
71
72static CFDataRef HandleToData(Handle inHandle)
73{
74 CFDataRef data = NULL;
75 CFIndex len;
76 SInt8 handleState;
77
78 if (inHandle == NULL) {
79 return NULL;
80 }
81
82 len = GetHandleSize(inHandle);
83
84 handleState = HGetState(inHandle);
85
86 HLock(inHandle);
87
88 data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *) *inHandle, len);
89
90 HSetState(inHandle, handleState);
91
92 return data;
93}
94
95static OSStatus PathToFSRef(CFStringRef inPath, FSRef *outRef)
96{
97 CFURLRef tempURL = NULL;
98 Boolean gotRef = false;
99
100 tempURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, inPath,
101 kCFURLPOSIXPathStyle, false);
102
103 if (tempURL == NULL) {
104 return fnfErr;
105 }
106
107 gotRef = CFURLGetFSRef(tempURL, outRef);
108
109 if (gotRef == false) {
110 return fnfErr;
111 }
112
113 return noErr;
114}
115
116static CFStringRef FSRefToPathCopy(const FSRef *inRef)
117{
118 CFURLRef tempURL = NULL;
119 CFStringRef result = NULL;
120
121 if (inRef != NULL) {
122 tempURL = CFURLCreateFromFSRef(kCFAllocatorDefault, inRef);
123
124 if (tempURL == NULL) {
125 return NULL;
126 }
127
128 result = CFURLCopyFileSystemPath(tempURL, kCFURLPOSIXPathStyle);
129
130 CFRelease(tempURL);
131 }
132
133 return result;
134}
135
136
137@implementation BDAlias
138
139- (id)initWithAliasHandle:(AliasHandle)alias
140{
141 id ret = [super init];
142
143 if (ret != nil) {
144 _alias = alias;
145 }
146
147 return ret;
148}
149
150- (id)initWithData:(NSData *)data
151{
152 return [self initWithAliasHandle:(AliasHandle)DataToHandle((CFDataRef) data)];
153}
154
155- (id)initWithPath:(NSString *)fullPath
156{
157 OSStatus anErr = noErr;
158 FSRef ref;
159
160 anErr = PathToFSRef((CFStringRef) fullPath, &ref);
161
162 if (anErr != noErr) {
163 return nil;
164 }
165
166 return [self initWithFSRef:&ref];;
167}
168
169- (id)initWithPath:(NSString *)path relativeToPath:(NSString *)relPath
170{
171 OSStatus anErr = noErr;
172 FSRef ref, relRef;
173
174 anErr = PathToFSRef((CFStringRef) [relPath stringByAppendingPathComponent:path],
175 &ref);
176
177 if (anErr != noErr) {
178 return nil;
179 }
180
181 anErr = PathToFSRef((CFStringRef) relPath, &relRef);
182
183 if (anErr != noErr) {
184 return nil;
185 }
186
187 return [self initWithFSRef:&ref relativeToFSRef:&relRef];
188}
189
190- (id)initWithFSRef:(FSRef *)ref
191{
192 return [self initWithFSRef:ref relativeToFSRef:NULL];
193}
194
195- (id)initWithFSRef:(FSRef *)ref relativeToFSRef:(FSRef *)relRef
196{
197 OSStatus anErr = noErr;
198 AliasHandle alias = NULL;
199
200 anErr = FSNewAlias(relRef, ref, &alias);
201
202 if (anErr != noErr) {
203 return nil;
204 }
205
206 return [self initWithAliasHandle:alias];
207}
208
209- (void)dealloc
210{
211 if (_alias != NULL) {
212 DisposeHandle((Handle) _alias);
213 _alias = NULL;
214 }
215
216 [super dealloc];
217}
218
219- (AliasHandle)alias
220{
221 return _alias;
222}
223
224- (void)setAlias:(AliasHandle)newAlias
225{
226 if (_alias != NULL) {
227 DisposeHandle((Handle) _alias);
228 }
229
230 _alias = newAlias;
231}
232
233- (NSData *)aliasData
234{
235 NSData *result;
236
237 result = (NSData *)HandleToData((Handle) _alias);
238
239 return [result autorelease];
240}
241
242- (void)setAliasData:(NSData *)newAliasData
243{
244 [self setAlias:(AliasHandle) DataToHandle((CFDataRef) newAliasData)];
245}
246
247- (NSString *)displayNameWithKindString:(NSString **)outKindString;
248{
249 AliasHandle alias = [self alias];
250 FSRef ref;
251 Boolean wasChanged;
252 CFStringRef name;
253
254 if (alias == NULL) return nil;
255 if (FSResolveAlias(NULL, alias, &ref, &wasChanged) != noErr) return nil;
256
257 if (LSCopyDisplayNameForRef(&ref, &name) != noErr) return nil;
258 [(NSString *)name autorelease];
259
260 if (outKindString != NULL) {
261 if (LSCopyKindStringForRef(&ref, (CFStringRef *)outKindString) != noErr) return nil;
262 [*outKindString autorelease];
263 }
264
265 return (NSString *)name;
266}
267
268- (NSString *)fullPath
269{
270 return [self fullPathRelativeToPath:nil];
271}
272
273- (NSString *)fullPathRelativeToPath:(NSString *)relPath
274{
275 OSStatus anErr = noErr;
276 FSRef relPathRef;
277 FSRef tempRef;
278 NSString *result = nil;
279 Boolean wasChanged;
280
281 if (_alias != NULL) {
282 if (relPath != nil) {
283 anErr = PathToFSRef((CFStringRef)relPath, &relPathRef);
284
285 if (anErr != noErr) {
286 return NULL;
287 }
288
289 anErr = FSResolveAlias(&relPathRef, _alias, &tempRef, &wasChanged);
290 } else {
291 anErr = FSResolveAlias(NULL, _alias, &tempRef, &wasChanged);
292 }
293
294 if (anErr != noErr) {
295 return NULL;
296 }
297
298 result = (NSString *)FSRefToPathCopy(&tempRef);
299 }
300
301 return [result autorelease];
302}
303
304- (BOOL)aliasIsEqual:(AliasHandle)otherAlias;
305{
306 AliasHandle alias = [self alias];
307 FSRef ref, otherRef;
308 Boolean wasChanged;
309
310 if (alias == otherAlias) return YES;
311 if (alias == NULL || otherAlias == NULL) return NO;
312 if (FSResolveAlias(NULL, alias, &ref, &wasChanged) != noErr) return NO;
313 if (FSResolveAlias(NULL, otherAlias, &otherRef, &wasChanged) != noErr) return NO;
314 return (FSCompareFSRefs(&ref, &otherRef) == noErr);
315}
316
317- (BOOL)aliasDataIsEqual:(NSData *)data;
318{
319 AliasHandle otherAlias;
320 const UInt8 *aliasPtr = CFDataGetBytePtr((CFDataRef)data);
321 BOOL result;
322 if (aliasPtr == NULL) {
323 otherAlias = (AliasHandle)DataToHandle((CFDataRef)data);
324 } else {
325 otherAlias = (AliasHandle)&aliasPtr;
326 }
327 result = [self aliasIsEqual: otherAlias];
328 if (aliasPtr == NULL) DisposeHandle((Handle)otherAlias);
329 return result;
330}
331
332- (BOOL)isEqual:(id)object;
333{
334 if (![object isKindOfClass: [BDAlias class]]) return NO;
335 return [self aliasIsEqual: [object alias]];
336}
337
338+ (BDAlias *)aliasWithAliasHandle:(AliasHandle)alias
339{
340 return [[[BDAlias alloc] initWithAliasHandle:alias] autorelease];
341}
342
343+ (BDAlias *)aliasWithData:(NSData *)data
344{
345 return [[[BDAlias alloc] initWithData:data] autorelease];
346}
347
348+ (BDAlias *)aliasWithPath:(NSString *)fullPath
349{
350 return [[[BDAlias alloc] initWithPath:fullPath] autorelease];
351}
352
353+ (BDAlias *)aliasWithPath:(NSString *)path relativeToPath:(NSString *)relPath
354{
355 return [[[BDAlias alloc] initWithPath:path relativeToPath:relPath] autorelease];
356}
357
358+ (BDAlias *)aliasWithFSRef:(FSRef *)ref
359{
360 return [[[BDAlias alloc] initWithFSRef:ref] autorelease];
361}
362
363+ (BDAlias *)aliasWithFSRef:(FSRef *)ref relativeToFSRef:(FSRef *)relRef
364{
365 return [[[BDAlias alloc] initWithFSRef:ref relativeToFSRef:relRef] autorelease];
366}
367
368@end
Note: See TracBrowser for help on using the repository browser.