//
#import <Foundation/Foundation.h>
-/*! @class ITByteStream
- * @abstract A FIFO bytestream
- */
+
+@class ITByteStream;
+
+@protocol ITByteStreamDelegate
+-(void)newDataAdded:(ITByteStream *)sender;
+@end
@interface ITByteStream : NSObject {
@public
NSMutableData *data;
@private
NSLock *lock;
+ id <ITByteStreamDelegate> delegate;
}
--(id) initWithStream:(ITByteStream*)stream;
+-(id) initWithStream:(ITByteStream*)stream delegate:(id <ITByteStreamDelegate>)d;
+-(id) initWithDelegate:(id <ITByteStreamDelegate>)d;
+-(void) setDelegate:(id <ITByteStreamDelegate>)d;
-(int) availableDataLength;
-(NSData*) readDataOfLength:(int)length;
-(NSData*) readAllData;
-(void) writeData:(in NSData*)data;
+-(void) writeBytes:(char *)b len:(long)length;
@end
{
data = [[NSMutableData alloc] init];
lock = [[NSLock alloc] init];
+ delegate = nil;
}
return self;
}
--(id) initWithStream:(ITByteStream*)stream
+-(id) initWithDelegate:(id)d
+{
+ if (self == [super init])
+ {
+ data = [[NSMutableData alloc] init];
+ lock = [[NSLock alloc] init];
+ delegate = [d retain];
+ }
+ return self;
+}
+
+-(id) initWithStream:(ITByteStream*)stream delegate:(id)d
{
if (self == [super init])
{
data = [stream->data copy];
lock = [[NSLock alloc] init];
+ delegate = [d retain];
}
return 0;
}
--(void) dealloc
+-(oneway void) dealloc
{
+ [lock lock];
[data release];
+ [lock unlock];
[lock release];
[super dealloc];
}
+-(void) setDelegate:(id <ITByteStreamDelegate>)d
+{
+ [delegate release];
+ delegate = [d retain];
+}
+
-(int) availableDataLength
{
int len;
return ret;
}
--(void) writeData:(NSData*)_data
+-(void) writeData:(in NSData*)_data
{
[lock lock];
[data appendData:_data];
[lock unlock];
+ [delegate newDataAdded:self];
+}
+
+-(void) writeBytes:(char *)b len:(long)length
+{
+ [lock lock];
+ [data appendBytes:b length:length];
+ [lock unlock];
+ [delegate newDataAdded:self];
}
@end
* @abstract Delegate methods for ITInetSocket
* @discussion ITInetSockets use these methods to communicate with their delegates
*/
-@protocol ITInetSocketDelegate
+@protocol ITInetSocketDelegate <ITByteStreamDelegate>
/*!
* @method dataReceived:
* @abstract Alerts the delegate of data.
* @discussion The delegate should check [sender readPipe] to get the data.
* @param sender The socket that the messages came from.
*/
-- (void) dataReceived:(in ITInetSocket *)sender;
+- (void) dataReceived:(ITInetSocket *)sender;
/*!
* @method errorOccured:during:onSocket:
* @abstract Alerts the delegate of an error condition.
* @param state What the socket was doing when the error occured.
* @param sender The socket the error occured on.
*/
-- (void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(in ITInetSocket*)sender;
+- (void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(ITInetSocket*)sender;
/*!
* @method finishedConnecting:
* @abstract Alerts the delegate of a successful connection attempt.
* @discussion The delegate should send whatever initial data is required for the protocol (nickname for IRC, etc.)
* @param sender The socket that established the connection.
*/
-- (void) finishedConnecting:(in ITInetSocket *)sender;
+- (void) finishedConnecting:(ITInetSocket *)sender;
@end
/*!
* @abstract An Internet socket class.
* @discussion ITInetSocket is an Internet socket class supporting IPv6 and Rendezvous.
*/
-@interface ITInetSocket : NSObject {
+@interface ITInetSocket : NSObject <ITByteStreamDelegate> {
@public
/*!
* @var sockfd
sockfd = fd;
delegate = [d retain];
port = 0;
- writePipe = [[ITByteStream alloc] init];
- readPipe = [[ITByteStream alloc] init];
+ writePipe = [[ITByteStream alloc] initWithDelegate:self];
+ readPipe = [[ITByteStream alloc] initWithDelegate:d];
ai = nil;
sarr = nil;
bufs = 512;
sockfd = -1;
delegate = [d retain];
port = 0;
- writePipe = [[ITByteStream alloc] init];
- readPipe = [[ITByteStream alloc] init];
+ writePipe = [[ITByteStream alloc] initWithDelegate:self];
+ readPipe = [[ITByteStream alloc] initWithDelegate:d];
ai = nil;
sarr = nil;
bufs = 512;
-(void)disconnect
{
+ NSLog(@"Got a disconnect");
dieflag = 1;
do {} while (dieflag == 1);
}
{
bufs = _bufs;
}
+
+-(void)newDataAdded:(ITByteStream*)sender
+{
+ NSLog(@"writePipe got something");
+ actionflag = 1;
+ NSLog(@"thread saw actionFlag");
+}
@end
@implementation ITInetSocket(Debugging)
{
NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init];
NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[data objectAtIndex:0] sendPort:[data objectAtIndex:1]];
- NSProxy *dp = [dcon rootProxy];
+ NSProxy *dp = [[dcon rootProxy] retain];
char *buf = malloc(bufs);
unsigned long readLen = 0;
signed int err;
- NSLog(@"EYE MAEK CONNECT");
+ [readPipe setDelegate:dp];
+ NSLog(@"Connecting");
err = connect(sockfd,ai_cur->ai_addr,ai_cur->ai_addrlen);
if (err == -1)
{
[(id)dp errorOccured:ITInetCouldNotConnect during:ITInetSocketConnecting onSocket:self];
goto dieaction;
}
+ NSLog(@"Sending finishedConnecting");
[(id)dp finishedConnecting:self];
lstart:
- while (!actionflag && ![writePipe availableDataLength] && !dieflag)
+ while (!actionflag && !dieflag)
{
NSData *d;
readLen = recv(sockfd,buf,bufs,0);
+ if (readLen == -1) {[(id)dp errorOccured:ITInetConnectionDropped during:ITInetSocketReading onSocket:self];goto dieaction;}
if (readLen) {
- d = [NSData alloc];
- [d initWithBytesNoCopy:buf length:readLen freeWhenDone:NO];
- [readPipe writeData:d];
- [d release];
- [(id)dp dataReceived:self];
+ NSLog(@"recv'd");
+ NSLog(@"Doing writeData to readPipe");
+ [readPipe writeBytes:buf len:readLen];
+ [ap release];
+ ap = [[NSAutoreleasePool alloc] init];
}
}
free(buf);
shutdown(sockfd,2);
[dcon release];
+ [dp release];
[ap release];
dieflag = 0;
return;
}
{
+ NSLog(@"Emptying writePipe");
NSData *d = [writePipe readAllData];
write(sockfd,[d bytes],[d length]);
+ [ap release];
+ ap = [[NSAutoreleasePool alloc] init];
goto lstart;
}
goto dieaction;
#import "ShowcaseController.h"
#import "ITInetSocket.h"
+ITInetSocket *sock;
@implementation ShowcaseController
- (void)awakeFromNib
{
- ITInetSocket *sock = [[ITInetSocket alloc] initWithDelegate:self];
+ sock = [[ITInetSocket alloc] initWithDelegate:self];
NSLog(@"rawr?");
[sock connectToHost:@"irc.freenode.net" onPort:6667];
}
-- (void) finishedConnecting:(in ITInetSocket *)sender {
- NSString *ircini = @"NICK ITFTest\r\nUSER m0nk3ys . . :Not Tellin'\r\nJOIN #iThink\r\nPRIVMSG #iThink :w00t\r\nQUIT :!\r\n";
- NSLog(@"Done connectin'");
- NSData *d = [NSData dataWithBytes:[ircini cString] length:[ircini length]];
- [sender->writePipe writeData:d];
- NSLog(@"%@",sender->writePipe->data);
+- (void) finishedConnecting:(ITInetSocket *)sender {
+
}
+
- (void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(in ITInetSocket*)sender {NSLog(@"wtf");[sender retryConnection];}
-- (void) dataReceived:(in ITInetSocket *)sender
+- (void) dataReceived:(ITInetSocket *)sender
{
- ITByteStream *p = sender->readPipe;
- NSData *d = [p readAllData];
- NSLog(@"%@",d);
}
+- (void) newDataAdded:(ITByteStream*)sender {
+ static int firstTime = YES;
+ NSString *ircini = @"USER m0nk3ys . . :Not Telling\r\nNICK ITFTest\r\n", *irc2 = @"JOIN #iThink\r\nPRIVMSG #iThink :w00t\r\nQUIT :!\r\n";
+ NSLog(@"Writing something");
+ NSData *d = [NSData dataWithBytes:[firstTime?ircini:irc2 cString] length:[firstTime?ircini:irc2 length]];
+ [sock->writePipe writeData:d];
+ NSLog(@"Reading something");
+ firstTime = NO;
+}
@end