Index: src/OFRunLoop.h ================================================================== --- src/OFRunLoop.h +++ src/OFRunLoop.h @@ -50,23 +50,27 @@ + (void)OF_setMainRunLoop; + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer length: (size_t)length target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer exactLength: (size_t)length target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; + (void)OF_addAsyncReadLineForStream: (OFStream*)stream encoding: (of_string_encoding_t)encoding target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; + (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)socket target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; #ifdef OF_HAVE_BLOCKS + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer length: (size_t)length block: (of_stream_async_read_block_t)block; Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -26,63 +26,73 @@ #import "autorelease.h" #import "macros.h" static OFRunLoop *mainRunLoop = nil; -@interface OFRunLoop_ReadQueueItem: OFObject +@interface OFRunLoop_QueueItem: OFObject +{ +@public + id target; + SEL selector; + id context; +} +@end + +@interface OFRunLoop_ReadQueueItem: OFRunLoop_QueueItem { @public void *buffer; size_t length; - id target; - SEL selector; #ifdef OF_HAVE_BLOCKS of_stream_async_read_block_t block; #endif } @end -@interface OFRunLoop_ExactReadQueueItem: OFObject +@interface OFRunLoop_ExactReadQueueItem: OFRunLoop_QueueItem { @public void *buffer; size_t exactLength, readLength; - id target; - SEL selector; #ifdef OF_HAVE_BLOCKS of_stream_async_read_block_t block; #endif } @end -@interface OFRunLoop_ReadLineQueueItem: OFObject +@interface OFRunLoop_ReadLineQueueItem: OFRunLoop_QueueItem { @public of_string_encoding_t encoding; - id target; - SEL selector; #ifdef OF_HAVE_BLOCKS of_stream_async_read_line_block_t block; #endif } @end -@interface OFRunLoop_AcceptQueueItem: OFObject +@interface OFRunLoop_AcceptQueueItem: OFRunLoop_QueueItem { @public - id target; - SEL selector; #ifdef OF_HAVE_BLOCKS of_tcpsocket_async_accept_block_t block; #endif } @end -@implementation OFRunLoop_ReadQueueItem +@implementation OFRunLoop_QueueItem - (void)dealloc { [target release]; + [context release]; + + [super dealloc]; +} +@end + +@implementation OFRunLoop_ReadQueueItem +- (void)dealloc +{ #ifdef OF_HAVE_BLOCKS [block release]; #endif [super dealloc]; @@ -90,11 +100,10 @@ @end @implementation OFRunLoop_ExactReadQueueItem - (void)dealloc { - [target release]; #ifdef OF_HAVE_BLOCKS [block release]; #endif [super dealloc]; @@ -102,11 +111,10 @@ @end @implementation OFRunLoop_ReadLineQueueItem - (void)dealloc { - [target release]; #ifdef OF_HAVE_BLOCKS [block release]; #endif [super dealloc]; @@ -114,11 +122,10 @@ @end @implementation OFRunLoop_AcceptQueueItem - (void)dealloc { - [target release]; #ifdef OF_HAVE_BLOCKS [block release]; #endif [super dealloc]; @@ -167,52 +174,60 @@ + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer length: (size_t)length target: (id)target selector: (SEL)selector + context: (id)context { ADD(OFRunLoop_ReadQueueItem, { queueItem->buffer = buffer; queueItem->length = length; queueItem->target = [target retain]; queueItem->selector = selector; + queueItem->context = [context retain]; }) } + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer exactLength: (size_t)exactLength target: (id)target selector: (SEL)selector + context: (id)context { ADD(OFRunLoop_ExactReadQueueItem, { queueItem->buffer = buffer; queueItem->exactLength = exactLength; queueItem->target = [target retain]; queueItem->selector = selector; + queueItem->context = [context retain]; }) } + (void)OF_addAsyncReadLineForStream: (OFStream*)stream encoding: (of_string_encoding_t)encoding target: (id)target selector: (SEL)selector + context: (id)context { ADD(OFRunLoop_ReadLineQueueItem, { queueItem->encoding = encoding; queueItem->target = [target retain]; queueItem->selector = selector; + queueItem->context = [context retain]; }) } + (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream target: (id)target selector: (SEL)selector + context: (id)context { ADD(OFRunLoop_AcceptQueueItem, { queueItem->target = [target retain]; queueItem->selector = selector; + queueItem->context = [context retain]; }) } #ifdef OF_HAVE_BLOCKS + (void)OF_addAsyncReadForStream: (OFStream*)stream @@ -331,18 +346,19 @@ [readQueues removeObjectForKey: stream]; } } } else { #endif - BOOL (*func)(id, SEL, OFStream*, void*, size_t, + BOOL (*func)(id, SEL, OFStream*, void*, size_t, id, OFException*) = (BOOL(*)(id, SEL, OFStream*, void*, - size_t, OFException*)) + size_t, id, OFException*)) [queueItem->target methodForSelector: queueItem->selector]; if (!func(queueItem->target, queueItem->selector, - stream, queueItem->buffer, length, exception)) { + stream, queueItem->buffer, length, + queueItem->context, exception)) { [queue removeListObject: listObject]; if ([queue count] == 0) { [streamObserver removeStreamForReading: stream]; @@ -388,20 +404,20 @@ removeObjectForKey: stream]; } } } else { #endif - BOOL (*func)(id, SEL, OFStream*, void*, - size_t, OFException*) = (BOOL(*)(id, SEL, - OFStream*, void*, size_t, OFException*)) + BOOL (*func)(id, SEL, OFStream*, void*, size_t, + id, OFException*) = (BOOL(*)(id, SEL, + OFStream*, void*, size_t, id, OFException*)) [queueItem->target methodForSelector: queueItem->selector]; if (func(queueItem->target, queueItem->selector, stream, queueItem->buffer, queueItem->readLength, - exception)) + queueItem->context, exception)) queueItem->readLength = 0; else { [queue removeListObject: listObject]; if ([queue count] == 0) { @@ -447,18 +463,18 @@ } } } else { #endif BOOL (*func)(id, SEL, OFStream*, OFString*, - OFException*) = (BOOL(*)(id, SEL, OFStream*, - OFString*, OFException*)) + id, OFException*) = (BOOL(*)(id, SEL, + OFStream*, OFString*, id, OFException*)) [queueItem->target methodForSelector: queueItem->selector]; if (!func(queueItem->target, queueItem->selector, stream, line, - exception)) { + queueItem->context, exception)) { [queue removeListObject: listObject]; if ([queue count] == 0) { [streamObserver removeStreamForReading: @@ -497,18 +513,19 @@ } } } else { #endif BOOL (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*, - OFException*) = + id, OFException*) = (BOOL(*)(id, SEL, OFTCPSocket*, OFTCPSocket*, - OFException*)) + id, OFException*)) [queueItem->target methodForSelector: queueItem->selector]; if (!func(queueItem->target, queueItem->selector, - (OFTCPSocket*)stream, newSocket, exception)) { + (OFTCPSocket*)stream, newSocket, queueItem->context, + exception)) { [queue removeListObject: listObject]; if ([queue count] == 0) { [streamObserver removeStreamForReading: stream]; Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -132,16 +132,18 @@ * data has been received. If you want the next method in the * queue to handle the data received next, you need to return NO * from the method. * @param selector The selector to call on the target. The signature must be * BOOL (OFStream *stream, void *buffer, size_t size, - * OFException *exception). + * id context, OFException *exception). + * @param context A context to pass when the target gets called */ - (void)asyncReadIntoBuffer: (void*)buffer length: (size_t)length target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; /*! * @brief Asyncronously reads exactly the specified length bytes from the * stream into a buffer. * @@ -159,16 +161,18 @@ * data has been received. If you want the next method in the * queue to handle the data received next, you need to return NO * from the method. * @param selector The selector to call on the target. The signature must be * BOOL (OFStream *stream, void *buffer, size_t size, - * OFException *exception). + * id context, OFException *exception). + * @param context A context to pass when the target gets called */ - (void)asyncReadIntoBuffer: (void*)buffer exactLength: (size_t)length target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; #ifdef OF_HAVE_BLOCKS /*! * @brief Asyncronously reads at most size bytes from the stream into a * buffer. @@ -570,15 +574,17 @@ * been received. If the method returns YES, it will be called * again when the next line has been received. If you want the * next method in the queue to handle the next line, you need to * return NO from the method * @param selector The selector to call on the target. The signature must be - * BOOL (OFStream *stream, OFString *line, + * BOOL (OFStream *stream, OFString *line, id context, * OFException *exception). + * @param context A context to pass when the target gets called */ - (void)asyncReadLineWithTarget: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; /*! * @brief Asyncronously reads with the specified encoding until a newline, \\0, * end of stream or an exception occurs. * @@ -587,16 +593,18 @@ * been received. If the method returns YES, it will be called * again when the next line has been received. If you want the * next method in the queue to handle the next line, you need to * return NO from the method * @param selector The selector to call on the target. The signature must be - * BOOL (OFStream *stream, OFString *line, + * BOOL (OFStream *stream, OFString *line, id context, * OFException *exception). + * @param context A context to pass when the target gets called */ - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; #ifdef OF_HAVE_BLOCKS /*! * @brief Asyncronously reads until a newline, \\0, end of stream or an * exception occurs. Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -146,28 +146,32 @@ - (void)asyncReadIntoBuffer: (void*)buffer length: (size_t)length target: (id)target selector: (SEL)selector + context: (id)context { [OFRunLoop OF_addAsyncReadForStream: self buffer: buffer length: length target: target - selector: selector]; + selector: selector + context: context]; } - (void)asyncReadIntoBuffer: (void*)buffer exactLength: (size_t)length target: (id)target selector: (SEL)selector + context: (id)context { [OFRunLoop OF_addAsyncReadForStream: self buffer: buffer exactLength: length target: target - selector: selector]; + selector: selector + context: context]; } #ifdef OF_HAVE_BLOCKS - (void)asyncReadIntoBuffer: (void*)buffer length: (size_t)length @@ -720,24 +724,28 @@ return line; } - (void)asyncReadLineWithTarget: (id)target selector: (SEL)selector + context: (id)context { return [self asyncReadLineWithEncoding: OF_STRING_ENCODING_UTF_8 target: target - selector: selector]; + selector: selector + context: context]; } - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding target: (id)target selector: (SEL)selector + context: (id)context { [OFRunLoop OF_addAsyncReadLineForStream: self encoding: encoding target: target - selector: selector]; + selector: selector + context: context]; } #ifdef OF_HAVE_BLOCKS - (void)asyncReadLineWithBlock: (of_stream_async_read_line_block_t)block { Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -136,16 +136,19 @@ * @param host The host to connect to * @param port The port on the host to connect to * @param target The target on which to call the selector once the connection * has been established * @param selector The selector to call on the target. The signature must be - * void (OFTCPSocket *socket, OFException *exception). + * void (OFTCPSocket *socket, id context, + * OFException *exception). + * @param context A context to pass when the target gets called */ - (void)asyncConnectToHost: (OFString*)host port: (uint16_t)port target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; #ifdef OF_HAVE_BLOCKS /*! * @brief Asyncronously connect the OFTCPSocket to the specified destination. * @@ -196,14 +199,16 @@ * connection has been accepted. The method returns whether the * next incoming connection should be accepted by the specified * block as well. * @param selector The selector to call on the target. The signature must be * BOOL (OFTCPSocket *socket, OFTCPSocket *acceptedSocket, - * OFException *exception). + * id context, OFException *exception). + * @param context A context to pass when the target gets called */ - (void)asyncAcceptWithTarget: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; #ifdef OF_HAVE_BLOCKS /*! * @brief Asyncronously accept an incoming connection. * Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -86,19 +86,21 @@ id target; SEL selector; #ifdef OF_HAVE_BLOCKS of_tcpsocket_async_connect_block_t connectBlock; #endif + id context; OFException *exception; } - initWithSourceThread: (OFThread*)sourceThread socket: (OFTCPSocket*)socket host: (OFString*)host port: (uint16_t)port target: (id)target - selector: (SEL)selector; + selector: (SEL)selector + context: (id)context; #ifdef OF_HAVE_BLOCKS - initWithSourceThread: (OFThread*)sourceThread socket: (OFTCPSocket*)socket host: (OFString*)host port: (uint16_t)port @@ -111,10 +113,11 @@ socket: (OFTCPSocket*)sock_ host: (OFString*)host_ port: (uint16_t)port_ target: (id)target_ selector: (SEL)selector_ + context: (id)context_ { self = [super init]; @try { sourceThread = [sourceThread_ retain]; @@ -121,10 +124,11 @@ sock = [sock_ retain]; host = [host_ copy]; port = port_; target = [target_ retain]; selector = selector_; + context = [context_ retain]; } @catch (id e) { [self release]; @throw e; } @@ -162,10 +166,11 @@ [host release]; [target release]; #ifdef OF_HAVE_BLOCKS [connectBlock release]; #endif + [context release]; [exception release]; [super dealloc]; } @@ -176,15 +181,15 @@ #ifdef OF_HAVE_BLOCKS if (connectBlock != NULL) connectBlock(sock, exception); else { #endif - void (*func)(id, SEL, OFTCPSocket*, OFException*) = - (void(*)(id, SEL, OFTCPSocket*, OFException*))[target + void (*func)(id, SEL, OFTCPSocket*, id, OFException*) = + (void(*)(id, SEL, OFTCPSocket*, id, OFException*))[target methodForSelector: selector]; - func(target, selector, sock, exception); + func(target, selector, sock, context, exception); #ifdef OF_HAVE_BLOCKS } #endif } @@ -424,20 +429,22 @@ - (void)asyncConnectToHost: (OFString*)host port: (uint16_t)port target: (id)target selector: (SEL)selector + context: (id)context { void *pool = objc_autoreleasePoolPush(); [[[[OFTCPSocket_ConnectThread alloc] initWithSourceThread: [OFThread currentThread] socket: self host: host port: port target: target - selector: selector] autorelease] start]; + selector: selector + context: context] autorelease] start]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS @@ -649,14 +656,16 @@ return newSocket; } - (void)asyncAcceptWithTarget: (id)target selector: (SEL)selector + context: (id)context { [OFRunLoop OF_addAsyncAcceptForTCPSocket: self target: target - selector: selector]; + selector: selector + context: context]; } #ifdef OF_HAVE_BLOCKS - (void)asyncAcceptWithBlock: (of_tcpsocket_async_accept_block_t)block {