mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
Some tweaks for invocations and for networking.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25140 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1855046feb
commit
7c633ab823
6 changed files with 355 additions and 29 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2007-05-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSStream.m:
|
||||
* Source/unix/NSStream.m:
|
||||
* Source/win32/NSStreamWin32.m:
|
||||
* Headers/Foundation/NSStream.h:
|
||||
First hack at extensions to get address and port properties for
|
||||
network streams.
|
||||
* Source/GSFFIInvocation.m:
|
||||
Attempt to use forward2 if available.
|
||||
|
||||
2007-05-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSURLResponse.m:
|
||||
|
|
|
@ -329,6 +329,15 @@ GS_EXPORT NSString * const NSStreamSOCKSProxyVersion4;
|
|||
GS_EXPORT NSString * const NSStreamSOCKSProxyVersion5;
|
||||
GS_EXPORT NSString * const NSStreamSOCKSProxyVersionKey;
|
||||
|
||||
/** May be used to read the local IP address of a tcp/ip network stream. */
|
||||
GS_EXPORT NSString * const GSStreamLocalAddressKey;
|
||||
/** May be used to read the local port of a tcp/ip network stream. */
|
||||
GS_EXPORT NSString * const GSStreamLocalPortKey;
|
||||
/** May be used to read the remote IP address of a tcp/ip network stream. */
|
||||
GS_EXPORT NSString * const GSStreamRemoteAddressKey;
|
||||
/** May be used to read the remote port of a tcp/ip network stream. */
|
||||
GS_EXPORT NSString * const GSStreamRemotePortKey;
|
||||
|
||||
/**
|
||||
* Informal protocol for delegates of instance of the [NSStream] class.
|
||||
*/
|
||||
|
|
|
@ -141,37 +141,40 @@ gs_find_by_receiver_best_typed_sel (id receiver, SEL sel)
|
|||
|
||||
@implementation GSFFIInvocation
|
||||
|
||||
static IMP gs_objc_msg_forward (SEL sel)
|
||||
static IMP gs_objc_msg_forward2 (id receiver, SEL sel)
|
||||
{
|
||||
const char *sel_type;
|
||||
cifframe_t *cframe;
|
||||
ffi_closure *cclosure;
|
||||
|
||||
NSMethodSignature *sig;
|
||||
|
||||
/* Determine the method types so we can construct the frame. We may not
|
||||
get the right one, though. What to do then? Perhaps it can be fixed up
|
||||
in the callback, but only under limited circumstances.
|
||||
*/
|
||||
sel_type = sel_get_type (sel);
|
||||
sig = nil;
|
||||
sig = [receiver methodSignatureForSelector: sel];
|
||||
|
||||
if (sel_type)
|
||||
if (sig == nil)
|
||||
{
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: sel_type];
|
||||
}
|
||||
else
|
||||
{
|
||||
static NSMethodSignature *def = nil;
|
||||
const char *sel_type;
|
||||
|
||||
/*
|
||||
* Default signature is for a method returning an object.
|
||||
/* Determine the method types so we can construct the frame. We may not
|
||||
get the right one, though. What to do then? Perhaps it can be fixed up
|
||||
in the callback, but only under limited circumstances.
|
||||
*/
|
||||
if (def == nil)
|
||||
sel_type = sel_get_type (sel);
|
||||
if (sel_type)
|
||||
{
|
||||
def = RETAIN([NSMethodSignature signatureWithObjCTypes: "@@:"]);
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: sel_type];
|
||||
}
|
||||
else
|
||||
{
|
||||
static NSMethodSignature *def = nil;
|
||||
|
||||
/*
|
||||
* Default signature is for a method returning an object.
|
||||
*/
|
||||
if (def == nil)
|
||||
{
|
||||
def = RETAIN([NSMethodSignature signatureWithObjCTypes: "@@:"]);
|
||||
}
|
||||
sig = def;
|
||||
}
|
||||
sig = def;
|
||||
}
|
||||
|
||||
NSCAssert1(sig, @"No signature for selector %@", NSStringFromSelector(sel));
|
||||
|
@ -188,7 +191,7 @@ static IMP gs_objc_msg_forward (SEL sel)
|
|||
[NSException raise: NSMallocException format: @"Allocating closure"];
|
||||
}
|
||||
if (ffi_prep_closure(cclosure, &(cframe->cif),
|
||||
GSFFIInvocationCallback, cframe) != FFI_OK)
|
||||
GSFFIInvocationCallback, cframe) != FFI_OK)
|
||||
{
|
||||
[NSException raise: NSGenericException format: @"Preping closure"];
|
||||
}
|
||||
|
@ -196,9 +199,18 @@ static IMP gs_objc_msg_forward (SEL sel)
|
|||
return (IMP)cclosure;
|
||||
}
|
||||
|
||||
static IMP gs_objc_msg_forward (SEL sel)
|
||||
{
|
||||
return gs_objc_msg_forward2 (nil, sel);
|
||||
}
|
||||
|
||||
+ (void) load
|
||||
{
|
||||
#if HAVE_FORWARD2
|
||||
__objc_msg_forward2 = gs_objc_msg_forward2;
|
||||
#else
|
||||
__objc_msg_forward = gs_objc_msg_forward;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector
|
||||
|
@ -522,7 +534,7 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
|
|||
not the invocation so it will be demallocd at the end of this call
|
||||
*/
|
||||
if ([sig methodReturnType] && *[sig methodReturnType] == _C_ID
|
||||
&& ((NSInvocation_t *)invocation)->_validReturn == YES)
|
||||
&& ((NSInvocation_t *)invocation)->_validReturn == YES)
|
||||
{
|
||||
AUTORELEASE(*(id *)retp);
|
||||
((NSInvocation_t *)invocation)->_validReturn = NO;
|
||||
|
|
|
@ -73,6 +73,15 @@ NSString * const NSStreamSOCKSProxyVersion5
|
|||
NSString * const NSStreamSOCKSProxyVersionKey
|
||||
= @"NSStreamSOCKSProxyVersionKey";
|
||||
|
||||
NSString * const GSStreamLocalAddressKey
|
||||
= @"GSStreamLocalAddressKey";
|
||||
NSString * const GSStreamLocalPortKey
|
||||
= @"GSStreamLocalPortKey";
|
||||
NSString * const GSStreamRemoteAddressKey
|
||||
= @"GSStreamRemoteAddressKey";
|
||||
NSString * const GSStreamRemotePortKey
|
||||
= @"GSStreamRemotePortKey";
|
||||
|
||||
|
||||
/*
|
||||
* Determine the type of event to use when adding a stream to the run loop.
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <Foundation/NSError.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSHost.h>
|
||||
#include <Foundation/NSByteOrder.h>
|
||||
|
||||
#include "../GSStream.h"
|
||||
|
||||
|
@ -54,6 +55,99 @@
|
|||
#define socklen_t uint32_t
|
||||
#endif
|
||||
|
||||
static id propertyForInet4Stream(int descriptor, NSString *key)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
unsigned size = sizeof(sin);
|
||||
id result = nil;
|
||||
|
||||
if ([key isEqualToString: GSStreamLocalAddressKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithUTF8String:
|
||||
(char*)inet_ntoa(sin.sin_addr)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamLocalPortKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin_port)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemoteAddressKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithUTF8String:
|
||||
(char*)inet_ntoa(sin.sin_addr)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemotePortKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin_port)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||
{
|
||||
struct sockaddr_in6 sin;
|
||||
unsigned size = sizeof(sin);
|
||||
id result = nil;
|
||||
|
||||
if ([key isEqualToString: GSStreamLocalAddressKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
|
||||
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
|
||||
{
|
||||
buf[INET6_ADDRSTRLEN] = '\0';
|
||||
result = [NSString stringWithUTF8String: buf];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamLocalPortKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin6_port)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemoteAddressKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
|
||||
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
|
||||
{
|
||||
buf[INET6_ADDRSTRLEN] = '\0';
|
||||
result = [NSString stringWithUTF8String: buf];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemotePortKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin6_port)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The concrete subclass of NSInputStream that reads from a file
|
||||
*/
|
||||
|
@ -80,7 +174,7 @@
|
|||
- (socklen_t) sockLen;
|
||||
|
||||
/**
|
||||
* get the sockaddr
|
||||
* get the remote sockaddr
|
||||
*/
|
||||
- (struct sockaddr*) peerAddr;
|
||||
|
||||
|
@ -626,7 +720,7 @@ static void setNonblocking(int fd)
|
|||
if ((self = [super init]) != nil)
|
||||
{
|
||||
_peerAddr.sin_family = AF_INET;
|
||||
_peerAddr.sin_port = htons(port);
|
||||
_peerAddr.sin_port = GSSwapHostI16ToBig(port);
|
||||
ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
|
||||
if (ptonReturn == 0) // error
|
||||
{
|
||||
|
@ -636,6 +730,17 @@ static void setNonblocking(int fd)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id) propertyForKey: (NSString *)key
|
||||
{
|
||||
id result = propertyForInet4Stream((intptr_t)_loopID, key);
|
||||
|
||||
if (result == nil)
|
||||
{
|
||||
result = [super propertyForKey: key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSInet6InputStream
|
||||
|
@ -658,7 +763,7 @@ static void setNonblocking(int fd)
|
|||
if ((self = [super init]) != nil)
|
||||
{
|
||||
_peerAddr.sin6_family = AF_INET6;
|
||||
_peerAddr.sin6_port = htons(port);
|
||||
_peerAddr.sin6_port = GSSwapHostI16ToBig(port);
|
||||
ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
|
||||
if (ptonReturn == 0) // error
|
||||
{
|
||||
|
@ -667,6 +772,18 @@ static void setNonblocking(int fd)
|
|||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) propertyForKey: (NSString *)key
|
||||
{
|
||||
id result = propertyForInet6Stream((intptr_t)_loopID, key);
|
||||
|
||||
if (result == nil)
|
||||
{
|
||||
result = [super propertyForKey: key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||
{
|
||||
|
@ -1038,7 +1155,7 @@ static void setNonblocking(int fd)
|
|||
if ((self = [super init]) != nil)
|
||||
{
|
||||
_peerAddr.sin_family = AF_INET;
|
||||
_peerAddr.sin_port = htons(port);
|
||||
_peerAddr.sin_port = GSSwapHostI16ToBig(port);
|
||||
ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
|
||||
if (ptonReturn == 0) // error
|
||||
{
|
||||
|
@ -1048,6 +1165,17 @@ static void setNonblocking(int fd)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id) propertyForKey: (NSString *)key
|
||||
{
|
||||
id result = propertyForInet4Stream((intptr_t)_loopID, key);
|
||||
|
||||
if (result == nil)
|
||||
{
|
||||
result = [super propertyForKey: key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSInet6OutputStream
|
||||
|
@ -1070,7 +1198,7 @@ static void setNonblocking(int fd)
|
|||
if ((self = [super init]) != nil)
|
||||
{
|
||||
_peerAddr.sin6_family = AF_INET6;
|
||||
_peerAddr.sin6_port = htons(port);
|
||||
_peerAddr.sin6_port = GSSwapHostI16ToBig(port);
|
||||
ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
|
||||
if (ptonReturn == 0) // error
|
||||
{
|
||||
|
@ -1079,6 +1207,18 @@ static void setNonblocking(int fd)
|
|||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) propertyForKey: (NSString *)key
|
||||
{
|
||||
id result = propertyForInet6Stream((intptr_t)_loopID, key);
|
||||
|
||||
if (result == nil)
|
||||
{
|
||||
result = [super propertyForKey: key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||
{
|
||||
|
@ -1585,7 +1725,7 @@ static void setNonblocking(int fd)
|
|||
|
||||
[super init];
|
||||
_serverAddr.sin_family = AF_INET;
|
||||
_serverAddr.sin_port = htons(port);
|
||||
_serverAddr.sin_port = GSSwapHostI16ToBig(port);
|
||||
ptonReturn = inet_pton(AF_INET, addr_c, &(_serverAddr.sin_addr));
|
||||
_loopID = (void*)(intptr_t)socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (ptonReturn == 0 || _loopID < 0) // error
|
||||
|
@ -1628,7 +1768,7 @@ static void setNonblocking(int fd)
|
|||
|
||||
[super init];
|
||||
_serverAddr.sin6_family = AF_INET6;
|
||||
_serverAddr.sin6_port = htons(port);
|
||||
_serverAddr.sin6_port = GSSwapHostI16ToBig(port);
|
||||
ptonReturn = inet_pton(AF_INET6, addr_c, &(_serverAddr.sin6_addr));
|
||||
_loopID = (void*)(intptr_t)socket(AF_INET6, SOCK_STREAM, 0);
|
||||
if (ptonReturn == 0 || _loopID < 0) // error
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <Foundation/NSHost.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSByteOrder.h>
|
||||
|
||||
#include "../GSStream.h"
|
||||
#include "../GSPrivate.h"
|
||||
|
@ -50,6 +51,47 @@
|
|||
|
||||
typedef int socklen_t;
|
||||
|
||||
static id propertyForInet4Stream(int descriptor, NSString *key)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
unsigned size = sizeof(sin);
|
||||
id result = nil;
|
||||
|
||||
if ([key isEqualToString: GSStreamLocalAddressKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithUTF8String:
|
||||
(char*)inet_ntoa(sin.sin_addr)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamLocalPortKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin_port)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemoteAddressKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithUTF8String:
|
||||
(char*)inet_ntoa(sin.sin_addr)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemotePortKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin_port)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The concrete subclass of NSInputStream that reads from a file
|
||||
*/
|
||||
|
@ -1030,6 +1072,98 @@ static void setNonblocking(SOCKET fd)
|
|||
return self;
|
||||
}
|
||||
|
||||
static id propertyForInet4Stream(int descriptor, NSString *key)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
unsigned size = sizeof(sin);
|
||||
id result = nil;
|
||||
|
||||
if ([key isEqualToString: GSStreamLocalAddressKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithUTF8String:
|
||||
(char*)inet_ntoa(sin.sin_addr)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamLocalPortKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin_port)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemoteAddressKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithUTF8String:
|
||||
(char*)inet_ntoa(sin.sin_addr)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemotePortKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin_port)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#if defined(AF_INET6)
|
||||
static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||
{
|
||||
struct sockaddr_in6 sin;
|
||||
unsigned size = sizeof(sin);
|
||||
id result = nil;
|
||||
|
||||
if ([key isEqualToString: GSStreamLocalAddressKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
|
||||
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
|
||||
{
|
||||
buf[INET6_ADDRSTRLEN] = '\0';
|
||||
result = [NSString stringWithUTF8String: buf];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamLocalPortKey])
|
||||
{
|
||||
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin6_port)];
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemoteAddressKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
|
||||
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
|
||||
{
|
||||
buf[INET6_ADDRSTRLEN] = '\0';
|
||||
result = [NSString stringWithUTF8String: buf];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([key isEqualToString: GSStreamRemotePortKey])
|
||||
{
|
||||
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
|
||||
{
|
||||
result = [NSString stringWithFormat: @"%d",
|
||||
(int)GSSwapBigI16ToHost(sin.sin6_port)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation GSFileOutputStream
|
||||
|
@ -1772,6 +1906,17 @@ static void setNonblocking(SOCKET fd)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id) propertyForKey: (NSString *)key
|
||||
{
|
||||
id result = propertyForInet4Stream((intptr_t)_loopID, key);
|
||||
|
||||
if (result == nil)
|
||||
{
|
||||
result = [super propertyForKey: key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSStream
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue