mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-07 15:01:10 +00:00
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:
parent
e12d4b2648
commit
a84aca3d73
6 changed files with 777 additions and 179 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue