This is FileRetriever.m in view mode; [Download] [Up]
// FileRetriever.m // By Charles G. Fleming and Judy D. Halchin, // Educational Computing Services, Allegheny College. // Copyright 1992, 1993 Allegheny College // You may freely copy, distribute and reuse this code. // Allegheny College and the authors disclaim any warranty of any kind, // expressed or implied, as to its fitness for any particular use. // This work was partially supported by a grant from the Pew Charitable Trusts // and by an NSF Teacher Preparation Grant. #import "SaverAndRetriever.h" #import <objc/error.h> #import <appkit/OpenPanel.h> #import <appkit/Application.h> #import <stdlib.h> #import <strings.h> @implementation FileRetriever - (const char *)getInspectorClassName { return "FileSaverAndRetrieverInspector"; } // Initially the filename is the empty string, and the delegate and // dataDelegate are nil. - init { self = [super init]; filename = (char *)malloc(MAXPATHLEN + 1); directory = (char *)malloc(MAXPATHLEN + 1); strcpy(filename, ""); strcpy(directory, NXHomeDirectory()); return self; } - setDelegate:anObject { delegate = anObject; return self; } - setDataDelegate:anObject { dataDelegate = anObject; return self; } - setFileSaver:anObject { fileSaver = anObject; return self; } // Returns the file saver's delegate. - delegate { return delegate; } // Returns the file saver's dataDelegate. - dataDelegate { return dataDelegate; } // Returns the fileSaver with which this fileRetriever works - fileSaver { return fileSaver; } - setFilename:(char *)name { strcpy(filename, name); return self; } - setDirectory:(char *)path { strcpy(directory, path); return self; } - (char *)filename { return filename; } - (char *)directory { return directory; } // Run an open panel. If the cancel button is not pushed, call open. - open:sender { OpenPanel *openPanel = [OpenPanel new]; char tempFilename[MAXPATHLEN], *lastSlash; int count; // Try to run an open panel. If not possible, raise an exception. [openPanel allowMultipleFiles:NO]; if([openPanel runModalForDirectory:directory file:filename]) { strcpy(tempFilename, [openPanel filename]); // Split the filename into directory and file lastSlash = strrchr(tempFilename, '/'); strcpy(filename, lastSlash + 1); if(lastSlash == tempFilename) { count = 1; directory[1] = '\0'; } else { count = lastSlash - tempFilename; directory[lastSlash - tempFilename] = '\0'; } strncpy(directory, tempFilename, count); [self open]; } else if([delegate respondsTo: @selector(dataWasRead:success:errorCode:)]) [delegate dataWasRead:self success:NO errorCode:cancelButtonPushed]; return self; } // Open and read the file specified by the filename and directory instance // variables. The dataDelegate must read the data from the stream provided. // Any errors that occur will be handled by an exception handler. - (BOOL)open { NXStream *stream = NULL; char fullPath[MAXPATHLEN]; BOOL fileOpened = NO; NX_DURING; // begin exception handling zone if(strcmp(filename, "") != 0) { // Raise an exception if we don't have a dataDelegate or if it // doesn't respond to ReadDataFromStream; if(dataDelegate == nil) NX_RAISE(noDataDelegate, self, delegate); if(![dataDelegate respondsTo:@selector(readDataFromStream:)]) NX_RAISE(doesNotRespondToMethod, self, delegate); // If the directory variable is empty, we'll use the user's // home directory. if(strcmp(directory, "") == 0) strcpy(directory, NXHomeDirectory()); // Try to open the file. Raise exception if not possible. sprintf(fullPath, "%s/%s", directory, filename); stream = NXMapFile(fullPath, NX_READONLY); if (stream == NULL) NX_RAISE(noStream, self, delegate); // Send the dataDelegate a readDataFromStream: message. if (![dataDelegate readDataFromStream:stream]) NX_RAISE(dataNotRead, self, delegate); // If all went well, tell the delegate that the data has been read if([delegate respondsTo:@selector(dataWasRead:success:errorCode:)]) [delegate dataWasRead:self success:YES errorCode:noError]; if([fileSaver respondsTo:@selector(setFilename:)]) [fileSaver setFilename:filename]; if([fileSaver respondsTo:@selector(setDirectory:)]) [(FileSaver *)fileSaver setDirectory:directory]; fileOpened = YES; } else if([delegate respondsTo: @selector(dataWasRead:success:errorCode:)]) [delegate dataWasRead:self success:NO errorCode:noFile]; // Here's the error handler. NX_HANDLER switch(NXLocalHandler.code) { case noStream: if([(id)NXLocalHandler.data2 respondsTo: @selector(dataWasRead:success:errorCode:)]) [(id)NXLocalHandler.data2 dataWasRead:(id)NXLocalHandler.data1 success:NO errorCode:noStream]; break; case noDataDelegate: if([(id)NXLocalHandler.data2 respondsTo: @selector(dataWasRead:success:errorCode:)]) [(id)NXLocalHandler.data2 dataWasRead:(id)NXLocalHandler.data1 success:NO errorCode:noDataDelegate]; break; case doesNotRespondToMethod: if([(id)NXLocalHandler.data2 respondsTo: @selector(dataWasRead:success:errorCode:)]) [(id)NXLocalHandler.data2 dataWasRead:(id)NXLocalHandler.data1 success:NO errorCode:doesNotRespondToMethod]; break; case dataNotRead: if([(id)NXLocalHandler.data2 respondsTo: @selector(dataWasRead:success:errorCode:)]) [(id)NXLocalHandler.data2 dataWasRead:(id)NXLocalHandler.data1 success:NO errorCode:dataNotRead]; break; default: NX_RERAISE(); break; } NX_ENDHANDLER; // Close the stream. if(stream) NXCloseMemory(stream, NX_FREEBUFFER); return fileOpened; } - write:(NXTypedStream *)typedStream { [super write:typedStream]; NXWriteTypes(typedStream, "**", &directory, &filename); return self; } - read:(NXTypedStream *)typedStream { char *tempDirectory, *tempFilename; filename = (char *)malloc(MAXPATHLEN + 1); directory = (char *)malloc(MAXPATHLEN + 1); [super read:typedStream]; NXReadTypes(typedStream, "**", &tempDirectory, &tempFilename); strcpy(filename, tempFilename); strcpy(directory, tempDirectory); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.