3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.brokenzipper.com/trac/wiki/TheCheat
6 * Copyright (c) 2003-2011, Charles McGarvey et al.
8 * Distributable under the terms and conditions of the 2-clause BSD
9 * license; see the file COPYING for the legal text of the license.
18 // this is used to read in unclaimed data
19 #define MYSOCKET_PACKETLEN (1024)
22 kMySocketAddedToManager
= 1,
23 kMySocketConnected
= 2,
24 kMySocketIsListener
= 4
28 struct _mySocketGlobals
{
29 BOOL isManagerRunning
;
30 NSMutableArray
*sockets
;
31 NSRecursiveLock
*readLock
;
32 NSRecursiveLock
*writeLock
;
39 } _mySocketGlobals
= { NO
, nil, nil, nil, { -1, -1 }, { -1, -1 }, 0, 0 };
44 @interface _MySocketPacket
: NSObject
47 unsigned _bytesHandled
;
48 unsigned _bytesRequired
;
52 - (id)initWithData
:(NSData
*)data tag
:(int)tag
;
54 - (void *)bytes
; // pointer to the current bytes; changes are bytes are handled
55 - (unsigned)bytesRemaining
;
57 - (void)handledBytes
:(unsigned)count
;
59 - (unsigned)bytesRequired
;
70 @interface MySocket ( PrivateAPI
)
72 - (id)_initWithFileDescriptor
:(int)sockfd
;
75 - (void)_addToManager
;
76 - (void)_removeFromManager
;
78 + (void)_readWithSockFD
:(int)fd
;
79 + (void)_refreshReadThread
;
80 + (void)_writeWithSockFD
:(int)fd
;
81 + (void)_refreshWriteThread
;
87 + (void)_lockReadAndWrite
;
88 + (void)_unlockReadAndWrite
;
90 /* #### MANAGER METHODS #### */
91 + (void)_startManager
;
92 + (void)_readThread
:(id)object
;
93 + (void)_writeThread
:(id)object
;
99 - (void)_fillReadPacketsWithUnclaimedBytes
;
101 - (void)_handleReadQueue
;
102 - (void)_handleWriteQueue
;
104 - (void)_eventDidAcceptSocket
:(MySocket
*)newSocket
;
105 - (void)_eventDidDisconnect
:(id)dummy
;
106 - (void)_eventDidReadData
:(_MySocketPacket
*)packet
;
107 - (void)_eventDidWriteData
:(_MySocketPacket
*)packet
;
110 - (NSMutableData
*)_readBufferWithLength
:(unsigned *)len
;
119 @implementation MySocket
122 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
123 #pragma mark Initialization
124 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
126 - (id)initWithDelegate
:(id)delegate
128 if ( self = [super init
] ) {
129 ChazLog( @
"SOCKET CREATED" );
130 [self setDelegate
:delegate
];
137 ChazLog( @
"SOCKET DESTROYED" );
145 if ( [self retainCount
] == 1 ) {
146 [self _removeFromManager
];
153 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
154 #pragma mark Connecting/Disconnecting
155 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
157 - (BOOL)connectToHost
:(NSString
*)host port
:(int)port
159 return [self connectToAddressWithData
:[MySocket addressWithHost
:host port
:port
]];
162 - (BOOL)connectToAddress
:(const struct sockaddr
*)addr length
:(unsigned)addrLen
166 if ( [self isConnected
] ) {
170 _sockfd
= socket( addr
->sa_family
, SOCK_STREAM
, 0 );
171 if ( _sockfd
== -1 ) {
172 // can't get file descriptor
175 // make the socket NOT block
176 /*err = fcntl( _sockfd, F_SETFL, O_NONBLOCK );
182 err
= connect( _sockfd
, addr
, addrLen
);
193 - (BOOL)connectToAddressWithData
:(NSData
*)addr
195 return [self connectToAddress
:[addr bytes
] length
:[addr length
]];
198 - (BOOL)listenOnPort
:(int)port
200 struct sockaddr_in addr
;
205 if ( [self isConnected
] ) {
209 _sockfd
= socket( AF_INET
, SOCK_STREAM
, 0 );
210 if ( _sockfd
== -1 ) {
211 // can't get file descriptor
214 err
= setsockopt( _sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(yes
) );
216 // can't reuse address
221 // pack the socket address structure
222 addr.sin_family
= AF_INET
;
223 addr.sin_port
= htons( (short)port
);
224 addr.sin_addr.s_addr
= INADDR_ANY
;
225 // Use 0 replace NULL
226 memset( &(addr.sin_zero
), 0, 8 );
228 err
= bind( _sockfd
, (struct sockaddr
*)(&addr
), sizeof(addr
) );
230 // can't bind to this address
235 err
= listen( _sockfd
, 10 );
237 // can't listen on this address
242 _flags |
= kMySocketIsListener
;
250 if ( !(_flags
& kMySocketConnected
) ) {
255 [self _removeFromManager
];
260 [_readQueue release
];
262 [_writeQueue release
];
266 [_writeLock release
];
275 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
276 #pragma mark Reading/Writing
277 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
279 - (void)readDataToLength
:(unsigned)len tag
:(int)tag
281 _MySocketPacket
*packet
;
283 if ( ![self isConnected
] ||
[self isListener
] || len
== 0 ) {
284 // must be connected and have a valid length
288 // create a "read" packet
289 packet
= [[_MySocketPacket alloc
] initWithData
:[NSMutableData dataWithLength
:len
] tag
:tag
];
290 //[packet handledBytes:0];
292 // add the packet to the queue
294 [_readQueue addObject
:packet
];
298 // make sure the thread picks up the change
299 [MySocket _refreshReadThread
];
303 - (void)writeData
:(NSData
*)data tag
:(int)tag
305 _MySocketPacket
*packet
;
308 if ( ![self isConnected
] ||
[self isListener
] ) {
313 // create a "write" packet
314 packet
= [[_MySocketPacket alloc
] initWithData
:data tag
:tag
];
317 alreadyWriting
= [_writeQueue count
] > 0;
318 [_writeQueue addObject
:packet
];
322 if ( !alreadyWriting
) {
323 // make the helper aware the socket has data to write
324 [MySocket _writeWithSockFD
:_sockfd
];
328 - (void)writeBytes
:(void const *)bytes length
:(unsigned)len tag
:(int)tag
330 [self writeData
:[NSData dataWithBytes
:bytes length
:len
] tag
:tag
];
334 // AsyncSocket compatibility
335 - (void)readDataToLength
:(CFIndex
)length withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
337 [self readDataToLength
:length tag
:tag
];
340 - (void)writeData
:(NSData
*)data withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
342 [self writeData
:data tag
:tag
];
345 - (void)writeBytes
:(void *)bytes length
:(unsigned)len withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
347 [self writeBytes
:bytes length
:len tag
:tag
];
351 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
352 #pragma mark Accesors
353 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
355 - (unsigned)bytesRead
360 - (unsigned)bytesWritten
362 return _bytesWritten
;
365 - (NSTimeInterval
)timeConnected
367 return CFAbsoluteTimeGetCurrent() - _startTime
;
372 double currentTime
= CFAbsoluteTimeGetCurrent();
373 double speed
= (double)( _bytesRead
- _lastBytesRead
) / ( currentTime
- _lastBytesReadTime
);
374 _lastBytesRead
= _bytesRead
;
375 _lastBytesReadTime
= currentTime
;
381 double currentTime
= CFAbsoluteTimeGetCurrent();
382 double speed
= (double)( _bytesWritten
- _lastBytesWritten
) / ( currentTime
- _lastBytesWrittenTime
);
383 _lastBytesWritten
= _bytesWritten
;
384 _lastBytesWrittenTime
= currentTime
;
389 - (NSString
*)localHost
394 err
= gethostname( host
, sizeof(host
) );
398 return [NSString stringWithCString
:host encoding
:NSUTF8StringEncoding
];
406 - (NSString
*)remoteHost
409 struct sockaddr_in addr
;
410 unsigned int len
= sizeof(addr
);
412 err
= getpeername( _sockfd
, (struct sockaddr
*)(&addr
), &len
);
416 return [NSString stringWithCString
:inet_ntoa(addr.sin_addr
) encoding
:NSUTF8StringEncoding
];
422 struct sockaddr_in addr
;
423 unsigned int len
= sizeof(addr
);
425 err
= getpeername( _sockfd
, (struct sockaddr
*)(&addr
), &len
);
429 return addr.sin_port
;
435 return _flags
& kMySocketConnected
;
440 return _flags
& kMySocketIsListener
;
444 + (NSData
*)addressWithHost
:(NSString
*)host port
:(int)port
447 struct sockaddr_in addr
;
450 h
= gethostbyname( [host cStringUsingEncoding
:NSUTF8StringEncoding
] );
456 // pack the socket address structure
457 addr.sin_family
= AF_INET
;
458 addr.sin_port
= htons( (short)port
);
459 memcpy( &(addr.sin_addr
), h
->h_addr
, sizeof(struct in_addr
) );
460 // Use 0 replace NULL
461 memset( &(addr.sin_zero
), 0, 8 );
463 return [NSData dataWithBytes
:&addr length
:sizeof(addr
)];
472 - (void)setDelegate
:(id)delegate
474 _delegate
= delegate
;
478 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
479 #pragma mark PrivateAPI
480 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
482 - (id)_initWithFileDescriptor
:(int)sockfd
484 if ( self = [super init
] ) {
493 if ( ![self isListener
] ) {
494 _readQueue
= [[NSMutableArray alloc
] init
];
495 _writeQueue
= [[NSMutableArray alloc
] init
];
499 _readLock
= [[NSRecursiveLock alloc
] init
];
500 _writeLock
= [[NSRecursiveLock alloc
] init
];
502 _startTime
= _lastBytesReadTime
= _lastBytesWrittenTime
= CFAbsoluteTimeGetCurrent();
503 _bytesRead
= _lastBytesRead
= _bytesWritten
= _lastBytesWritten
= 0;
505 _flags |
= kMySocketConnected
;
507 [self _addToManager
];
511 - (void)_addToManager
513 if ( _flags
& kMySocketAddedToManager
) {
514 // only add this socket once
518 // start the manager if it is not already started
519 [MySocket _startManager
];
521 [MySocket _lockReadAndWrite
];
522 // add to global array of sockets
523 [_mySocketGlobals.sockets addObject
:self];
525 [MySocket _readWithSockFD
:_sockfd
];
526 [MySocket _unlockReadAndWrite
];
528 // mark as added to manager
529 _flags |
= kMySocketAddedToManager
;
532 - (void)_removeFromManager
534 if ( !(_flags
& kMySocketAddedToManager
) ) {
535 // only remove if it is added
539 [MySocket _lockReadAndWrite
];
540 // remove from global array
542 ChazLog( @
"REMOVING SOCKET AT INDEX %i", [_mySocketGlobals.sockets indexOfObject
:self] );
543 [_mySocketGlobals.sockets removeObject
:self];
544 FD_CLR( _sockfd
, &_mySocketGlobals.readfds
);
545 FD_CLR( _sockfd
, &_mySocketGlobals.writefds
);
546 [MySocket _unlockReadAndWrite
];
548 _flags ^
= kMySocketAddedToManager
;
552 + (void)_readWithSockFD
:(int)fd
554 [MySocket _lockRead
];
555 FD_SET( fd
, &_mySocketGlobals.readfds
);
556 _mySocketGlobals.maxreadfd
= MAX( _mySocketGlobals.maxreadfd
, fd
);
557 [MySocket _unlockRead
];
558 // make sure the thread picks up the change
559 [MySocket _refreshReadThread
];
562 + (void)_refreshReadThread
565 write( _mySocketGlobals.readPipe
[1], &b
, sizeof(b
) );
568 + (void)_writeWithSockFD
:(int)fd
570 [MySocket _lockWrite
];
571 FD_SET( fd
, &_mySocketGlobals.writefds
);
572 _mySocketGlobals.maxwritefd
= MAX( _mySocketGlobals.maxwritefd
, fd
);
573 [MySocket _unlockWrite
];
574 [MySocket _refreshWriteThread
];
577 + (void)_refreshWriteThread
580 write( _mySocketGlobals.writePipe
[1], &b
, sizeof(b
) );
586 [_mySocketGlobals.readLock lock
];
591 [_mySocketGlobals.readLock unlock
];
596 [_mySocketGlobals.writeLock lock
];
601 [_mySocketGlobals.writeLock unlock
];
604 + (void)_lockReadAndWrite
606 [MySocket _lockRead
];
607 [MySocket _lockWrite
];
610 + (void)_unlockReadAndWrite
612 [MySocket _unlockRead
];
613 [MySocket _unlockWrite
];
617 + (void)_startManager
621 if ( _mySocketGlobals.isManagerRunning
) {
625 ChazLog( @
"MySocketHelper STARTING" );
627 // zero the descriptor sets
628 FD_ZERO( &_mySocketGlobals.readfds
);
629 FD_ZERO( &_mySocketGlobals.writefds
);
631 // create the read pipe
632 err
= pipe( _mySocketGlobals.readPipe
);
636 FD_SET( _mySocketGlobals.readPipe
[0], &_mySocketGlobals.readfds
);
637 _mySocketGlobals.maxreadfd
= _mySocketGlobals.readPipe
[0];
638 // create the write pipe
639 err
= pipe( _mySocketGlobals.writePipe
);
641 close( _mySocketGlobals.readPipe
[0] );
642 close( _mySocketGlobals.readPipe
[1] );
645 _mySocketGlobals.maxwritefd
= _mySocketGlobals.writePipe
[0];
647 // create other global objects
648 _mySocketGlobals.sockets
= [[NSMutableArray alloc
] init
];
649 _mySocketGlobals.readLock
= [[NSRecursiveLock alloc
] init
];
650 _mySocketGlobals.writeLock
= [[NSRecursiveLock alloc
] init
];
653 [NSThread detachNewThreadSelector
:@selector(_readThread
:) toTarget
:[MySocket
class] withObject
:nil];
654 [NSThread detachNewThreadSelector
:@selector(_writeThread
:) toTarget
:[MySocket
class] withObject
:nil];
655 _mySocketGlobals.isManagerRunning
= YES
;
658 + (void)_readThread
:(id)object
667 // create the ever-so-important pool
668 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
670 [MySocket _lockRead
];
671 //FD_COPY( &_mySocketGlobals.readfds, &readfds );
672 readfds
= _mySocketGlobals.readfds
;
673 [MySocket _unlockRead
];
675 // find the sockets which need processing
676 err
= select( _mySocketGlobals.maxreadfd
+1, &readfds
, NULL
, NULL
, NULL
);
678 // trouble, select() is having problems
679 ChazLog( @
"select() failed!, error: %s", strerror(errno
) );
684 if ( FD_ISSET( _mySocketGlobals.readPipe
[0], &readfds
) ) {
686 err
= read( _mySocketGlobals.readPipe
[0], &b
, sizeof(b
) );
688 // our connection to the main thread was severed...
690 ChazLog( @
"readPipe severed, exiting READ thread..." );
696 // process the sockets
697 [MySocket _lockRead
];
698 top
= [_mySocketGlobals.sockets count
];
699 for ( i
= 0; i
< top
; i
++ ) {
700 MySocket
*sock
= [_mySocketGlobals.sockets objectAtIndex
:i
];
701 int sockfd
= [sock _sockfd
];
703 [sock _fillReadPacketsWithUnclaimedBytes
];
704 [sock _handleReadQueue
];
706 if ( FD_ISSET( sockfd
, &readfds
) ) {
707 if ( [sock isListener
] ) {
708 // socket ready for accepting
709 err
= [sock _accept
];
712 // socket ready for reading
716 // action returne error, disconnect socket
718 [sock performSelectorOnMainThread
:@selector(_eventDidDisconnect
:)
719 withObject
:nil waitUntilDone
:NO
];
724 [MySocket _unlockRead
];
729 while ( !breakLoop
);
732 + (void)_writeThread
:(id)object
736 fd_set readfds
, writefds
;
739 FD_SET( _mySocketGlobals.writePipe
[0], &pipefds
);
745 // create the ever-so-important pool
746 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
749 [MySocket _lockWrite
];
750 //FD_COPY( &_mySocketGlobals.writefds, &writefds );
751 writefds
= _mySocketGlobals.writefds
;
752 [MySocket _unlockWrite
];
754 // find the sockets which need processing
755 err
= select( _mySocketGlobals.maxwritefd
+1, &readfds
, &writefds
, NULL
, NULL
);
757 // trouble, select() is having problems
758 ChazLog( @
"select() failed!, error: %s", strerror(errno
) );
763 if ( FD_ISSET( _mySocketGlobals.writePipe
[0], &readfds
) ) {
765 err
= read( _mySocketGlobals.writePipe
[0], &b
, sizeof(b
) );
767 // our connection to the main thread was severed...
769 ChazLog( @
"writePipe severed" );
775 // process the sockets
776 [MySocket _lockWrite
];
777 top
= [_mySocketGlobals.sockets count
];
778 for ( i
= 0; i
< top
; i
++ ) {
779 MySocket
*sock
= [_mySocketGlobals.sockets objectAtIndex
:i
];
780 int sockfd
= [sock _sockfd
];
782 if ( FD_ISSET( sockfd
, &writefds
) ) {
783 // socket ready for accepting
786 // action returne error, disconnect socket
788 [sock performSelectorOnMainThread
:@selector(_eventDidDisconnect
:)
789 withObject
:nil waitUntilDone
:NO
];
794 [MySocket _unlockWrite
];
799 while ( !breakLoop
);
807 struct sockaddr addr
;
808 unsigned int addrlen
= sizeof(addr
);
810 newsockfd
= accept( _sockfd
, &addr
, &addrlen
);
811 if ( newsockfd
>= 0 ) {
812 // create a new MySocket
813 newSocket
= [[MySocket alloc
] _initWithFileDescriptor
:newsockfd
];
814 [newSocket setDelegate
:_delegate
];
816 [self performSelectorOnMainThread
:@selector(_eventDidAcceptSocket
:)
817 withObject
:newSocket waitUntilDone
:NO
];
827 _MySocketPacket
*packet
= nil;
831 if ( [_readQueue count
] == 0 ) {
832 // no packets claiming anything, so just
833 // read into the unclaimed bytes buffer.
834 if ( !_unclaimedData
) {
835 _unclaimedData
= [[NSMutableData alloc
] init
];
837 int len
= [_unclaimedData length
];
838 [_unclaimedData increaseLengthBy
:MYSOCKET_PACKETLEN
];
839 bytesRead
= recv( _sockfd
, [_unclaimedData mutableBytes
] + len
, MYSOCKET_PACKETLEN
, 0 );
840 [_unclaimedData setLength
:len
+bytesRead
];
843 packet
= [_readQueue objectAtIndex
:0];
844 bytesRead
= recv( _sockfd
, [packet bytes
], [packet bytesRemaining
], 0 );
845 [packet handledBytes
:bytesRead
];
849 if ( bytesRead
> 0 ) {
850 // update total bytes read
851 _bytesRead
+= bytesRead
;
853 [self _handleReadQueue
];
856 // remove this socket
857 ChazLog( @
"MySocket disconnecting: %i", bytesRead
);
865 _MySocketPacket
*packet
= nil;
866 int bytesWritten
= 0;
869 if ( [_writeQueue count
] > 0 ) {
871 unsigned int len
= sizeof(buflen
);
873 err
= getsockopt( _sockfd
, SOL_SOCKET
, SO_SNDBUF
, &buflen
, &len
);
875 packet
= [_writeQueue objectAtIndex
:0];
876 bytesWritten
= send( _sockfd
, [packet bytes
], MIN([packet bytesRemaining
],buflen
/2), 0 ); //MIN(4096,[packet bytesRemaining]), 0 );
877 [packet handledBytes
:bytesWritten
];
881 if ( bytesWritten
>= 0 ) {
882 // update total bytes read
883 _bytesWritten
+= bytesWritten
;
885 [self _handleWriteQueue
];
894 - (void)_fillReadPacketsWithUnclaimedBytes
900 total
= [_unclaimedData length
];
904 bytes
= [_unclaimedData mutableBytes
];
907 top
= [_readQueue count
];
908 for ( i
= 0; i
< top
; i
++ ) {
909 _MySocketPacket
*packet
= [_readQueue objectAtIndex
:i
];
910 int len
= MIN( total
, [packet bytesRemaining
] );
913 memcpy( [packet bytes
], bytes
, len
);
914 [packet handledBytes
:len
];
922 [_unclaimedData replaceBytesInRange
:NSMakeRange(0,[_unclaimedData length
]-total
) withBytes
:NULL length
:0];
927 - (void)_handleReadQueue
932 top
= [_readQueue count
];
933 for ( i
= 0; i
< top
; ) {
934 _MySocketPacket
*packet
= [_readQueue objectAtIndex
:0];
935 if ( [packet isComplete
] ) {
936 [self performSelectorOnMainThread
:@selector(_eventDidReadData
:)
937 withObject
:[packet retain
] waitUntilDone
:NO
];
938 [_readQueue removeObjectAtIndex
:i
];
948 - (void)_handleWriteQueue
953 top
= [_writeQueue count
];
954 for ( i
= 0; i
< top
; ) {
955 _MySocketPacket
*packet
= [_writeQueue objectAtIndex
:0];
956 if ( [packet isComplete
] ) {
957 [self performSelectorOnMainThread
:@selector(_eventDidWriteData
:)
958 withObject
:[packet retain
] waitUntilDone
:NO
];
959 [_writeQueue removeObjectAtIndex
:i
];
966 if ( [_writeQueue count
] == 0 ) {
967 // no more pending writes
968 FD_CLR( _sockfd
, &_mySocketGlobals.writefds
);
974 - (void)_eventDidAcceptSocket
:(MySocket
*)newSocket
976 // just report the event back to the delegate
977 if ( [_delegate respondsToSelector
:@selector(socket
:didAcceptSocket
:)] ) {
978 [_delegate socket
:self didAcceptSocket
:newSocket
];
981 // release the parameter(s)
982 // they were not released by the caller because the caller is in another thread.
986 - (void)_eventDidDisconnect
:(id)dummy
989 if ( [_delegate respondsToSelector
:@selector(socketDidDisconnect
:)] ) {
990 [_delegate socketDidDisconnect
:self];
994 - (void)_eventDidReadData
:(_MySocketPacket
*)packet
996 if ( [_delegate respondsToSelector
:@selector(socket
:didReadData
:tag
:)] ) {
997 [_delegate socket
:self didReadData
:[packet data
] tag
:[packet tag
]];
1003 - (void)_eventDidWriteData
:(_MySocketPacket
*)packet
1005 if ( [_delegate respondsToSelector
:@selector(socket
:didWriteDataWithTag
:)] ) {
1006 [_delegate socket
:self didWriteDataWithTag
:[packet tag
]];
1013 - (NSMutableData
*)_readBufferWithLength
:(unsigned *)len
1015 NSMutableData
*buffer
;
1016 unsigned packetLen
= *len
;
1018 if ( (buffer
= _unclaimedData
) ) {
1020 int unclaimedLen
= [_unclaimedData length
];
1021 if ( unclaimedLen
> packetLen
) {
1023 _unclaimedData
= [[NSMutableData alloc
] initWithBytes
:[buffer bytes
]+packetLen length
:unclaimedLen
-packetLen
];
1024 //[[buffer subdataWithRange:NSMakeRange(packetLen,unclaimedLen-packetLen)] retain];
1027 *len
= unclaimedLen
;
1028 _unclaimedData
= nil;
1030 [buffer setLength
:packetLen
];
1033 buffer
= [[NSMutableData alloc
] initWithLength
:packetLen
];
1036 return [buffer autorelease
];
1049 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1050 #pragma mark _MySocketPacket
1051 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1053 @implementation _MySocketPacket
1056 - (id)initWithData
:(NSData
*)data tag
:(int)tag
1058 if ( self = [super init
] ) {
1059 _buffer
= [data retain
];
1060 _bytesRequired
= [data length
];
1075 return (void *)[_buffer bytes
] + _bytesHandled
;
1078 - (unsigned)bytesRemaining
1080 return _bytesRequired
- _bytesHandled
;
1084 - (void)handledBytes
:(unsigned)count
1086 _bytesHandled
+= count
;
1089 - (unsigned)bytesRequired
1091 return _bytesRequired
;
1107 return [self bytesRemaining
] == 0;