source: releases/Pester/1.1a1/Source/BDAlias.m@ 490

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

Lots of wonderful changes for which I composed a detailed svn commit
message, which it proceeded to mangle yet AGAIN on failed commit.

File size: 8.2 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 *)fullPath
248{
249 return [self fullPathRelativeToPath:nil];
250}
251
252- (NSString *)fullPathRelativeToPath:(NSString *)relPath
253{
254 OSStatus anErr = noErr;
255 FSRef relPathRef;
256 FSRef tempRef;
257 NSString *result = nil;
258 Boolean wasChanged;
259
260 if (_alias != NULL) {
261 if (relPath != nil) {
262 anErr = PathToFSRef((CFStringRef)relPath, &relPathRef);
263
264 if (anErr != noErr) {
265 return NULL;
266 }
267
268 anErr = FSResolveAlias(&relPathRef, _alias, &tempRef, &wasChanged);
269 } else {
270 anErr = FSResolveAlias(NULL, _alias, &tempRef, &wasChanged);
271 }
272
273 if (anErr != noErr) {
274 return NULL;
275 }
276
277 result = (NSString *)FSRefToPathCopy(&tempRef);
278 }
279
280 return [result autorelease];
281}
282
283- (BOOL)aliasIsEqual:(AliasHandle)otherAlias;
284{
285 AliasHandle alias = [self alias];
286 FSRef ref, otherRef;
287 Boolean wasChanged;
288
289 if (alias == otherAlias) return YES;
290 if (alias == NULL || otherAlias == NULL) return NO;
291 if (FSResolveAlias(NULL, alias, &ref, &wasChanged) != noErr) return NO;
292 if (FSResolveAlias(NULL, otherAlias, &otherRef, &wasChanged) != noErr) return NO;
293 return (FSCompareFSRefs(&ref, &otherRef) == noErr);
294}
295
296- (BOOL)aliasDataIsEqual:(NSData *)data;
297{
298 AliasHandle otherAlias;
299 const UInt8 *aliasPtr = CFDataGetBytePtr((CFDataRef)data);
300 BOOL result;
301 if (aliasPtr == NULL) {
302 otherAlias = (AliasHandle)DataToHandle((CFDataRef)data);
303 } else {
304 otherAlias = (AliasHandle)&aliasPtr;
305 }
306 result = [self aliasIsEqual: otherAlias];
307 if (aliasPtr == NULL) DisposeHandle((Handle)otherAlias);
308 return result;
309}
310
311- (BOOL)isEqual:(id)object;
312{
313 if (![object isKindOfClass: [BDAlias class]]) return NO;
314 return [self aliasIsEqual: [object alias]];
315}
316
317+ (BDAlias *)aliasWithAliasHandle:(AliasHandle)alias
318{
319 return [[[BDAlias alloc] initWithAliasHandle:alias] autorelease];
320}
321
322+ (BDAlias *)aliasWithData:(NSData *)data
323{
324 return [[[BDAlias alloc] initWithData:data] autorelease];
325}
326
327+ (BDAlias *)aliasWithPath:(NSString *)fullPath
328{
329 return [[[BDAlias alloc] initWithPath:fullPath] autorelease];
330}
331
332+ (BDAlias *)aliasWithPath:(NSString *)path relativeToPath:(NSString *)relPath
333{
334 return [[[BDAlias alloc] initWithPath:path relativeToPath:relPath] autorelease];
335}
336
337+ (BDAlias *)aliasWithFSRef:(FSRef *)ref
338{
339 return [[[BDAlias alloc] initWithFSRef:ref] autorelease];
340}
341
342+ (BDAlias *)aliasWithFSRef:(FSRef *)ref relativeToFSRef:(FSRef *)relRef
343{
344 return [[[BDAlias alloc] initWithFSRef:ref relativeToFSRef:relRef] autorelease];
345}
346
347@end
Note: See TracBrowser for help on using the repository browser.