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

Last change on this file since 618 was 557, checked in by Nicholas Riley, 15 years ago

Fix leak in BDAlias.

File size: 8.6 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 CFRelease(tempURL);
110
111 if (gotRef == false) {
112 return fnfErr;
113 }
114
115 return noErr;
116}
117
118static CFStringRef FSRefToPathCopy(const FSRef *inRef)
119{
120 CFURLRef tempURL = NULL;
121 CFStringRef result = NULL;
122
123 if (inRef != NULL) {
124 tempURL = CFURLCreateFromFSRef(kCFAllocatorDefault, inRef);
125
126 if (tempURL == NULL) {
127 return NULL;
128 }
129
130 result = CFURLCopyFileSystemPath(tempURL, kCFURLPOSIXPathStyle);
131
132 CFRelease(tempURL);
133 }
134
135 return result;
136}
137
138
139@implementation BDAlias
140
141- (id)initWithAliasHandle:(AliasHandle)alias
142{
143 id ret = [super init];
144
145 if (ret != nil) {
146 _alias = alias;
147 }
148
149 return ret;
150}
151
152- (id)initWithData:(NSData *)data
153{
154 return [self initWithAliasHandle:(AliasHandle)DataToHandle((CFDataRef) data)];
155}
156
157- (id)initWithPath:(NSString *)fullPath
158{
159 OSStatus anErr = noErr;
160 FSRef ref;
161
162 anErr = PathToFSRef((CFStringRef) fullPath, &ref);
163
164 if (anErr != noErr) {
165 return nil;
166 }
167
168 return [self initWithFSRef:&ref];;
169}
170
171- (id)initWithPath:(NSString *)path relativeToPath:(NSString *)relPath
172{
173 OSStatus anErr = noErr;
174 FSRef ref, relRef;
175
176 anErr = PathToFSRef((CFStringRef) [relPath stringByAppendingPathComponent:path],
177 &ref);
178
179 if (anErr != noErr) {
180 return nil;
181 }
182
183 anErr = PathToFSRef((CFStringRef) relPath, &relRef);
184
185 if (anErr != noErr) {
186 return nil;
187 }
188
189 return [self initWithFSRef:&ref relativeToFSRef:&relRef];
190}
191
192- (id)initWithFSRef:(FSRef *)ref
193{
194 return [self initWithFSRef:ref relativeToFSRef:NULL];
195}
196
197- (id)initWithFSRef:(FSRef *)ref relativeToFSRef:(FSRef *)relRef
198{
199 OSStatus anErr = noErr;
200 AliasHandle alias = NULL;
201
202 anErr = FSNewAlias(relRef, ref, &alias);
203
204 if (anErr != noErr) {
205 return nil;
206 }
207
208 return [self initWithAliasHandle:alias];
209}
210
211- (void)dealloc
212{
213 if (_alias != NULL) {
214 DisposeHandle((Handle) _alias);
215 _alias = NULL;
216 }
217
218 [super dealloc];
219}
220
221- (AliasHandle)alias
222{
223 return _alias;
224}
225
226- (void)setAlias:(AliasHandle)newAlias
227{
228 if (_alias != NULL) {
229 DisposeHandle((Handle) _alias);
230 }
231
232 _alias = newAlias;
233}
234
235- (NSData *)aliasData
236{
237 NSData *result;
238
239 result = (NSData *)HandleToData((Handle) _alias);
240
241 return [result autorelease];
242}
243
244- (void)setAliasData:(NSData *)newAliasData
245{
246 [self setAlias:(AliasHandle) DataToHandle((CFDataRef) newAliasData)];
247}
248
249- (NSString *)displayNameWithKindString:(NSString **)outKindString;
250{
251 AliasHandle alias = [self alias];
252 FSRef ref;
253 Boolean wasChanged;
254 CFStringRef name;
255
256 if (alias == NULL) return nil;
257 if (FSResolveAlias(NULL, alias, &ref, &wasChanged) != noErr) return nil;
258
259 if (LSCopyDisplayNameForRef(&ref, &name) != noErr) return nil;
260 [(NSString *)name autorelease];
261
262 if (outKindString != NULL) {
263 if (LSCopyKindStringForRef(&ref, (CFStringRef *)outKindString) != noErr) return nil;
264 [*outKindString autorelease];
265 }
266
267 return (NSString *)name;
268}
269
270- (NSString *)fullPath
271{
272 return [self fullPathRelativeToPath:nil];
273}
274
275- (NSString *)fullPathRelativeToPath:(NSString *)relPath
276{
277 OSStatus anErr = noErr;
278 FSRef relPathRef;
279 FSRef tempRef;
280 NSString *result = nil;
281 Boolean wasChanged;
282
283 if (_alias != NULL) {
284 if (relPath != nil) {
285 anErr = PathToFSRef((CFStringRef)relPath, &relPathRef);
286
287 if (anErr != noErr) {
288 return NULL;
289 }
290
291 anErr = FSResolveAlias(&relPathRef, _alias, &tempRef, &wasChanged);
292 } else {
293 anErr = FSResolveAlias(NULL, _alias, &tempRef, &wasChanged);
294 }
295
296 if (anErr != noErr) {
297 return NULL;
298 }
299
300 result = (NSString *)FSRefToPathCopy(&tempRef);
301 }
302
303 return [result autorelease];
304}
305
306- (BOOL)aliasIsEqual:(AliasHandle)otherAlias;
307{
308 AliasHandle alias = [self alias];
309 FSRef ref, otherRef;
310 Boolean wasChanged;
311
312 if (alias == otherAlias) return YES;
313 if (alias == NULL || otherAlias == NULL) return NO;
314 if (FSResolveAlias(NULL, alias, &ref, &wasChanged) != noErr) return NO;
315 if (FSResolveAlias(NULL, otherAlias, &otherRef, &wasChanged) != noErr) return NO;
316 return (FSCompareFSRefs(&ref, &otherRef) == noErr);
317}
318
319- (BOOL)aliasDataIsEqual:(NSData *)data;
320{
321 BOOL result;
322 AliasHandle otherAlias = (AliasHandle)DataToHandle((CFDataRef)data);
323 result = [self aliasIsEqual: otherAlias];
324 DisposeHandle((Handle)otherAlias);
325 return result;
326}
327
328- (BOOL)isEqual:(id)object;
329{
330 if (![object isKindOfClass: [BDAlias class]]) return NO;
331 return [self aliasIsEqual: [object alias]];
332}
333
334+ (BDAlias *)aliasWithAliasHandle:(AliasHandle)alias
335{
336 return [[[BDAlias alloc] initWithAliasHandle:alias] autorelease];
337}
338
339+ (BDAlias *)aliasWithData:(NSData *)data
340{
341 return [[[BDAlias alloc] initWithData:data] autorelease];
342}
343
344+ (BDAlias *)aliasWithPath:(NSString *)fullPath
345{
346 return [[[BDAlias alloc] initWithPath:fullPath] autorelease];
347}
348
349+ (BDAlias *)aliasWithPath:(NSString *)path relativeToPath:(NSString *)relPath
350{
351 return [[[BDAlias alloc] initWithPath:path relativeToPath:relPath] autorelease];
352}
353
354+ (BDAlias *)aliasWithFSRef:(FSRef *)ref
355{
356 return [[[BDAlias alloc] initWithFSRef:ref] autorelease];
357}
358
359+ (BDAlias *)aliasWithFSRef:(FSRef *)ref relativeToFSRef:(FSRef *)relRef
360{
361 return [[[BDAlias alloc] initWithFSRef:ref relativeToFSRef:relRef] autorelease];
362}
363
364@end
Note: See TracBrowser for help on using the repository browser.