2 // **********************************************************************
3 // The Cheat - A universal game cheater for Mac OS X
4 // (C) 2003-2005 Chaz McGarvey (BrokenZipper)
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 1, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 // this is used to read in unclaimed data
28 #define MYSOCKET_PACKETLEN (1024)
31 kMySocketAddedToManager
= 1,
32 kMySocketConnected
= 2,
33 kMySocketIsListener
= 4
37 struct _mySocketGlobals
{
38 BOOL isManagerRunning
;
39 NSMutableArray
*sockets
;
40 NSRecursiveLock
*readLock
;
41 NSRecursiveLock
*writeLock
;
48 } _mySocketGlobals
= { NO
, nil, nil, nil, { -1, -1 }, { -1, -1 }, 0, 0 };
53 @interface _MySocketPacket
: NSObject
56 unsigned _bytesHandled
;
57 unsigned _bytesRequired
;
61 - (id)initWithData
:(NSData
*)data tag
:(int)tag
;
63 - (void *)bytes
; // pointer to the current bytes; changes are bytes are handled
64 - (unsigned)bytesRemaining
;
66 - (void)handledBytes
:(unsigned)count
;
68 - (unsigned)bytesRequired
;
79 @interface MySocket ( PrivateAPI
)
81 - (id)_initWithFileDescriptor
:(int)sockfd
;
84 - (void)_addToManager
;
85 - (void)_removeFromManager
;
87 + (void)_readWithSockFD
:(int)fd
;
88 + (void)_refreshReadThread
;
89 + (void)_writeWithSockFD
:(int)fd
;
90 + (void)_refreshWriteThread
;
96 + (void)_lockReadAndWrite
;
97 + (void)_unlockReadAndWrite
;
99 /* #### MANAGER METHODS #### */
100 + (void)_startManager
;
101 + (void)_readThread
:(id)object
;
102 + (void)_writeThread
:(id)object
;
108 - (void)_fillReadPacketsWithUnclaimedBytes
;
110 - (void)_handleReadQueue
;
111 - (void)_handleWriteQueue
;
113 - (void)_eventDidAcceptSocket
:(MySocket
*)newSocket
;
114 - (void)_eventDidDisconnect
:(id)dummy
;
115 - (void)_eventDidReadData
:(_MySocketPacket
*)packet
;
116 - (void)_eventDidWriteData
:(_MySocketPacket
*)packet
;
119 - (NSMutableData
*)_readBufferWithLength
:(unsigned *)len
;
128 @implementation MySocket
131 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
132 #pragma mark Initialization
133 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
135 - (id)initWithDelegate
:(id)delegate
137 if ( self = [super init
] ) {
138 ChazLog( @
"SOCKET CREATED" );
139 [self setDelegate
:delegate
];
146 ChazLog( @
"SOCKET DESTROYED" );
154 if ( [self retainCount
] == 1 ) {
155 [self _removeFromManager
];
162 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
163 #pragma mark Connecting/Disconnecting
164 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
166 - (BOOL)connectToHost
:(NSString
*)host port
:(int)port
168 return [self connectToAddressWithData
:[MySocket addressWithHost
:host port
:port
]];
171 - (BOOL)connectToAddress
:(const struct sockaddr
*)addr length
:(unsigned)addrLen
175 if ( [self isConnected
] ) {
179 _sockfd
= socket( addr
->sa_family
, SOCK_STREAM
, 0 );
180 if ( _sockfd
== -1 ) {
181 // can't get file descriptor
184 // make the socket NOT block
185 /*err = fcntl( _sockfd, F_SETFL, O_NONBLOCK );
191 err
= connect( _sockfd
, addr
, addrLen
);
202 - (BOOL)connectToAddressWithData
:(NSData
*)addr
204 return [self connectToAddress
:[addr bytes
] length
:[addr length
]];
207 - (BOOL)listenOnPort
:(int)port
209 struct sockaddr_in addr
;
214 if ( [self isConnected
] ) {
218 _sockfd
= socket( AF_INET
, SOCK_STREAM
, 0 );
219 if ( _sockfd
== -1 ) {
220 // can't get file descriptor
223 err
= setsockopt( _sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(yes
) );
225 // can't reuse address
230 // pack the socket address structure
231 addr.sin_family
= AF_INET
;
232 addr.sin_port
= htons( (short)port
);
233 addr.sin_addr.s_addr
= INADDR_ANY
;
234 memset( &(addr.sin_zero
), NULL
, 8 );
236 err
= bind( _sockfd
, (struct sockaddr
*)(&addr
), sizeof(addr
) );
238 // can't bind to this address
243 err
= listen( _sockfd
, 10 );
245 // can't listen on this address
250 _flags |
= kMySocketIsListener
;
258 if ( !(_flags
& kMySocketConnected
) ) {
263 [self _removeFromManager
];
268 [_readQueue release
];
270 [_writeQueue release
];
274 [_writeLock release
];
283 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
284 #pragma mark Reading/Writing
285 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
287 - (void)readDataToLength
:(unsigned)len tag
:(int)tag
289 _MySocketPacket
*packet
;
291 if ( ![self isConnected
] ||
[self isListener
] || len
== 0 ) {
292 // must be connected and have a valid length
296 // create a "read" packet
297 packet
= [[_MySocketPacket alloc
] initWithData
:[NSMutableData dataWithLength
:len
] tag
:tag
];
298 //[packet handledBytes:0];
300 // add the packet to the queue
302 [_readQueue addObject
:packet
];
306 // make sure the thread picks up the change
307 [MySocket _refreshReadThread
];
311 - (void)writeData
:(NSData
*)data tag
:(int)tag
313 _MySocketPacket
*packet
;
316 if ( ![self isConnected
] ||
[self isListener
] ) {
321 // create a "write" packet
322 packet
= [[_MySocketPacket alloc
] initWithData
:data tag
:tag
];
325 alreadyWriting
= [_writeQueue count
] > 0;
326 [_writeQueue addObject
:packet
];
330 if ( !alreadyWriting
) {
331 // make the helper aware the socket has data to write
332 [MySocket _writeWithSockFD
:_sockfd
];
336 - (void)writeBytes
:(void const *)bytes length
:(unsigned)len tag
:(int)tag
338 [self writeData
:[NSData dataWithBytes
:bytes length
:len
] tag
:tag
];
342 // AsyncSocket compatibility
343 - (void)readDataToLength
:(CFIndex
)length withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
345 [self readDataToLength
:length tag
:tag
];
348 - (void)writeData
:(NSData
*)data withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
350 [self writeData
:data tag
:tag
];
353 - (void)writeBytes
:(void *)bytes length
:(unsigned)len withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
355 [self writeBytes
:bytes length
:len tag
:tag
];
359 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
360 #pragma mark Accesors
361 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
363 - (unsigned)bytesRead
368 - (unsigned)bytesWritten
370 return _bytesWritten
;
373 - (NSTimeInterval
)timeConnected
375 return CFAbsoluteTimeGetCurrent() - _startTime
;
380 double currentTime
= CFAbsoluteTimeGetCurrent();
381 double speed
= (double)( _bytesRead
- _lastBytesRead
) / ( currentTime
- _lastBytesReadTime
);
382 _lastBytesRead
= _bytesRead
;
383 _lastBytesReadTime
= currentTime
;
389 double currentTime
= CFAbsoluteTimeGetCurrent();
390 double speed
= (double)( _bytesWritten
- _lastBytesWritten
) / ( currentTime
- _lastBytesWrittenTime
);
391 _lastBytesWritten
= _bytesWritten
;
392 _lastBytesWrittenTime
= currentTime
;
397 - (NSString
*)localHost
402 err
= gethostname( host
, sizeof(host
) );
406 return [NSString stringWithCString
:host
];
414 - (NSString
*)remoteHost
417 struct sockaddr_in addr
;
418 int len
= sizeof(addr
);
420 err
= getpeername( _sockfd
, (struct sockaddr
*)(&addr
), &len
);
424 return [NSString stringWithCString
:inet_ntoa(addr.sin_addr
)];
430 struct sockaddr_in addr
;
431 int len
= sizeof(addr
);
433 err
= getpeername( _sockfd
, (struct sockaddr
*)(&addr
), &len
);
437 return addr.sin_port
;
443 return _flags
& kMySocketConnected
;
448 return _flags
& kMySocketIsListener
;
452 + (NSData
*)addressWithHost
:(NSString
*)host port
:(int)port
455 struct sockaddr_in addr
;
458 h
= gethostbyname( [host lossyCString
] );
464 // pack the socket address structure
465 addr.sin_family
= AF_INET
;
466 addr.sin_port
= htons( (short)port
);
467 memcpy( &(addr.sin_addr
), h
->h_addr
, sizeof(struct in_addr
) );
468 memset( &(addr.sin_zero
), NULL
, 8 );
470 return [NSData dataWithBytes
:&addr length
:sizeof(addr
)];
479 - (void)setDelegate
:(id)delegate
481 _delegate
= delegate
;
485 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
486 #pragma mark PrivateAPI
487 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
489 - (id)_initWithFileDescriptor
:(int)sockfd
491 if ( self = [super init
] ) {
500 if ( ![self isListener
] ) {
501 _readQueue
= [[NSMutableArray alloc
] init
];
502 _writeQueue
= [[NSMutableArray alloc
] init
];
506 _readLock
= [[NSRecursiveLock alloc
] init
];
507 _writeLock
= [[NSRecursiveLock alloc
] init
];
509 _startTime
= _lastBytesReadTime
= _lastBytesWrittenTime
= CFAbsoluteTimeGetCurrent();
510 _bytesRead
= _lastBytesRead
= _bytesWritten
= _lastBytesWritten
= 0;
512 _flags |
= kMySocketConnected
;
514 [self _addToManager
];
518 - (void)_addToManager
520 if ( _flags
& kMySocketAddedToManager
) {
521 // only add this socket once
525 // start the manager if it is not already started
526 [MySocket _startManager
];
528 [MySocket _lockReadAndWrite
];
529 // add to global array of sockets
530 [_mySocketGlobals.sockets addObject
:self];
532 [MySocket _readWithSockFD
:_sockfd
];
533 [MySocket _unlockReadAndWrite
];
535 // mark as added to manager
536 _flags |
= kMySocketAddedToManager
;
539 - (void)_removeFromManager
541 if ( !(_flags
& kMySocketAddedToManager
) ) {
542 // only remove if it is added
546 [MySocket _lockReadAndWrite
];
547 // remove from global array
549 ChazLog( @
"REMOVING SOCKET AT INDEX %i", [_mySocketGlobals.sockets indexOfObject
:self] );
550 [_mySocketGlobals.sockets removeObject
:self];
551 FD_CLR( _sockfd
, &_mySocketGlobals.readfds
);
552 FD_CLR( _sockfd
, &_mySocketGlobals.writefds
);
553 [MySocket _unlockReadAndWrite
];
555 _flags ^
= kMySocketAddedToManager
;
559 + (void)_readWithSockFD
:(int)fd
561 [MySocket _lockRead
];
562 FD_SET( fd
, &_mySocketGlobals.readfds
);
563 _mySocketGlobals.maxreadfd
= MAX( _mySocketGlobals.maxreadfd
, fd
);
564 [MySocket _unlockRead
];
565 // make sure the thread picks up the change
566 [MySocket _refreshReadThread
];
569 + (void)_refreshReadThread
572 write( _mySocketGlobals.readPipe
[1], &b
, sizeof(b
) );
575 + (void)_writeWithSockFD
:(int)fd
577 [MySocket _lockWrite
];
578 FD_SET( fd
, &_mySocketGlobals.writefds
);
579 _mySocketGlobals.maxwritefd
= MAX( _mySocketGlobals.maxwritefd
, fd
);
580 [MySocket _unlockWrite
];
581 [MySocket _refreshWriteThread
];
584 + (void)_refreshWriteThread
587 write( _mySocketGlobals.writePipe
[1], &b
, sizeof(b
) );
593 [_mySocketGlobals.readLock lock
];
598 [_mySocketGlobals.readLock unlock
];
603 [_mySocketGlobals.writeLock lock
];
608 [_mySocketGlobals.writeLock unlock
];
611 + (void)_lockReadAndWrite
613 [MySocket _lockRead
];
614 [MySocket _lockWrite
];
617 + (void)_unlockReadAndWrite
619 [MySocket _unlockRead
];
620 [MySocket _unlockWrite
];
624 + (void)_startManager
628 if ( _mySocketGlobals.isManagerRunning
) {
632 ChazLog( @
"MySocketHelper STARTING" );
634 // zero the descriptor sets
635 FD_ZERO( &_mySocketGlobals.readfds
);
636 FD_ZERO( &_mySocketGlobals.writefds
);
638 // create the read pipe
639 err
= pipe( _mySocketGlobals.readPipe
);
643 FD_SET( _mySocketGlobals.readPipe
[0], &_mySocketGlobals.readfds
);
644 _mySocketGlobals.maxreadfd
= _mySocketGlobals.readPipe
[0];
645 // create the write pipe
646 err
= pipe( _mySocketGlobals.writePipe
);
648 close( _mySocketGlobals.readPipe
[0] );
649 close( _mySocketGlobals.readPipe
[1] );
652 _mySocketGlobals.maxwritefd
= _mySocketGlobals.writePipe
[0];
654 // create other global objects
655 _mySocketGlobals.sockets
= [[NSMutableArray alloc
] init
];
656 _mySocketGlobals.readLock
= [[NSRecursiveLock alloc
] init
];
657 _mySocketGlobals.writeLock
= [[NSRecursiveLock alloc
] init
];
660 [NSThread detachNewThreadSelector
:@selector(_readThread
:) toTarget
:[MySocket
class] withObject
:nil];
661 [NSThread detachNewThreadSelector
:@selector(_writeThread
:) toTarget
:[MySocket
class] withObject
:nil];
662 _mySocketGlobals.isManagerRunning
= YES
;
665 + (void)_readThread
:(id)object
674 // create the ever-so-important pool
675 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
677 [MySocket _lockRead
];
678 //FD_COPY( &_mySocketGlobals.readfds, &readfds );
679 readfds
= _mySocketGlobals.readfds
;
680 [MySocket _unlockRead
];
682 // find the sockets which need processing
683 err
= select( _mySocketGlobals.maxreadfd
+1, &readfds
, NULL
, NULL
, NULL
);
685 // trouble, select() is having problems
686 ChazLog( @
"select() failed!, error: %s", strerror(errno
) );
691 if ( FD_ISSET( _mySocketGlobals.readPipe
[0], &readfds
) ) {
693 err
= read( _mySocketGlobals.readPipe
[0], &b
, sizeof(b
) );
695 // our connection to the main thread was severed...
697 ChazLog( @
"readPipe severed, exiting READ thread..." );
703 // process the sockets
704 [MySocket _lockRead
];
705 top
= [_mySocketGlobals.sockets count
];
706 for ( i
= 0; i
< top
; i
++ ) {
707 MySocket
*sock
= [_mySocketGlobals.sockets objectAtIndex
:i
];
708 int sockfd
= [sock _sockfd
];
710 [sock _fillReadPacketsWithUnclaimedBytes
];
711 [sock _handleReadQueue
];
713 if ( FD_ISSET( sockfd
, &readfds
) ) {
714 if ( [sock isListener
] ) {
715 // socket ready for accepting
716 err
= [sock _accept
];
719 // socket ready for reading
723 // action returne error, disconnect socket
725 [sock performSelectorOnMainThread
:@selector(_eventDidDisconnect
:)
726 withObject
:nil waitUntilDone
:NO
];
731 [MySocket _unlockRead
];
736 while ( !breakLoop
);
739 + (void)_writeThread
:(id)object
743 fd_set readfds
, writefds
;
746 FD_SET( _mySocketGlobals.writePipe
[0], &pipefds
);
752 // create the ever-so-important pool
753 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
756 [MySocket _lockWrite
];
757 //FD_COPY( &_mySocketGlobals.writefds, &writefds );
758 writefds
= _mySocketGlobals.writefds
;
759 [MySocket _unlockWrite
];
761 // find the sockets which need processing
762 err
= select( _mySocketGlobals.maxwritefd
+1, &readfds
, &writefds
, NULL
, NULL
);
764 // trouble, select() is having problems
765 ChazLog( @
"select() failed!, error: %s", strerror(errno
) );
770 if ( FD_ISSET( _mySocketGlobals.writePipe
[0], &readfds
) ) {
772 err
= read( _mySocketGlobals.writePipe
[0], &b
, sizeof(b
) );
774 // our connection to the main thread was severed...
776 ChazLog( @
"writePipe severed" );
782 // process the sockets
783 [MySocket _lockWrite
];
784 top
= [_mySocketGlobals.sockets count
];
785 for ( i
= 0; i
< top
; i
++ ) {
786 MySocket
*sock
= [_mySocketGlobals.sockets objectAtIndex
:i
];
787 int sockfd
= [sock _sockfd
];
789 if ( FD_ISSET( sockfd
, &writefds
) ) {
790 // socket ready for accepting
793 // action returne error, disconnect socket
795 [sock performSelectorOnMainThread
:@selector(_eventDidDisconnect
:)
796 withObject
:nil waitUntilDone
:NO
];
801 [MySocket _unlockWrite
];
806 while ( !breakLoop
);
814 struct sockaddr addr
;
815 int addrlen
= sizeof(addr
);
817 newsockfd
= accept( _sockfd
, &addr
, &addrlen
);
818 if ( newsockfd
>= 0 ) {
819 // create a new MySocket
820 newSocket
= [[MySocket alloc
] _initWithFileDescriptor
:newsockfd
];
821 [newSocket setDelegate
:_delegate
];
823 [self performSelectorOnMainThread
:@selector(_eventDidAcceptSocket
:)
824 withObject
:newSocket waitUntilDone
:NO
];
834 _MySocketPacket
*packet
= nil;
838 if ( [_readQueue count
] == 0 ) {
839 // no packets claiming anything, so just
840 // read into the unclaimed bytes buffer.
841 if ( !_unclaimedData
) {
842 _unclaimedData
= [[NSMutableData alloc
] init
];
844 int len
= [_unclaimedData length
];
845 [_unclaimedData increaseLengthBy
:MYSOCKET_PACKETLEN
];
846 bytesRead
= recv( _sockfd
, [_unclaimedData mutableBytes
] + len
, MYSOCKET_PACKETLEN
, 0 );
847 [_unclaimedData setLength
:len
+bytesRead
];
850 packet
= [_readQueue objectAtIndex
:0];
851 bytesRead
= recv( _sockfd
, [packet bytes
], [packet bytesRemaining
], 0 );
852 [packet handledBytes
:bytesRead
];
856 if ( bytesRead
> 0 ) {
857 // update total bytes read
858 _bytesRead
+= bytesRead
;
860 [self _handleReadQueue
];
863 // remove this socket
864 ChazLog( @
"MySocket disconnecting: %i", bytesRead
);
872 _MySocketPacket
*packet
= nil;
873 int bytesWritten
= 0;
876 if ( [_writeQueue count
] > 0 ) {
878 int len
= sizeof(buflen
);
880 err
= getsockopt( _sockfd
, SOL_SOCKET
, SO_SNDBUF
, &buflen
, &len
);
882 packet
= [_writeQueue objectAtIndex
:0];
883 bytesWritten
= send( _sockfd
, [packet bytes
], MIN([packet bytesRemaining
],buflen
/2), 0 ); //MIN(4096,[packet bytesRemaining]), 0 );
884 [packet handledBytes
:bytesWritten
];
888 if ( bytesWritten
>= 0 ) {
889 // update total bytes read
890 _bytesWritten
+= bytesWritten
;
892 [self _handleWriteQueue
];
901 - (void)_fillReadPacketsWithUnclaimedBytes
907 total
= [_unclaimedData length
];
911 bytes
= [_unclaimedData mutableBytes
];
914 top
= [_readQueue count
];
915 for ( i
= 0; i
< top
; i
++ ) {
916 _MySocketPacket
*packet
= [_readQueue objectAtIndex
:i
];
917 int len
= MIN( total
, [packet bytesRemaining
] );
920 memcpy( [packet bytes
], bytes
, len
);
921 [packet handledBytes
:len
];
929 [_unclaimedData replaceBytesInRange
:NSMakeRange(0,[_unclaimedData length
]-total
) withBytes
:NULL length
:0];
934 - (void)_handleReadQueue
939 top
= [_readQueue count
];
940 for ( i
= 0; i
< top
; ) {
941 _MySocketPacket
*packet
= [_readQueue objectAtIndex
:0];
942 if ( [packet isComplete
] ) {
943 [self performSelectorOnMainThread
:@selector(_eventDidReadData
:)
944 withObject
:[packet retain
] waitUntilDone
:NO
];
945 [_readQueue removeObjectAtIndex
:i
];
955 - (void)_handleWriteQueue
960 top
= [_writeQueue count
];
961 for ( i
= 0; i
< top
; ) {
962 _MySocketPacket
*packet
= [_writeQueue objectAtIndex
:0];
963 if ( [packet isComplete
] ) {
964 [self performSelectorOnMainThread
:@selector(_eventDidWriteData
:)
965 withObject
:[packet retain
] waitUntilDone
:NO
];
966 [_writeQueue removeObjectAtIndex
:i
];
973 if ( [_writeQueue count
] == 0 ) {
974 // no more pending writes
975 FD_CLR( _sockfd
, &_mySocketGlobals.writefds
);
981 - (void)_eventDidAcceptSocket
:(MySocket
*)newSocket
983 // just report the event back to the delegate
984 if ( [_delegate respondsToSelector
:@selector(socket
:didAcceptSocket
:)] ) {
985 [_delegate socket
:self didAcceptSocket
:newSocket
];
988 // release the parameter(s)
989 // they were not released by the caller because the caller is in another thread.
993 - (void)_eventDidDisconnect
:(id)dummy
996 if ( [_delegate respondsToSelector
:@selector(socketDidDisconnect
:)] ) {
997 [_delegate socketDidDisconnect
:self];
1001 - (void)_eventDidReadData
:(_MySocketPacket
*)packet
1003 if ( [_delegate respondsToSelector
:@selector(socket
:didReadData
:tag
:)] ) {
1004 [_delegate socket
:self didReadData
:[packet data
] tag
:[packet tag
]];
1010 - (void)_eventDidWriteData
:(_MySocketPacket
*)packet
1012 if ( [_delegate respondsToSelector
:@selector(socket
:didWriteDataWithTag
:)] ) {
1013 [_delegate socket
:self didWriteDataWithTag
:[packet tag
]];
1020 - (NSMutableData
*)_readBufferWithLength
:(unsigned *)len
1022 NSMutableData
*buffer
;
1023 unsigned packetLen
= *len
;
1025 if ( buffer
= _unclaimedData
) {
1027 int unclaimedLen
= [_unclaimedData length
];
1028 if ( unclaimedLen
> packetLen
) {
1030 _unclaimedData
= [[NSMutableData alloc
] initWithBytes
:[buffer bytes
]+packetLen length
:unclaimedLen
-packetLen
];
1031 //[[buffer subdataWithRange:NSMakeRange(packetLen,unclaimedLen-packetLen)] retain];
1034 *len
= unclaimedLen
;
1035 _unclaimedData
= nil;
1037 [buffer setLength
:packetLen
];
1040 buffer
= [[NSMutableData alloc
] initWithLength
:packetLen
];
1043 return [buffer autorelease
];
1056 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1057 #pragma mark _MySocketPacket
1058 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1060 @implementation _MySocketPacket
1063 - (id)initWithData
:(NSData
*)data tag
:(int)tag
1065 if ( self = [super init
] ) {
1066 _buffer
= [data retain
];
1067 _bytesRequired
= [data length
];
1082 return (void *)[_buffer bytes
] + _bytesHandled
;
1085 - (unsigned)bytesRemaining
1087 return _bytesRequired
- _bytesHandled
;
1091 - (void)handledBytes
:(unsigned)count
1093 _bytesHandled
+= count
;
1096 - (unsigned)bytesRequired
1098 return _bytesRequired
;
1114 return [self bytesRemaining
] == 0;