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.