Add server and pipe streams.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22505 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-02-16 19:19:30 +00:00
parent e12d4b2648
commit a84aca3d73
6 changed files with 777 additions and 179 deletions

View file

@ -1,3 +1,12 @@
2006-02-16 Derek Zhou <dzhou@nvidea.com>
* Source/GSStream.h:
* Source/GSStream.m:
* Source/unix/NSStream.m:
* Source/win32/NSStreamWin32.m:
* Headers/Foundation/NSStream.h:
Add server side and pipe stream extensions along with a few fixes.
2006-02-15 Andrew Ruder <aeruder@ksu.edu>
* Headers/Foundation/NSStream.h: NSRunLoop was not defined in

View file

@ -233,6 +233,63 @@ typedef enum {
@end
/**
* the additional interface defined for gnustep
*/
@interface NSStream (GNUstepExtensions)
/**
* Creates and returns by reference an NSInputStream object and
* NSOutputStream object for a local socket connection with the
* specified path. To use them you need to open them and wait
* on the NSStreamEventOpenCompleted event on one of them
*/
+ (void) getLocalStreamsToPath: (NSString *)path
inputStream: (NSInputStream **)inputStream
outputStream: (NSOutputStream **)outputStream;
/**
* Creates and returns by reference an NSInputStream object and NSOutputStream
* object for a anonymous local socket. Although you still need to open them,
* the open will be instantanious, and no NSStreamEventOpenCompleted event
* will be delivered.
*/
+ (void) pipeWithInputStream: (NSInputStream **)inputStream
outputStream: (NSOutputStream **)outputStream;
@end
/**
* GSServerStream is a subclass of NSStream that encapsulate a "server" stream;
* that is a stream that binds to a socket and accepts incoming connections
*/
@interface GSServerStream : NSStream
/**
* Createe a ip (ipv6) server stream
*/
+ (id) serverStreamToAddr: (NSString*)addr port: (int)port;
/**
* Create a local (unix domain) server stream
*/
+ (id) serverStreamToAddr: (NSString*)addr;
/**
* This is the method that accepts a connection and generates two streams
* as the server side inputStream and OutputStream.
* Although you still need to open them, the open will be
* instantanious, and no NSStreamEventOpenCompleted event will be delivered.
*/
- (void) acceptWithInputStream: (NSInputStream **)inputStream
outputStream: (NSOutputStream **)outputStream;
/**
* the designated initializer for a ip (ipv6) server stream
*/
- (id) initToAddr: (NSString*)addr port: (int)port;
/**
* the designated initializer for a local (unix domain) server stream
*/
- (id) initToAddr: (NSString*)addr;
@end
@protocol GSStreamListener
/**
* The delegate receives this message when streamEvent

View file

@ -34,15 +34,21 @@
| |-- GSInetInputStream
| |-- GSLocalInputStream
| `-- GSInet6InputStream
`-- NSOutputStream
`--GSOutputStream
|-- GSMemoryOutputStream
|-- GSFileOutputStream
`-- GSSocketOutputStream
|-- GSInetOutputStream
|-- GSLocalOutputStream
`-- GSInet6InputStream
*/
|-- NSOutputStream
| `--GSOutputStream
| |-- GSMemoryOutputStream
| |-- GSFileOutputStream
| `-- GSSocketOutputStream
| |-- GSInetOutputStream
| |-- GSLocalOutputStream
| `-- GSInet6InputStream
`-- GSServerStream
`-- GSAbstractServerStream
`-- GSSocketServerStream
|-- GSInetServerStream
|-- GSInet6ServerStream
`-- GSLocalServerStream
*/
#include <Foundation/NSStream.h>
@ -55,6 +61,7 @@
NSStreamStatus _currentStatus;/* current status */\
NSMutableArray *_modes; /* currently scheduled modes. */\
NSRunLoop *_runloop; /* currently scheduled loop. */\
void *_fd; /* the file descriptor (if any) */\
}
/**
@ -82,6 +89,11 @@ IVARS
*/
- (void) _setStatus: (NSStreamStatus)newStatus;
/**
* setter for fd
*/
- (void) _setFd: (void *)fd;
/**
* record an error based on errno
*/
@ -95,6 +107,7 @@ IVARS
- (BOOL) _isOpened;
- (void) _sendEvent: (NSStreamEvent)event;
- (void) _setStatus: (NSStreamStatus)newStatus;
- (void) _setFd: (void*)fd;
- (void) _recordError;
@end
@ -105,9 +118,20 @@ IVARS
- (BOOL) _isOpened;
- (void) _sendEvent: (NSStreamEvent)event;
- (void) _setStatus: (NSStreamStatus)newStatus;
- (void) _setFd: (void*)fd;
- (void) _recordError;
@end
@interface GSAbstractServerStream : GSServerStream
IVARS
@end
@interface GSAbstractServerStream (private)
- (BOOL) _isOpened;
- (void) _sendEvent: (NSStreamEvent)event;
- (void) _setStatus: (NSStreamStatus)newStatus;
- (void) _setFd: (void*)fd;
- (void) _recordError;
@end
/**
* The concrete subclass of NSInputStream that reads from the memory
@ -122,7 +146,7 @@ IVARS
/**
* this is the bridge method for asynchronized operation. Do not call.
*/
- (void) dispatch;
- (void) _dispatch;
@end
/**
@ -139,7 +163,7 @@ IVARS
/**
* this is the bridge method for asynchronized operation. Do not call.
*/
- (void) dispatch;
- (void) _dispatch;
@end
#endif

View file

@ -128,6 +128,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
_lastError = nil;
_modes = [NSMutableArray new];
_currentStatus = NSStreamStatusNotOpen;
_fd = (void*)-1; // any operation will fail
}
return self;
}
@ -179,7 +180,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
NSError *theError = [NSError errorWithDomain: NSPOSIXErrorDomain
code: errno
userInfo: nil];
perror("");
NSLog(@"stream error: - %s", GSLastErrorStr(errno));
ASSIGN(_lastError, theError);
_currentStatus = NSStreamStatusError;
}
@ -202,6 +203,11 @@ NSString * const NSStreamSOCKSProxyVersionKey
}
}
- (void) _setFd: (void *)fd
{
_fd = fd;
}
@end
@implementation GSInputStream
@ -223,6 +229,15 @@ NSString * const NSStreamSOCKSProxyVersionKey
}
}
@end
@implementation GSAbstractServerStream
+ (void) initialize
{
if (self == [GSAbstractServerStream class])
{
GSObjCAddClassBehavior(self, [GSStream class]);
}
}
@end
@implementation GSMemoryInputStream
@ -299,8 +314,11 @@ NSString * const NSStreamSOCKSProxyVersionKey
if (![_modes containsObject: mode])
[_modes addObject: mode];
if ([self _isOpened])
[_runloop performSelector:@selector(dispatch:) target: self
argument: nil order: 0 modes: _modes];
[_runloop performSelector: @selector(_dispatch:)
target: self
argument: nil
order: 0
modes: _modes];
}
- (void) removeFromRunLoop: (NSRunLoop *)aRunLoop forMode: (NSString *)mode
@ -311,8 +329,9 @@ NSString * const NSStreamSOCKSProxyVersionKey
{
[_modes removeObject: mode];
if ([self _isOpened])
[_runloop cancelPerformSelector:@selector(dispatch:)
target: self argument: nil];
[_runloop cancelPerformSelector: @selector(_dispatch:)
target: self
argument: nil];
if ([_modes count] == 0)
DESTROY(_runloop);
}
@ -329,7 +348,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
{
[super open];
if (_runloop)
[_runloop performSelector: @selector(dispatch:)
[_runloop performSelector: @selector(_dispatch:)
target: self
argument: nil
order: 0
@ -343,7 +362,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
[super close];
}
- (void) dispatch
- (void) _dispatch
{
BOOL av = [self hasBytesAvailable];
NSStreamEvent myEvent = av ? NSStreamEventHasBytesAvailable :
@ -356,7 +375,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
// dispatch again iff still opened, and last event is not eos
if (av && [self _isOpened])
{
[_runloop performSelector: @selector(dispatch:)
[_runloop performSelector: @selector(_dispatch:)
target: self
argument: nil
order: 0
@ -428,7 +447,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
if (![_modes containsObject: mode])
[_modes addObject: mode];
if ([self _isOpened])
[_runloop performSelector: @selector(dispatch:)
[_runloop performSelector: @selector(_dispatch:)
target: self
argument: nil
order: 0
@ -443,7 +462,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
{
[_modes removeObject: mode];
if ([self _isOpened])
[_runloop cancelPerformSelector: @selector(dispatch:)
[_runloop cancelPerformSelector: @selector(_dispatch:)
target: self
argument: nil];
if ([_modes count] == 0)
@ -470,7 +489,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
[super open];
if (_runloop)
{
[_runloop performSelector: @selector(dispatch:)
[_runloop performSelector: @selector(_dispatch:)
target: self
argument: nil
order: 0
@ -485,7 +504,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
[super close];
}
- (void) dispatch
- (void) _dispatch
{
BOOL av = [self hasSpaceAvailable];
NSStreamEvent myEvent = av ? NSStreamEventHasSpaceAvailable :
@ -494,7 +513,7 @@ NSString * const NSStreamSOCKSProxyVersionKey
[self _sendEvent: myEvent];
// dispatch again iff still opened, and last event is not eos
if (av && [self _isOpened])
[_runloop performSelector: @selector(dispatch:)
[_runloop performSelector: @selector(_dispatch:)
target: self
argument: nil
order: 0

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@
inputStream: (NSInputStream **)inputStream
outputStream: (NSOutputStream **)outputStream
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
}
- (void) close
@ -103,25 +103,25 @@
+ (id) inputStreamWithData: (NSData *)data
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
+ (id) inputStreamWithFileAtPath: (NSString *)path
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
- (id) initWithData: (NSData *)data
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
- (id) initWithFileAtPath: (NSString *)path
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
@ -149,37 +149,37 @@
+ (id) outputStreamToMemory
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
+ (id) outputStreamToBuffer: (uint8_t *)buffer capacity: (unsigned int)capacity
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
+ (id) outputStreamToFileAtPath: (NSString *)path append: (BOOL)shouldAppend
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
- (id) initToMemory
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
- (id) initToBuffer: (uint8_t *)buffer capacity: (unsigned int)capacity
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
- (id) initToFileAtPath: (NSString *)path append: (BOOL)shouldAppend
{
[self notImplemented:_cmd];
[self notImplemented: _cmd];
return nil;
}
@ -197,3 +197,35 @@
@end
@implementation GSServerStream
+ (id) serverStreamToAddr: (NSString*)addr port: (int)port
{
[self notImplemented: _cmd];
}
+ (id) serverStreamToAddr: (NSString*)addr
{
[self notImplemented: _cmd];
}
- (id) initToAddr: (NSString*)addr port: (int)port
{
[self notImplemented: _cmd];
return nil;
}
- (id) initToAddr: (NSString*)addr
{
[self notImplemented: _cmd];
return nil;
}
- (void) acceptWithInputStream: (NSInputStream **)inputStream
outputStream: (NSOutputStream **)outputStream
{
[self subclassResponsibility: _cmd];
}
@end