Re: Memory not being freed
Re: Memory not being freed
- Subject: Re: Memory not being freed
- From: Mark Williams <email@hidden>
- Date: Tue, 8 Nov 2005 08:55:56 -0700
Ok, last message was too large, let me try this again.
Here is the code for my stream. I think this is the problem but I'm
not sure. It is based on the example stream test.
@interface AGDStreamObj : NSObject
{
NSDictionary *agent;
id streamDelegate;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
UInt8 *recvBuffer;
NSMutableData *writeBuffer;
NSMutableString *readBuffer;
NSTimer * timer;
float workUnitsExpected;
float workUnitsCompleted;
Byte theFlags;
BOOL toFlag;
int timeout;
}
- (id) initWithHostInfo: (NSDictionary *)anAgent delegate:(id)sender;
-(void)setTimeOut:(int)to; //Default is 60 seconds
- (BOOL) open;
- (void) close;
- (void) writeLine: (NSString *)aLine;
- (void) writeLineWithFormat: (NSString *)aFormat, ...;
@end
@interface NSObject (StreamDelegateMethods)
-(void)newBytesAvailable:(NSData*)newData;
-(void)streamDisconnected;
-(void)streamErrorOccured:(CFStreamError)error errorText:(NSString*)
errTxt;
-(void)streamDisconnectWithError:(CFStreamError)error;
-(void)dataWritten:(NSString*)string;
-(void)streamConnected:(NSString*)connect;
-(void)streamTimedOut;
@end
/* Agent Dictionary Keys */
AGD_KEY NSString * const AGDServerAddress;
AGD_KEY NSString * const AGDServerPort;
#import "AGDStreamObj.h"
NSString * const AGDServerAddress = @"AGDServerAddress";
NSString * const AGDServerPort = @"AGDServerPort";
@interface AGDStreamObj (Private)
- (void) streamHasBytesAvailable;
- (void) streamCanAcceptBytes;
- (void) streamOpenCompleted;
- (void) streamErrorOccurred;
-(void)closeWithError:(CFStreamError)err;
@end
@implementation AGDStreamObj
/*****
* Object lifecycle
*****/
- (id) initWithHostInfo: (NSDictionary *)anAgent delegate:(id)sender
{
if ((self = [super init]))
{
theFlags = 0x00;
recvBuffer = malloc(8192);
toFlag = NO;
timeout = 60.0;
streamDelegate = sender;
agent = [[NSDictionary alloc]
initWithDictionary:anAgent];
if(![sender respondsToSelector:@selector(newBytesAvailable:)]){
NSLog(@"Illegal Stream delegate. StreamObj Delegates must
implement:\nnewBytesAvailable:\nstreamDisconnected
\nstreamErrorOccured:\nstreamDisconnectWithError:\nstreamConnected:\n");
}
if(![sender respondsToSelector:@selector
(streamErrorOccured:errorText:)]
|| ![sender respondsToSelector:@selector
(streamConnected:)]){
//Not a legal delegate
NSLog(@"Illegal Stream delegate. StreamObj
Delegates must implement:\nnewBytesAvailable:\nstreamDisconnected
\nstreamErrorOccured:\nstreamDisconnectWithError:\nstreamConnected:\n");
}
if(![sender respondsToSelector:@selector
(streamDisconnectWithError:)] && ![sender respondsToSelector:@selector
(streamDisconnected)]){ //Not a legal delegate
NSLog(@"Illegal Stream delegate. StreamObj
Delegates must implement:\nnewBytesAvailable:\nstreamDisconnected
\nstreamErrorOccured:\nstreamDisconnectWithError:\nstreamConnected:\n");
}
}
return self;
}
-(void)setTimeOut:(int)to
{
timeout = to;
}
- (void) dealloc
{
[self close];
free(recvBuffer);
free(writeStream);
free(readStream);
[writeBuffer release];
[readBuffer release];
[super dealloc];
}
void readStreamCallBack(CFReadStreamRef stream, CFStreamEventType
type, void *transportStream)
{
id self = (id)transportStream;
switch (type)
{
case kCFStreamEventHasBytesAvailable:
{
[self streamHasBytesAvailable];
break;
}
case kCFStreamEventOpenCompleted:
{
[self streamOpenCompleted];
break;
}
default:
case kCFStreamEventErrorOccurred:
{
[self streamErrorOccurred];
break;
}
}
}
void writeStreamCallBack(CFWriteStreamRef stream, CFStreamEventType
type, void *transportStream)
{
id self = (id)transportStream;
switch (type)
{
case kCFStreamEventCanAcceptBytes:
{
[self streamCanAcceptBytes];
break;
}
default:
case kCFStreamEventErrorOccurred:
{
[self streamErrorOccurred];
break;
}
}
}
-(void)requestTimeOut:(id)sender
{
if(toFlag){
if([streamDelegate respondsToSelector:@selector
(stramTimedOut)]) [streamDelegate performSelector:@selector
(streamTimedOut)];
[self close];
}
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
toFlag = NO;
}
- (BOOL) open
/*
Opens the connection.
*/
{
CFStreamStatus readStreamStatus;
CFStreamStatus writeStreamStatus;
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
NSDate * theDate = [[NSDate alloc]
initWithTimeIntervalSinceNow:timeout];
timer = [[NSTimer alloc]initWithFireDate:theDate
interval:timeout
target:self selector:@selector
(requestTimeOut:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop]addTimer:timer
forMode:NSDefaultRunLoopMode];
toFlag = YES;
if (!readStream)
{
// create our streams
CFStreamClientContext clientContext =
{
NULL,
(void *)self,
(void *(*)(void *))CFRetain,
(void(*)(void *))CFRelease,
(CFStringRef(*)(void*))CFCopyDescription
};
CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)[agent
objectForKey:AGDServerAddress],[[agent objectForKey:AGDServerPort]
intValue], &readStream, &writeStream);
CFReadStreamSetClient(readStream,
kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred |
kCFStreamEventOpenCompleted | kCFStreamEventEndEncountered,
&readStreamCallBack,
&clientContext);
CFWriteStreamSetClient(writeStream,
kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred,
&writeStreamCallBack,
&clientContext);
CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(),
kCFRunLoopCommonModes);
CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent
(), kCFRunLoopCommonModes);
}
readStreamStatus = CFReadStreamGetStatus(readStream);
writeStreamStatus = CFWriteStreamGetStatus(writeStream);
if ((kCFStreamStatusNotOpen == readStreamStatus) ||
(kCFStreamStatusNotOpen == writeStreamStatus))
{
CFReadStreamOpen(readStream);
CFWriteStreamOpen(writeStream);
return NO;
}
return YES;
}
- (void) close
/*
Shuts down the socket, closes the socket, prevents any
furthering monitoring of activity on that socket and discards any
queued writes for that socket.
*/
{
if (readStream)
{
CFReadStreamClose(readStream);
CFRelease(readStream);
readStream = NULL;
}
if (writeStream)
{
CFWriteStreamClose(writeStream);
CFRelease(writeStream);
writeStream = NULL;
}
// flush the write and read buffers
[writeBuffer release];
writeBuffer = nil;
[readBuffer release];
readBuffer = nil;
[streamDelegate performSelector:@selector(streamDisconnected)];
}
- (void) writeLine: (NSString *)aLine
/*
Writes the specified line when we can.
*/
{
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
NSDate * theDate = [[NSDate alloc]
initWithTimeIntervalSinceNow:timeout];
timer = [[NSTimer alloc]initWithFireDate:theDate
interval:timeout
target:self selector:@selector
(requestTimeOut:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop]addTimer:timer
forMode:NSDefaultRunLoopMode];
toFlag = YES;
if (!writeBuffer)
{
writeBuffer = [[NSMutableData alloc] init];
}
[writeBuffer appendData: [aLine dataUsingEncoding:
NSUTF8StringEncoding]];
[writeBuffer appendData: [@"\r\n" dataUsingEncoding:
NSUTF8StringEncoding]];
[streamDelegate dataWritten:aLine];
[self streamCanAcceptBytes];
}
- (void) writeLineWithFormat: (NSString *)aFormat, ...
{
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
NSDate * theDate = [[NSDate alloc]
initWithTimeIntervalSinceNow:timeout];
timer = [[NSTimer alloc]initWithFireDate:theDate
interval:timeout
target:self selector:@selector
(requestTimeOut:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop]addTimer:timer
forMode:NSDefaultRunLoopMode];
toFlag = YES;
va_list argList;
NSString *formattedString;
va_start(argList, aFormat);
formattedString = [[NSString alloc] initWithFormat: aFormat
arguments: argList];
va_end(argList);
[self writeLine: formattedString];
[formattedString release];
}
/*****
* Generic/errror handling
*****/
- (void) handleGenericResponseLine: (NSString *)aLine
/*
Processes any response which has not yet been handled... this is
generally either a request for authorization or a generic error message.
*/
{
if ([aLine length]) [streamDelegate performSelector:@selector
(newDataAvailable:) withObject:aLine];
}
@end
@implementation AGDStreamObj (Private)
- (void) streamHasBytesAvailable
/*
Private method - gets called when the read stream is ready to be
read from.
*/
{
CFIndex length = CFReadStreamRead(readStream, recvBuffer, 8192);
if (length >=0)
{
toFlag = NO;
[NSObject
cancelPreviousPerformRequestsWithTarget:self selector:@selector
(requestTimeOut:) object:nil];
NSData *data = [NSData dataWithBytes: recvBuffer length: length];
[streamDelegate performSelectorOnMainThread:@selector
(newBytesAvailable:) withObject:data waitUntilDone:YES];
}
}
- (void) streamCanAcceptBytes
/*
Private method - gets called when the write stream is ready to be
written to.
*/
{
if ([writeBuffer length] && CFWriteStreamCanAcceptBytes(writeStream))
{
CFIndex length = CFWriteStreamWrite(writeStream, [writeBuffer
bytes], [writeBuffer length]);
if (length = [writeBuffer length])
{
[writeBuffer release];
writeBuffer = nil;
}
else
{
[writeBuffer replaceBytesInRange: NSMakeRange(0, length)
withBytes: NULL];
}
}
}
- (void) streamOpenCompleted
/*
Private method - gets called when the stream is open
*/
{
NSString * con = [NSString stringWithFormat:@"Connected To: %
@ on Port: %@",[agent objectForKey:AGDServerAddress],[agent
objectForKey:AGDServerPort]];
[streamDelegate performSelector:@selector(streamConnected:)
withObject:con];
workUnitsCompleted = 0;
}
- (void) streamErrorOccurred
/*
Private method - gets called when there is a stream error
*/
{
CFIndex length = CFReadStreamRead(readStream, recvBuffer, 8192);
NSString *string =@"Unknown Error";
if (length != -1)
{
NSData *data = [NSData dataWithBytes: recvBuffer length: length];
string = [[NSString alloc] initWithData: data encoding:
NSISOLatin1StringEncoding];
}
CFStreamError err = CFReadStreamGetError(readStream);
if(err.domain==1) [self closeWithError:err];
else if(CFReadStreamGetStatus(readStream) ==
kCFStreamStatusNotOpen) [self closeWithError:err];
else if(CFReadStreamGetStatus(readStream) ==
kCFStreamStatusAtEnd) [streamDelegate streamDisconnected];
else [streamDelegate streamErrorOccured:err errorText:string];
}
-(void)closeWithError:(CFStreamError)err
{
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(requestTimeOut:) object:nil];
[streamDelegate streamDisconnectWithError:err];
[self close];
}
@end
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden