DELETED src/OFSocketObserver.h Index: src/OFSocketObserver.h ================================================================== --- src/OFSocketObserver.h +++ src/OFSocketObserver.h @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2008 - 2010 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE included in - * the packaging of this file. - */ - -#if !defined(OF_HAVE_POLL) && defined(OF_HAVE_SYS_SELECT_H) -# include -#endif - -#import "OFObject.h" - -#ifdef _WIN32 -# define _WIN32_WINNT 0x0501 -# include -#endif - -@class OFSocket; -@class OFTCPSocket; -#ifdef OF_HAVE_POLL -@class OFDataArray; -#endif -@class OFMutableDictionary; - -/** - * \brief A protocol that needs to be implemented by delegates for - * OFSocketObserver. - */ -@protocol OFSocketObserverDelegate -/* - * This callback is called when a listening socket got a new incoming - * connection. - * - * \param sock The socket which did receive an incoming connection - */ -- (void)socketDidReceiveIncomingConnection: (OFTCPSocket*)sock; - -/** - * This callback is called when a socket did get ready for reading. - * - * \param sock The socket which did become ready for reading - */ -- (void)socketDidBecomeReadyForReading: (OFSocket*)sock; - -/** - * This callback is called when a socket did get ready for writing. - * - * \param sock The socket which did become ready for writing - */ -- (void)socketDidBecomeReadyForWriting: (OFSocket*)sock; -@end - -/** - * \brief A class that can observe multiple sockets at once. - */ -@interface OFSocketObserver: OFObject -{ - OFObject *delegate; -#ifdef OF_HAVE_POLL - OFDataArray *fds; -#else - fd_set readfds; - fd_set writefds; - int nfds; -#endif - OFMutableDictionary *fdToSocket; -} - -#ifdef OF_HAVE_PROPERTIES -@property (retain) OFObject *delegate; -#endif - -/** - * \return A new, autoreleased OFSocketObserver - */ -+ socketObserver; - -/** - * \return The delegate for the OFSocketObserver - */ -- (OFObject *)delegate; - -/** - * Sets the delegate for the OFSocketObserver. - * - * \param delegate The delegate for the OFSocketObserver - */ -- (void)setDelegate: (OFObject *)delegate; - -/** - * Adds a socket to observe for incoming connections. - * - * \param sock The socket to observe for incoming connections - */ -- (void)addSocketToObserveForIncomingConnections: (OFTCPSocket*)sock; - -/** - * Adds a socket to observe for reading. - * - * \param sock The socket to observe for reading - */ -- (void)addSocketToObserveForReading: (OFSocket*)sock; - -/** - * Adds a socket to observe for writing. - * - * \param sock The socket to observe for writing - */ -- (void)addSocketToObserveForWriting: (OFSocket*)sock; - -/** - * Removes a socket to observe for incoming connections. - * - * \param sock The socket to remove from observing for incoming connections - */ -- (void)removeSocketToObserveForIncomingConnections: (OFTCPSocket*)sock; - -/** - * Removes a socket to observe for reading. - * - * \param sock The socket to remove from observing for reading - */ -- (void)removeSocketToObserveForReading: (OFSocket*)sock; - -/** - * Removes a socket to observe for writing. - * - * \param sock The socket to remove from observing for writing - */ -- (void)removeSocketToObserveForWriting: (OFSocket*)sock; - -/** - * Observes all sockets and blocks until an event happens on a socket. - */ -- (void)observe; - -/** - * Observes all sockets until an event happens on a socket or the timeout is - * reached. - * - * \param timeout The time to wait for an event, in milliseconds - * \return A boolean whether events occurred during the timeinterval - */ -- (BOOL)observeWithTimeout: (int)timeout; -@end - -@interface OFObject (OFSocketObserverDelegate) -@end DELETED src/OFSocketObserver.m Index: src/OFSocketObserver.m ================================================================== --- src/OFSocketObserver.m +++ src/OFSocketObserver.m @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2008 - 2010 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE included in - * the packaging of this file. - */ - -#include "config.h" - -#include - -#ifdef OF_HAVE_POLL -# include -#endif - -#import "OFSocketObserver.h" -#import "OFDataArray.h" -#import "OFDictionary.h" -#import "OFSocket.h" -#import "OFTCPSocket.h" -#import "OFNumber.h" -#import "OFAutoreleasePool.h" -#import "OFExceptions.h" - -@implementation OFSocketObserver -+ socketObserver -{ - return [[[self alloc] init] autorelease]; -} - -- init -{ - self = [super init]; - -#ifdef OF_HAVE_POLL - fds = [[OFDataArray alloc] initWithItemSize: sizeof(struct pollfd)]; -#else - FD_ZERO(&readfds); - FD_ZERO(&writefds); -#endif - fdToSocket = [[OFMutableDictionary alloc] init]; - - return self; -} - -- (void)dealloc -{ - [delegate release]; -#ifdef OF_HAVE_POLL - [fds release]; -#endif - [fdToSocket release]; - - [super dealloc]; -} - -- (OFObject *)delegate -{ - return [[delegate retain] autorelease]; -} - -- (void)setDelegate: (OFObject *)delegate_ -{ - [delegate_ retain]; - [delegate release]; - delegate = delegate_; -} - -#ifdef OF_HAVE_POLL -- (void)_addSocket: (OFSocket*)sock - withEvents: (short)events -{ - struct pollfd *fds_c = [fds cArray]; - size_t i, count = [fds count]; - BOOL found = NO; - - for (i = 0; i < count; i++) { - if (fds_c[i].fd == sock->sock) { - fds_c[i].events |= events; - found = YES; - } - } - - if (!found) { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - struct pollfd p = { sock->sock, events, 0 }; - [fds addItem: &p]; - [fdToSocket setObject: sock - forKey: [OFNumber numberWithInt: sock->sock]]; - [pool release]; - } -} - -- (void)_removeSocket: (OFSocket*)sock - withEvents: (short)events -{ - struct pollfd *fds_c = [fds cArray]; - size_t i, nfds = [fds count]; - - for (i = 0; i < nfds; i++) { - if (fds_c[i].fd == sock->sock) { - OFAutoreleasePool *pool; - - fds_c[i].events &= ~events; - - if (fds_c[i].events != 0) - return; - - pool = [[OFAutoreleasePool alloc] init]; - - [fds removeItemAtIndex: i]; - [fdToSocket removeObjectForKey: - [OFNumber numberWithInt: sock->sock]]; - - [pool release]; - } - } -} -#else -- (void)_addSocket: (OFSocket*)sock - withFDSet: (fd_set*)fdset -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - - if (sock->sock >= FD_SETSIZE) - @throw [OFOutOfRangeException newWithClass: isa]; - - FD_SET(sock->sock, fdset); - - if (sock->sock >= nfds) - nfds = sock->sock + 1; - - [fdToSocket setObject: sock - forKey: [OFNumber numberWithInt: sock->sock]]; - - [pool release]; -} - -- (void)_removeSocket: (OFSocket*)sock - withFDSet: (fd_set*)fdset -{ - if (sock->sock >= FD_SETSIZE) - @throw [OFOutOfRangeException newWithClass: isa]; - - FD_CLR(sock->sock, fdset); - - if (!FD_ISSET(sock->sock, &readfds) && - !FD_ISSET(sock->sock, &writefds)) { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - - [fdToSocket removeObjectForKey: - [OFNumber numberWithInt: sock->sock]]; - - [pool release]; - } -} -#endif - -- (void)addSocketToObserveForIncomingConnections: (OFTCPSocket*)sock -{ -#ifdef OF_HAVE_POLL - [self _addSocket: sock - withEvents: POLLIN]; -#else - [self _addSocket: sock - withFDSet: &readfds]; -#endif -} - -- (void)addSocketToObserveForReading: (OFSocket*)sock -{ -#ifdef OF_HAVE_POLL - [self _addSocket: sock - withEvents: POLLIN]; -#else - [self _addSocket: sock - withFDSet: &readfds]; -#endif -} - -- (void)addSocketToObserveForWriting: (OFSocket*)sock -{ -#ifdef OF_HAVE_POLL - [self _addSocket: sock - withEvents: POLLOUT]; -#else - [self _addSocket: sock - withFDSet: &writefds]; -#endif -} - -- (void)removeSocketToObserveForIncomingConnections: (OFTCPSocket*)sock -{ -#ifdef OF_HAVE_POLL - [self _removeSocket: sock - withEvents: POLLIN]; -#else - [self _removeSocket: sock - withFDSet: &readfds]; -#endif -} - -- (void)removeSocketToObserveForReading: (OFSocket*)sock -{ -#ifdef OF_HAVE_POLL - [self _removeSocket: sock - withEvents: POLLIN]; -#else - [self _removeSocket: sock - withFDSet: &readfds]; -#endif -} - -- (void)removeSocketToObserveForWriting: (OFSocket*)sock -{ -#ifdef OF_HAVE_POLL - [self _removeSocket: sock - withEvents: POLLOUT]; -#else - [self _removeSocket: sock - withFDSet: &writefds]; -#endif -} - -- (void)observe -{ - [self observeWithTimeout: -1]; -} - -- (BOOL)observeWithTimeout: (int)timeout -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; -#ifdef OF_HAVE_POLL - struct pollfd *fds_c = [fds cArray]; - size_t i, nfds = [fds count]; - - if (poll(fds_c, nfds, timeout) < 1) - return NO; - - for (i = 0; i < nfds; i++) { - OFNumber *num; - OFSocket *sock; - - if (fds_c[i].revents & POLLIN) { - num = [OFNumber numberWithInt: fds_c[i].fd]; - sock = [fdToSocket objectForKey: num]; - - if (sock->listening) - [delegate socketDidReceiveIncomingConnection: - (OFTCPSocket*)sock]; - else - [delegate socketDidBecomeReadyForReading: sock]; - } - - if (fds_c[i].revents & POLLOUT) { - num = [OFNumber numberWithInt: fds_c[i].fd]; - sock = [fdToSocket objectForKey: num]; - [delegate socketDidBecomeReadyForReading: sock]; - } - - fds_c[i].revents = 0; - } -#else - fd_set readfds_; - fd_set writefds_; - fd_set exceptfds_; - struct timeval tv; - OFEnumerator *enumerator; - OFSocket *sock; - - readfds_ = readfds; - writefds_ = writefds; - FD_ZERO(&exceptfds_); - - if (select(nfds, &readfds_, &writefds_, &exceptfds_, - (timeout != -1 ? &tv : NULL)) < 1) - return NO; - - enumerator = [[[fdToSocket copy] autorelease] objectEnumerator]; - - while ((sock = [enumerator nextObject]) != nil) { - if (FD_ISSET(sock->sock, &readfds_)) { - if (sock->listening) - [delegate socketDidReceiveIncomingConnection: - (OFTCPSocket*)sock]; - else - [delegate socketDidBecomeReadyForReading: sock]; - } - - if (FD_ISSET(sock->sock, &writefds_)) - [delegate socketDidBecomeReadyForWriting: sock]; - } -#endif - [pool release]; - - return YES; -} -@end - -@implementation OFObject (OFSocketObserverDelegate) -- (void)socketDidReceiveIncomingConnection: (OFTCPSocket*)sock -{ -} - -- (void)socketDidBecomeReadyForReading: (OFSocket*)sock -{ -} - -- (void)socketDidBecomeReadyForWriting: (OFSocket*)sock -{ -} -@end ADDED src/OFStreamObserver.h Index: src/OFStreamObserver.h ================================================================== --- src/OFStreamObserver.h +++ src/OFStreamObserver.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008 - 2010 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#if !defined(OF_HAVE_POLL) && defined(OF_HAVE_SYS_SELECT_H) +# include +#endif + +#import "OFObject.h" + +#ifdef _WIN32 +# define _WIN32_WINNT 0x0501 +# include +#endif + +@class OFStream; +#ifdef OF_HAVE_POLL +@class OFDataArray; +#endif +@class OFMutableDictionary; + +/** + * \brief A protocol that needs to be implemented by delegates for + * OFStreamObserver. + */ +@protocol OFStreamObserverDelegate + +/** + * This callback is called when a stream did get ready for reading. + * + * \param stream The stream which did become ready for reading + */ +- (void)streamDidBecomeReadyForReading: (OFStream*)stream; + +/** + * This callback is called when a stream did get ready for writing. + * + * \param stream The stream which did become ready for writing + */ +- (void)streamDidBecomeReadyForWriting: (OFStream*)stream; +@end + +/** + * \brief A class that can observe multiple streams at once. + */ +@interface OFStreamObserver: OFObject +{ + OFObject *delegate; +#ifdef OF_HAVE_POLL + OFDataArray *fds; +#else + fd_set readfds; + fd_set writefds; + int nfds; +#endif + OFMutableDictionary *fdToStream; +} + +#ifdef OF_HAVE_PROPERTIES +@property (retain) OFObject *delegate; +#endif + +/** + * \return A new, autoreleased OFStreamObserver + */ ++ streamObserver; + +/** + * \return The delegate for the OFStreamObserver + */ +- (OFObject *)delegate; + +/** + * Sets the delegate for the OFStreamObserver. + * + * \param delegate The delegate for the OFStreamObserver + */ +- (void)setDelegate: (OFObject *)delegate; + +/** + * Adds a stream to observe for reading. + * + * \param stream The stream to observe for reading + */ +- (void)addStreamToObserveForReading: (OFStream*)stream; + +/** + * Adds a stream to observe for writing. + * + * \param stream The stream to observe for writing + */ +- (void)addStreamToObserveForWriting: (OFStream*)stream; + +/** + * Removes a stream to observe for reading. + * + * \param stream The stream to remove from observing for reading + */ +- (void)removeStreamToObserveForReading: (OFStream*)stream; + +/** + * Removes a stream to observe for writing. + * + * \param stream The stream to remove from observing for writing + */ +- (void)removeStreamToObserveForWriting: (OFStream*)stream; + +/** + * Observes all streams and blocks until an event happens on a stream. + */ +- (void)observe; + +/** + * Observes all streams until an event happens on a stream or the timeout is + * reached. + * + * \param timeout The time to wait for an event, in milliseconds + * \return A boolean whether events occurred during the timeinterval + */ +- (BOOL)observeWithTimeout: (int)timeout; +@end + +@interface OFObject (OFStreamObserverDelegate) +@end ADDED src/OFStreamObserver.m Index: src/OFStreamObserver.m ================================================================== --- src/OFStreamObserver.m +++ src/OFStreamObserver.m @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2008 - 2010 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#include "config.h" + +#include + +#ifdef OF_HAVE_POLL +# include +#endif + +#import "OFStreamObserver.h" +#import "OFDataArray.h" +#import "OFDictionary.h" +#import "OFStream.h" +#import "OFNumber.h" +#import "OFAutoreleasePool.h" +#import "OFExceptions.h" + +@implementation OFStreamObserver ++ streamObserver +{ + return [[[self alloc] init] autorelease]; +} + +- init +{ + self = [super init]; + +#ifdef OF_HAVE_POLL + fds = [[OFDataArray alloc] initWithItemSize: sizeof(struct pollfd)]; +#else + FD_ZERO(&readfds); + FD_ZERO(&writefds); +#endif + fdToStream = [[OFMutableDictionary alloc] init]; + + return self; +} + +- (void)dealloc +{ + [delegate release]; +#ifdef OF_HAVE_POLL + [fds release]; +#endif + [fdToStream release]; + + [super dealloc]; +} + +- (OFObject *)delegate +{ + return [[delegate retain] autorelease]; +} + +- (void)setDelegate: (OFObject *)delegate_ +{ + [delegate_ retain]; + [delegate release]; + delegate = delegate_; +} + +#ifdef OF_HAVE_POLL +- (void)_addStream: (OFStream*)stream + withEvents: (short)events +{ + struct pollfd *fds_c = [fds cArray]; + size_t i, count = [fds count]; + int fd = [stream fileDescriptor]; + BOOL found = NO; + + for (i = 0; i < count; i++) { + if (fds_c[i].fd == fd) { + fds_c[i].events |= events; + found = YES; + } + } + + if (!found) { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + struct pollfd p = { fd, events, 0 }; + [fds addItem: &p]; + [fdToStream setObject: stream + forKey: [OFNumber numberWithInt: fd]]; + [pool release]; + } +} + +- (void)_removeStream: (OFStream*)stream + withEvents: (short)events +{ + struct pollfd *fds_c = [fds cArray]; + size_t i, nfds = [fds count]; + int fd = [stream fileDescriptor]; + + for (i = 0; i < nfds; i++) { + if (fds_c[i].fd == fd) { + OFAutoreleasePool *pool; + + fds_c[i].events &= ~events; + + if (fds_c[i].events != 0) + return; + + pool = [[OFAutoreleasePool alloc] init]; + + [fds removeItemAtIndex: i]; + [fdToStream removeObjectForKey: + [OFNumber numberWithInt: fd]]; + + [pool release]; + } + } +} +#else +- (void)_addStream: (OFStream*)stream + withFDSet: (fd_set*)fdset +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + int fd = [stream fileDescriptor]; + + if (fd >= FD_SETSIZE) + @throw [OFOutOfRangeException newWithClass: isa]; + + FD_SET(fd, fdset); + + if (fd >= nfds) + nfds = fd + 1; + + [fdToStream setObject: stream + forKey: [OFNumber numberWithInt: fd]]; + + [pool release]; +} + +- (void)_removeStream: (OFStream*)stream + withFDSet: (fd_set*)fdset +{ + int fd = [stream fileDescriptor]; + + if (fd >= FD_SETSIZE) + @throw [OFOutOfRangeException newWithClass: isa]; + + FD_CLR(fd, fdset); + + if (!FD_ISSET(fd, &readfds) && !FD_ISSET(fd, &writefds)) { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + + [fdToStream removeObjectForKey: [OFNumber numberWithInt: fd]]; + + [pool release]; + } +} +#endif + +- (void)addStreamToObserveForReading: (OFStream*)stream +{ +#ifdef OF_HAVE_POLL + [self _addStream: stream + withEvents: POLLIN]; +#else + [self _addStream: stream + withFDSet: &readfds]; +#endif +} + +- (void)addStreamToObserveForWriting: (OFStream*)stream +{ +#ifdef OF_HAVE_POLL + [self _addStream: stream + withEvents: POLLOUT]; +#else + [self _addStream: stream + withFDSet: &writefds]; +#endif +} + +- (void)removeStreamToObserveForReading: (OFStream*)stream +{ +#ifdef OF_HAVE_POLL + [self _removeStream: stream + withEvents: POLLIN]; +#else + [self _removeStream: stream + withFDSet: &readfds]; +#endif +} + +- (void)removeStreamToObserveForWriting: (OFStream*)stream +{ +#ifdef OF_HAVE_POLL + [self _removeStream: stream + withEvents: POLLOUT]; +#else + [self _removeStream: stream + withFDSet: &writefds]; +#endif +} + +- (void)observe +{ + [self observeWithTimeout: -1]; +} + +- (BOOL)observeWithTimeout: (int)timeout +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; +#ifdef OF_HAVE_POLL + struct pollfd *fds_c = [fds cArray]; + size_t i, nfds = [fds count]; + + if (poll(fds_c, nfds, timeout) < 1) + return NO; + + for (i = 0; i < nfds; i++) { + OFNumber *num; + OFStream *stream; + + if (fds_c[i].revents & POLLIN) { + num = [OFNumber numberWithInt: fds_c[i].fd]; + stream = [fdToStream objectForKey: num]; + [delegate streamDidBecomeReadyForReading: stream]; + } + + if (fds_c[i].revents & POLLOUT) { + num = [OFNumber numberWithInt: fds_c[i].fd]; + stream = [fdToStream objectForKey: num]; + [delegate streamDidBecomeReadyForReading: stream]; + } + + fds_c[i].revents = 0; + } +#else + fd_set readfds_; + fd_set writefds_; + fd_set exceptfds_; + struct timeval tv; + OFEnumerator *enumerator; + OFStream *stream; + + readfds_ = readfds; + writefds_ = writefds; + FD_ZERO(&exceptfds_); + + if (select(nfds, &readfds_, &writefds_, &exceptfds_, + (timeout != -1 ? &tv : NULL)) < 1) + return NO; + + enumerator = [[[fdToStream copy] autorelease] objectEnumerator]; + + while ((stream = [enumerator nextObject]) != nil) { + int fd = [stream fileDescriptor]; + + if (FD_ISSET(fd, &readfds_)) + [delegate streamDidBecomeReadyForReading: stream]; + + if (FD_ISSET(fd, &writefds_)) + [delegate streamDidBecomeReadyForWriting: stream]; + } +#endif + [pool release]; + + return YES; +} +@end + +@implementation OFObject (OFStreamObserverDelegate) +- (void)streamDidBecomeReadyForReading: (OFStream*)stream +{ +} + +- (void)streamDidBecomeReadyForWriting: (OFStream*)stream +{ +} +@end