1 | /*
|
---|
2 | * NDResourceFork.m
|
---|
3 | *
|
---|
4 | * Created by nathan on Wed Dec 05 2001.
|
---|
5 | * Copyright (c) 2001 Nathan Day. All rights reserved.
|
---|
6 | *
|
---|
7 | * Currently ResourceFork will not add resource forks to files
|
---|
8 | * or create new files with resource forks
|
---|
9 | *
|
---|
10 | */
|
---|
11 |
|
---|
12 | #import "NDResourceFork.h"
|
---|
13 | #import "NSURL+NDCarbonUtilities.h"
|
---|
14 |
|
---|
15 | @implementation NDResourceFork
|
---|
16 |
|
---|
17 | /*
|
---|
18 | * resourceForkForReadingAtURL:
|
---|
19 | */
|
---|
20 | + (id)resourceForkForReadingAtURL:(NSURL *)aURL
|
---|
21 | {
|
---|
22 | return [[[self alloc] initForReadingAtURL:aURL] autorelease];
|
---|
23 | }
|
---|
24 |
|
---|
25 | /*
|
---|
26 | * resourceForkForWritingAtURL:
|
---|
27 | */
|
---|
28 | + (id)resourceForkForWritingAtURL:(NSURL *)aURL
|
---|
29 | {
|
---|
30 | return [[[self alloc] initForWritingAtURL:aURL] autorelease];
|
---|
31 | }
|
---|
32 |
|
---|
33 | /*
|
---|
34 | * resourceForkForReadingAtPath:
|
---|
35 | */
|
---|
36 | + (id)resourceForkForReadingAtPath:(NSString *)aPath
|
---|
37 | {
|
---|
38 | return [[[self alloc] initForReadingAtPath:aPath] autorelease];
|
---|
39 | }
|
---|
40 |
|
---|
41 | /*
|
---|
42 | * resourceForkForWritingAtPath:
|
---|
43 | */
|
---|
44 | + (id)resourceForkForWritingAtPath:(NSString *)aPath
|
---|
45 | {
|
---|
46 | return [[[self alloc] initForWritingAtPath:aPath] autorelease];
|
---|
47 | }
|
---|
48 |
|
---|
49 | /*
|
---|
50 | * initForReadingAtURL:
|
---|
51 | */
|
---|
52 | - (id)initForReadingAtURL:(NSURL *)aURL
|
---|
53 | {
|
---|
54 | return [self initForPermission:fsRdPerm AtURL:aURL];
|
---|
55 | }
|
---|
56 |
|
---|
57 | /*
|
---|
58 | * initForWritingAtURL:
|
---|
59 | */
|
---|
60 | - (id)initForWritingAtURL:(NSURL *)aURL
|
---|
61 | {
|
---|
62 | return [self initForPermission:fsWrPerm AtURL:aURL];
|
---|
63 | }
|
---|
64 |
|
---|
65 | /*
|
---|
66 | * initForPermission:AtURL:
|
---|
67 | */
|
---|
68 | - (id)initForPermission:(char)aPermission AtURL:(NSURL *)aURL
|
---|
69 | {
|
---|
70 | OSErr theError = noErr;
|
---|
71 | FSRef theFsRef;
|
---|
72 | FSSpec theFSSpec;
|
---|
73 |
|
---|
74 | if( ( self = [self init] ) && [aURL getFSRef:&theFsRef] )
|
---|
75 | {
|
---|
76 | if( (aPermission & 0x06) != 0 && FSGetCatalogInfo( &theFsRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL ) == noErr ) // if write permission and we can get a FSSpec, then create fork
|
---|
77 | {
|
---|
78 | OSType theCreatorCode,
|
---|
79 | theFileTypeCode;
|
---|
80 | NSDictionary * theFileAttributes;
|
---|
81 |
|
---|
82 | /*
|
---|
83 | * we don't want to change the file type creator codes
|
---|
84 | */
|
---|
85 | theFileAttributes = [[NSFileManager defaultManager] fileSystemAttributesAtPath:[aURL path]];
|
---|
86 | theCreatorCode = [theFileAttributes fileHFSCreatorCode];
|
---|
87 | theFileTypeCode = [theFileAttributes fileHFSTypeCode];
|
---|
88 |
|
---|
89 | FSpCreateResFile( &theFSSpec, theCreatorCode, theFileTypeCode, smRoman ); // doesn't replace fork if already exists
|
---|
90 |
|
---|
91 | theError = ResError( );
|
---|
92 | }
|
---|
93 |
|
---|
94 |
|
---|
95 | if( theError == noErr || theError == dupFNErr )
|
---|
96 | {
|
---|
97 | fileReference = FSOpenResFile ( &theFsRef, aPermission );
|
---|
98 |
|
---|
99 | theError = fileReference > 0 ? ResError( ) : !noErr;
|
---|
100 | }
|
---|
101 | }
|
---|
102 |
|
---|
103 | if( noErr != theError )
|
---|
104 | {
|
---|
105 | [self release];
|
---|
106 | self = nil;
|
---|
107 | }
|
---|
108 |
|
---|
109 | return self;
|
---|
110 | }
|
---|
111 |
|
---|
112 | /*
|
---|
113 | * initForReadingAtPath:
|
---|
114 | */
|
---|
115 | - (id)initForReadingAtPath:(NSString *)aPath
|
---|
116 | {
|
---|
117 | if( [[NSFileManager defaultManager] fileExistsAtPath:aPath] )
|
---|
118 | return [self initForPermission:fsRdPerm AtURL:[NSURL fileURLWithPath:aPath]];
|
---|
119 | else
|
---|
120 | return nil;
|
---|
121 | }
|
---|
122 |
|
---|
123 | /*
|
---|
124 | * initForWritingAtPath:
|
---|
125 | */
|
---|
126 | - (id)initForWritingAtPath:(NSString *)aPath
|
---|
127 | {
|
---|
128 | return [self initForPermission:fsWrPerm AtURL:[NSURL fileURLWithPath:aPath]];
|
---|
129 | }
|
---|
130 |
|
---|
131 | /*
|
---|
132 | * dealloc
|
---|
133 | */
|
---|
134 | - (void)dealloc
|
---|
135 | {
|
---|
136 | CloseResFile( fileReference );
|
---|
137 | }
|
---|
138 |
|
---|
139 | - (BOOL)addData:(NSData *)aData type:(ResType)aType Id:(short)anID name:(NSString *)aName
|
---|
140 | {
|
---|
141 | Handle theResHandle;
|
---|
142 |
|
---|
143 | if( [self removeType:aType Id:anID] )
|
---|
144 | {
|
---|
145 | short thePreviousRefNum;
|
---|
146 |
|
---|
147 | thePreviousRefNum = CurResFile(); // save current resource
|
---|
148 | UseResFile( fileReference ); // set this resource to be current
|
---|
149 |
|
---|
150 | // copy NSData's bytes to a handle
|
---|
151 | if ( noErr == PtrToHand ( [aData bytes], &theResHandle, [aData length] ) )
|
---|
152 | {
|
---|
153 | Str255 thePName;
|
---|
154 |
|
---|
155 | CopyCStringToPascal ( [aName lossyCString], thePName );
|
---|
156 |
|
---|
157 | HLock( theResHandle );
|
---|
158 | AddResource( theResHandle, aType, anID, thePName );
|
---|
159 | HUnlock( theResHandle );
|
---|
160 |
|
---|
161 | UseResFile( thePreviousRefNum ); // reset back to resource previously set
|
---|
162 |
|
---|
163 | // DisposeHandle( theResHandle );
|
---|
164 | return ( ResError( ) == noErr );
|
---|
165 | }
|
---|
166 | }
|
---|
167 |
|
---|
168 | return NO;
|
---|
169 | }
|
---|
170 |
|
---|
171 | /*
|
---|
172 | * dataForType:Id:
|
---|
173 | */
|
---|
174 | - (NSData *)dataForType:(ResType)aType Id:(short)anID
|
---|
175 | {
|
---|
176 | NSData * theData = nil;
|
---|
177 | Handle theResHandle;
|
---|
178 | short thePreviousRefNum;
|
---|
179 |
|
---|
180 | thePreviousRefNum = CurResFile(); // save current resource
|
---|
181 |
|
---|
182 | UseResFile( fileReference ); // set this resource to be current
|
---|
183 |
|
---|
184 | theResHandle = Get1Resource( aType, anID );
|
---|
185 |
|
---|
186 | if ( noErr == ResError( ) && theResHandle != NULL )
|
---|
187 | {
|
---|
188 | HLock(theResHandle);
|
---|
189 | theData = [NSData dataWithBytes:*theResHandle length:GetHandleSize( theResHandle )];
|
---|
190 | HUnlock(theResHandle);
|
---|
191 | }
|
---|
192 |
|
---|
193 | if ( theResHandle )
|
---|
194 | ReleaseResource( theResHandle );
|
---|
195 |
|
---|
196 | UseResFile( thePreviousRefNum ); // reset back to resource previously set
|
---|
197 |
|
---|
198 | return theData;
|
---|
199 | }
|
---|
200 |
|
---|
201 | /*
|
---|
202 | * removeType: Id:
|
---|
203 | */
|
---|
204 | - (BOOL)removeType:(ResType)aType Id:(short)anID
|
---|
205 | {
|
---|
206 | Handle theResHandle;
|
---|
207 | OSErr theError;
|
---|
208 |
|
---|
209 | UseResFile( fileReference ); // set this resource to be current
|
---|
210 |
|
---|
211 | theResHandle = Get1Resource( aType, anID );
|
---|
212 | theError = ResError( );
|
---|
213 | if( theResHandle != NULL && theError == noErr )
|
---|
214 | {
|
---|
215 | RemoveResource( theResHandle ); // Disposed of in current resource file
|
---|
216 | theError = ResError( );
|
---|
217 | }
|
---|
218 |
|
---|
219 | return theError == noErr;
|
---|
220 | }
|
---|
221 |
|
---|
222 | @end
|
---|