// // BJGTextIOHandler.m // Escape // // Created by Brent Gulanowski on 11/27/05. // Copyright 2005 Bored Astronaut Software. All rights reserved. // #import "BJGTextIOHandler.h" @interface BJGTextIOHandler (BJGTextIOHandler_private) -(void)receive; @end @implementation BJGTextIOHandler /** inheritance tree overrides **/ #pragma mark NSObject #if 0 /* remove the guards as necessary */ +(void)initialize { } #endif -(id)init { return [self initWithInputFile:nil outputFile:nil]; } /** new methods **/ #pragma mark BJGTextIOHandler -(id)initWithInputFile:(NSString *)inFile outputFile:(NSString *)outFile { [self setInputFile:inFile]; [self setOutputFile:outFile]; return self; } -(void)write:(NSString *)line { if(line) { [outputFH writeData:[line dataUsingEncoding:NSUTF8StringEncoding]]; } } -(void)setInputFile:(NSString *)inFile { inputFH = [[NSFileHandle fileHandleForReadingAtPath:inFile] retain]; if(nil == inputFH) { inputFH = [NSFileHandle fileHandleWithStandardInput]; } } -(void)setOutputFile:(NSString *)outFile { outputFH = [[NSFileHandle fileHandleForWritingAtPath:outFile] retain]; if(nil == outputFH) { outputFH = [NSFileHandle fileHandleWithStandardOutput]; } } -(id)delegate { return delegate; } -(void)setDelegate:(id)del { if(del) { if(NO == [del respondsToSelector:NSSelectorFromString(@"processInput:")]) { NSLog(@"Delegate must implement -processInput: method."); delegate = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; } else if (!delegate) { [[NSNotificationCenter defaultCenter] addObserver:self selector:NSSelectorFromString(@"receive") name:NSFileHandleDataAvailableNotification object:inputFH]; } } delegate = del; if(delegate) { [inputFH waitForDataInBackgroundAndNotify]; } } #pragma mark BJGTextIOHandler_private -(void)receive { NSData *data = [inputFH availableData]; /* should always be true if "-receive" is called */ if(delegate) { NSString *read; if(!data || [data length] == 0) { [delegate processInput:nil]; } else { read = [NSString stringWithCString:[data bytes] encoding:NSUTF8StringEncoding]; /* Workaround to clean up garbage attached to single-character input. Why is this happening? */ if('\n' == [read characterAtIndex:[read length] - 3]) { read = [read substringToIndex:[read length] - 2]; } read = [read stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; [self write:[delegate processInput:read]]; } } if(delegate) { [inputFH waitForDataInBackgroundAndNotify]; } } @end