source: trunk/Cocoa/Pester/Source/NDAppleScript/NDResourceFork.m @ 35

Last change on this file since 35 was 35, checked in by Nicholas Riley, 19 years ago

Nathan Day's NDAppleScript and related classes, somewhat modified.
Still need to commit Nathan's changes to NDResourceFork.

File size: 5.3 KB
Line 
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
Note: See TracBrowser for help on using the repository browser.