3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.dogcows.com/chaz/wiki/TheCheat
6 * Copyright (c) 2003-2010, 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 memset( &(addr.sin_zero
), NULL
, 8 );
227 err
= bind( _sockfd
, (struct sockaddr
*)(&addr
), sizeof(addr
) );
229 // can't bind to this address
234 err
= listen( _sockfd
, 10 );
236 // can't listen on this address
241 _flags |
= kMySocketIsListener
;
249 if ( !(_flags
& kMySocketConnected
) ) {
254 [self _removeFromManager
];
259 [_readQueue release
];
261 [_writeQueue release
];
265 [_writeLock release
];
274 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
275 #pragma mark Reading/Writing
276 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
278 - (void)readDataToLength
:(unsigned)len tag
:(int)tag
280 _MySocketPacket
*packet
;
282 if ( ![self isConnected
] ||
[self isListener
] || len
== 0 ) {
283 // must be connected and have a valid length
287 // create a "read" packet
288 packet
= [[_MySocketPacket alloc
] initWithData
:[NSMutableData dataWithLength
:len
] tag
:tag
];
289 //[packet handledBytes:0];
291 // add the packet to the queue
293 [_readQueue addObject
:packet
];
297 // make sure the thread picks up the change
298 [MySocket _refreshReadThread
];
302 - (void)writeData
:(NSData
*)data tag
:(int)tag
304 _MySocketPacket
*packet
;
307 if ( ![self isConnected
] ||
[self isListener
] ) {
312 // create a "write" packet
313 packet
= [[_MySocketPacket alloc
] initWithData
:data tag
:tag
];
316 alreadyWriting
= [_writeQueue count
] > 0;
317 [_writeQueue addObject
:packet
];
321 if ( !alreadyWriting
) {
322 // make the helper aware the socket has data to write
323 [MySocket _writeWithSockFD
:_sockfd
];
327 - (void)writeBytes
:(void const *)bytes length
:(unsigned)len tag
:(int)tag
329 [self writeData
:[NSData dataWithBytes
:bytes length
:len
] tag
:tag
];
333 // AsyncSocket compatibility
334 - (void)readDataToLength
:(CFIndex
)length withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
336 [self readDataToLength
:length tag
:tag
];
339 - (void)writeData
:(NSData
*)data withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
341 [self writeData
:data tag
:tag
];
344 - (void)writeBytes
:(void *)bytes length
:(unsigned)len withTimeout
:(NSTimeInterval
)timeout tag
:(long)tag
346 [self writeBytes
:bytes length
:len tag
:tag
];
350 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
351 #pragma mark Accesors
352 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
354 - (unsigned)bytesRead
359 - (unsigned)bytesWritten
361 return _bytesWritten
;
364 - (NSTimeInterval
)timeConnected
366 return CFAbsoluteTimeGetCurrent() - _startTime
;
371 double currentTime
= CFAbsoluteTimeGetCurrent();
372 double speed
= (double)( _bytesRead
- _lastBytesRead
) / ( currentTime
- _lastBytesReadTime
);
373 _lastBytesRead
= _bytesRead
;
374 _lastBytesReadTime
= currentTime
;
380 double currentTime
= CFAbsoluteTimeGetCurrent();
381 double speed
= (double)( _bytesWritten
- _lastBytesWritten
) / ( currentTime
- _lastBytesWrittenTime
);
382 _lastBytesWritten
= _bytesWritten
;
383 _lastBytesWrittenTime
= currentTime
;
388 - (NSString
*)localHost
393 err
= gethostname( host
, sizeof(host
) );
397 return [NSString stringWithCString
:host
];
405 - (NSString
*)remoteHost
408 struct sockaddr_in addr
;
409 int len
= sizeof(addr
);
411 err
= getpeername( _sockfd
, (struct sockaddr
*)(&addr
), &len
);
415 return [NSString stringWithCString
:inet_ntoa(addr.sin_addr
)];
421 struct sockaddr_in addr
;
422 int len
= sizeof(addr
);
424 err
= getpeername( _sockfd
, (struct sockaddr
*)(&addr
), &len
);
428 return addr.sin_port
;
434 return _flags
& kMySocketConnected
;
439 return _flags
& kMySocketIsListener
;
443 + (NSData
*)addressWithHost
:(NSString
*)host port
:(int)port
446 struct sockaddr_in addr
;
449 h
= gethostbyname( [host lossyCString
] );
455 // pack the socket address structure
456 addr.sin_family
= AF_INET
;
457 addr.sin_port
= htons( (short)port
);
458 memcpy( &(addr.sin_addr
), h
->h_addr
, sizeof(struct in_addr
) );
459 memset( &(addr.sin_zero
), NULL
, 8 );
461 return [NSData dataWithBytes
:&addr length
:sizeof(addr
)];
470 - (void)setDelegate
:(id)delegate
472 _delegate
= delegate
;
476 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
477 #pragma mark PrivateAPI
478 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
480 - (id)_initWithFileDescriptor
:(int)sockfd
482 if ( self = [super init
] ) {
491 if ( ![self isListener
] ) {
492 _readQueue
= [[NSMutableArray alloc
] init
];
493 _writeQueue
= [[NSMutableArray alloc
] init
];
497 _readLock
= [[NSRecursiveLock alloc
] init
];
498 _writeLock
= [[NSRecursiveLock alloc
] init
];
500 _startTime
= _lastBytesReadTime
= _lastBytesWrittenTime
= CFAbsoluteTimeGetCurrent();
501 _bytesRead
= _lastBytesRead
= _bytesWritten
= _lastBytesWritten
= 0;
503 _flags |
= kMySocketConnected
;
505 [self _addToManager
];
509 - (void)_addToManager
511 if ( _flags
& kMySocketAddedToManager
) {
512 // only add this socket once
516 // start the manager if it is not already started
517 [MySocket _startManager
];
519 [MySocket _lockReadAndWrite
];
520 // add to global array of sockets
521 [_mySocketGlobals.sockets addObject
:self];
523 [MySocket _readWithSockFD
:_sockfd
];
524 [MySocket _unlockReadAndWrite
];
526 // mark as added to manager
527 _flags |
= kMySocketAddedToManager
;
530 - (void)_removeFromManager
532 if ( !(_flags
& kMySocketAddedToManager
) ) {
533 // only remove if it is added
537 [MySocket _lockReadAndWrite
];
538 // remove from global array
540 ChazLog( @
"REMOVING SOCKET AT INDEX %i", [_mySocketGlobals.sockets indexOfObject
:self] );
541 [_mySocketGlobals.sockets removeObject
:self];
542 FD_CLR( _sockfd
, &_mySocketGlobals.readfds
);
543 FD_CLR( _sockfd
, &_mySocketGlobals.writefds
);
544 [MySocket _unlockReadAndWrite
];
546 _flags ^
= kMySocketAddedToManager
;
550 + (void)_readWithSockFD
:(int)fd
552 [MySocket _lockRead
];
553 FD_SET( fd
, &_mySocketGlobals.readfds
);
554 _mySocketGlobals.maxreadfd
= MAX( _mySocketGlobals.maxreadfd
, fd
);
555 [MySocket _unlockRead
];
556 // make sure the thread picks up the change
557 [MySocket _refreshReadThread
];
560 + (void)_refreshReadThread
563 write( _mySocketGlobals.readPipe
[1], &b
, sizeof(b
) );
566 + (void)_writeWithSockFD
:(int)fd
568 [MySocket _lockWrite
];
569 FD_SET( fd
, &_mySocketGlobals.writefds
);
570 _mySocketGlobals.maxwritefd
= MAX( _mySocketGlobals.maxwritefd
, fd
);
571 [MySocket _unlockWrite
];
572 [MySocket _refreshWriteThread
];
575 + (void)_refreshWriteThread
578 write( _mySocketGlobals.writePipe
[1], &b
, sizeof(b
) );
584 [_mySocketGlobals.readLock lock
];
589 [_mySocketGlobals.readLock unlock
];
594 [_mySocketGlobals.writeLock lock
];
599 [_mySocketGlobals.writeLock unlock
];
602 + (void)_lockReadAndWrite
604 [MySocket _lockRead
];
605 [MySocket _lockWrite
];
608 + (void)_unlockReadAndWrite
610 [MySocket _unlockRead
];
611 [MySocket _unlockWrite
];
615 + (void)_startManager
619 if ( _mySocketGlobals.isManagerRunning
) {
623 ChazLog( @
"MySocketHelper STARTING" );
625 // zero the descriptor sets
626 FD_ZERO( &_mySocketGlobals.readfds
);
627 FD_ZERO( &_mySocketGlobals.writefds
);
629 // create the read pipe
630 err
= pipe( _mySocketGlobals.readPipe
);
634 FD_SET( _mySocketGlobals.readPipe
[0], &_mySocketGlobals.readfds
);
635 _mySocketGlobals.maxreadfd
= _mySocketGlobals.readPipe
[0];
636 // create the write pipe
637 err
= pipe( _mySocketGlobals.writePipe
);
639 close( _mySocketGlobals.readPipe
[0] );
640 close( _mySocketGlobals.readPipe
[1] );
643 _mySocketGlobals.maxwritefd
= _mySocketGlobals.writePipe
[0];
645 // create other global objects
646 _mySocketGlobals.sockets
= [[NSMutableArray alloc
] init
];
647 _mySocketGlobals.readLock
= [[NSRecursiveLock alloc
] init
];
648 _mySocketGlobals.writeLock
= [[NSRecursiveLock alloc
] init
];
651 [NSThread detachNewThreadSelector
:@selector(_readThread
:) toTarget
:[MySocket
class] withObject
:nil];
652 [NSThread detachNewThreadSelector
:@selector(_writeThread
:) toTarget
:[MySocket
class] withObject
:nil];
653 _mySocketGlobals.isManagerRunning
= YES
;
656 + (void)_readThread
:(id)object
665 // create the ever-so-important pool
666 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
668 [MySocket _lockRead
];
669 //FD_COPY( &_mySocketGlobals.readfds, &readfds );
670 readfds
= _mySocketGlobals.readfds
;
671 [MySocket _unlockRead
];
673 // find the sockets which need processing
674 err
= select( _mySocketGlobals.maxreadfd
+1, &readfds
, NULL
, NULL
, NULL
);
676 // trouble, select() is having problems
677 ChazLog( @
"select() failed!, error: %s", strerror(errno
) );
682 if ( FD_ISSET( _mySocketGlobals.readPipe
[0], &readfds
) ) {
684 err
= read( _mySocketGlobals.readPipe
[0], &b
, sizeof(b
) );
686 // our connection to the main thread was severed...
688 ChazLog( @
"readPipe severed, exiting READ thread..." );
694 // process the sockets
695 [MySocket _lockRead
];
696 top
= [_mySocketGlobals.sockets count
];
697 for ( i
= 0; i
< top
; i
++ ) {
698 MySocket
*sock
= [_mySocketGlobals.sockets objectAtIndex
:i
];
699 int sockfd
= [sock _sockfd
];
701 [sock _fillReadPacketsWithUnclaimedBytes
];
702 [sock _handleReadQueue
];
704 if ( FD_ISSET( sockfd
, &readfds
) ) {
705 if ( [sock isListener
] ) {
706 // socket ready for accepting
707 err
= [sock _accept
];
710 // socket ready for reading
714 // action returne error, disconnect socket
716 [sock performSelectorOnMainThread
:@selector(_eventDidDisconnect
:)
717 withObject
:nil waitUntilDone
:NO
];
722 [MySocket _unlockRead
];
727 while ( !breakLoop
);
730 + (void)_writeThread
:(id)object
734 fd_set readfds
, writefds
;
737 FD_SET( _mySocketGlobals.writePipe
[0], &pipefds
);
743 // create the ever-so-important pool
744 NSAutoreleasePool
*pool
= [[NSAutoreleasePool alloc
] init
];
747 [MySocket _lockWrite
];
748 //FD_COPY( &_mySocketGlobals.writefds, &writefds );
749 writefds
= _mySocketGlobals.writefds
;
750 [MySocket _unlockWrite
];
752 // find the sockets which need processing
753 err
= select( _mySocketGlobals.maxwritefd
+1, &readfds
, &writefds
, NULL
, NULL
);
755 // trouble, select() is having problems
756 ChazLog( @
"select() failed!, error: %s", strerror(errno
) );
761 if ( FD_ISSET( _mySocketGlobals.writePipe
[0], &readfds
) ) {
763 err
= read( _mySocketGlobals.writePipe
[0], &b
, sizeof(b
) );
765 // our connection to the main thread was severed...
767 ChazLog( @
"writePipe severed" );
773 // process the sockets
774 [MySocket _lockWrite
];
775 top
= [_mySocketGlobals.sockets count
];
776 for ( i
= 0; i
< top
; i
++ ) {
777 MySocket
*sock
= [_mySocketGlobals.sockets objectAtIndex
:i
];
778 int sockfd
= [sock _sockfd
];
780 if ( FD_ISSET( sockfd
, &writefds
) ) {
781 // socket ready for accepting
784 // action returne error, disconnect socket
786 [sock performSelectorOnMainThread
:@selector(_eventDidDisconnect
:)
787 withObject
:nil waitUntilDone
:NO
];
792 [MySocket _unlockWrite
];
797 while ( !breakLoop
);
805 struct sockaddr addr
;
806 int addrlen
= sizeof(addr
);
808 newsockfd
= accept( _sockfd
, &addr
, &addrlen
);
809 if ( newsockfd
>= 0 ) {
810 // create a new MySocket
811 newSocket
= [[MySocket alloc
] _initWithFileDescriptor
:newsockfd
];
812 [newSocket setDelegate
:_delegate
];
814 [self performSelectorOnMainThread
:@selector(_eventDidAcceptSocket
:)
815 withObject
:newSocket waitUntilDone
:NO
];
825 _MySocketPacket
*packet
= nil;
829 if ( [_readQueue count
] == 0 ) {
830 // no packets claiming anything, so just
831 // read into the unclaimed bytes buffer.
832 if ( !_unclaimedData
) {
833 _unclaimedData
= [[NSMutableData alloc
] init
];
835 int len
= [_unclaimedData length
];
836 [_unclaimedData increaseLengthBy
:MYSOCKET_PACKETLEN
];
837 bytesRead
= recv( _sockfd
, [_unclaimedData mutableBytes
] + len
, MYSOCKET_PACKETLEN
, 0 );
838 [_unclaimedData setLength
:len
+bytesRead
];
841 packet
= [_readQueue objectAtIndex
:0];
842 bytesRead
= recv( _sockfd
, [packet bytes
], [packet bytesRemaining
], 0 );
843 [packet handledBytes
:bytesRead
];
847 if ( bytesRead
> 0 ) {
848 // update total bytes read
849 _bytesRead
+= bytesRead
;
851 [self _handleReadQueue
];
854 // remove this socket
855 ChazLog( @
"MySocket disconnecting: %i", bytesRead
);
863 _MySocketPacket
*packet
= nil;
864 int bytesWritten
= 0;
867 if ( [_writeQueue count
] > 0 ) {
869 int len
= sizeof(buflen
);
871 err
= getsockopt( _sockfd
, SOL_SOCKET
, SO_SNDBUF
, &buflen
, &len
);
873 packet
= [_writeQueue objectAtIndex
:0];
874 bytesWritten
= send( _sockfd
, [packet bytes
], MIN([packet bytesRemaining
],buflen
/2), 0 ); //MIN(4096,[packet bytesRemaining]), 0 );
875 [packet handledBytes
:bytesWritten
];
879 if ( bytesWritten
>= 0 ) {
880 // update total bytes read
881 _bytesWritten
+= bytesWritten
;
883 [self _handleWriteQueue
];
892 - (void)_fillReadPacketsWithUnclaimedBytes
898 total
= [_unclaimedData length
];
902 bytes
= [_unclaimedData mutableBytes
];
905 top
= [_readQueue count
];
906 for ( i
= 0; i
< top
; i
++ ) {
907 _MySocketPacket
*packet
= [_readQueue objectAtIndex
:i
];
908 int len
= MIN( total
, [packet bytesRemaining
] );
911 memcpy( [packet bytes
], bytes
, len
);
912 [packet handledBytes
:len
];
920 [_unclaimedData replaceBytesInRange
:NSMakeRange(0,[_unclaimedData length
]-total
) withBytes
:NULL length
:0];
925 - (void)_handleReadQueue
930 top
= [_readQueue count
];
931 for ( i
= 0; i
< top
; ) {
932 _MySocketPacket
*packet
= [_readQueue objectAtIndex
:0];
933 if ( [packet isComplete
] ) {
934 [self performSelectorOnMainThread
:@selector(_eventDidReadData
:)
935 withObject
:[packet retain
] waitUntilDone
:NO
];
936 [_readQueue removeObjectAtIndex
:i
];
946 - (void)_handleWriteQueue
951 top
= [_writeQueue count
];
952 for ( i
= 0; i
< top
; ) {
953 _MySocketPacket
*packet
= [_writeQueue objectAtIndex
:0];
954 if ( [packet isComplete
] ) {
955 [self performSelectorOnMainThread
:@selector(_eventDidWriteData
:)
956 withObject
:[packet retain
] waitUntilDone
:NO
];
957 [_writeQueue removeObjectAtIndex
:i
];
964 if ( [_writeQueue count
] == 0 ) {
965 // no more pending writes
966 FD_CLR( _sockfd
, &_mySocketGlobals.writefds
);
972 - (void)_eventDidAcceptSocket
:(MySocket
*)newSocket
974 // just report the event back to the delegate
975 if ( [_delegate respondsToSelector
:@selector(socket
:didAcceptSocket
:)] ) {
976 [_delegate socket
:self didAcceptSocket
:newSocket
];
979 // release the parameter(s)
980 // they were not released by the caller because the caller is in another thread.
984 - (void)_eventDidDisconnect
:(id)dummy
987 if ( [_delegate respondsToSelector
:@selector(socketDidDisconnect
:)] ) {
988 [_delegate socketDidDisconnect
:self];
992 - (void)_eventDidReadData
:(_MySocketPacket
*)packet
994 if ( [_delegate respondsToSelector
:@selector(socket
:didReadData
:tag
:)] ) {
995 [_delegate socket
:self didReadData
:[packet data
] tag
:[packet tag
]];
1001 - (void)_eventDidWriteData
:(_MySocketPacket
*)packet
1003 if ( [_delegate respondsToSelector
:@selector(socket
:didWriteDataWithTag
:)] ) {
1004 [_delegate socket
:self didWriteDataWithTag
:[packet tag
]];
1011 - (NSMutableData
*)_readBufferWithLength
:(unsigned *)len
1013 NSMutableData
*buffer
;
1014 unsigned packetLen
= *len
;
1016 if ( buffer
= _unclaimedData
) {
1018 int unclaimedLen
= [_unclaimedData length
];
1019 if ( unclaimedLen
> packetLen
) {
1021 _unclaimedData
= [[NSMutableData alloc
] initWithBytes
:[buffer bytes
]+packetLen length
:unclaimedLen
-packetLen
];
1022 //[[buffer subdataWithRange:NSMakeRange(packetLen,unclaimedLen-packetLen)] retain];
1025 *len
= unclaimedLen
;
1026 _unclaimedData
= nil;
1028 [buffer setLength
:packetLen
];
1031 buffer
= [[NSMutableData alloc
] initWithLength
:packetLen
];
1034 return [buffer autorelease
];
1047 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1048 #pragma mark _MySocketPacket
1049 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1051 @implementation _MySocketPacket
1054 - (id)initWithData
:(NSData
*)data tag
:(int)tag
1056 if ( self = [super init
] ) {
1057 _buffer
= [data retain
];
1058 _bytesRequired
= [data length
];
1073 return (void *)[_buffer bytes
] + _bytesHandled
;
1076 - (unsigned)bytesRemaining
1078 return _bytesRequired
- _bytesHandled
;
1082 - (void)handledBytes
:(unsigned)count
1084 _bytesHandled
+= count
;
1087 - (unsigned)bytesRequired
1089 return _bytesRequired
;
1105 return [self bytesRemaining
] == 0;