Enabling garbage collection support.
[ITFoundation.git] / ITByteStream.m
old mode 100755 (executable)
new mode 100644 (file)
index 301d851..a96aa7f
-//
-//  ITByteStream.h
-//  ITFoundation
-//
-//  Created by Alexander Strange on Thu Feb 27 2003.
-//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
-//
-
 #import "ITByteStream.h"
 
-// TODO: Add NSCopying/NSCoding support
+// TODO: Add NSCopying/NSCoding support. Blocking reads (how would this work? NSConditionLock?)
 
 @implementation ITByteStream
--(id) init
-{
-    if (self == [super init])
-          {
-          data = [[NSMutableData alloc] init];
-          }
-    return self;
-}
-
--(id) initWithStream:(ITByteStream*)stream
-{
-    if (self == [super init])
-          {
-          data = [stream->data copy];
-          }
-    return 0;
-}
-
--(void) dealloc
-{
-    [data release];
-    [super dealloc];
-}
-
--(int) availableDataLength
-{
-    return [data length];
-}
-
--(NSData*) readDataOfLength:(int)length
-{
-    NSData *ret, *tmp;
-    NSRange range = {0, length};
-    ret = [data subdataWithRange:range];
-#if MAC_OS_X_VERSION_10_2 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    [data replaceBytesInRange:range withBytes:nil length:0]; // this should delete off the end. should test.
-#else
-    range = {length, [data length]};
-    tmp = [data subdataWithRange:range];
-    [data setData:tmp]; // maybe i should add a lock to this? it would be bad if someone was writing when it was reading...
-#endif
-    return ret;
-}
-
--(void) writeData:(NSData*)_data
-{
-    [data appendData:_data];
+
+- (id)init {
+       if (self == [super init]) {
+               data = [[NSMutableData alloc] init];
+               lock = [[NSLock alloc] init];
+               delegate = nil;
+       }
+       return self;
+}
+
+- (id)initWithDelegate:(id <ITDataReceiver>)d {
+       if (self == [super init]) {
+               data = [[NSMutableData alloc] init];
+               lock = [[NSLock alloc] init];
+               delegate = [d retain];
+       }
+       return self;
+}
+
+- (id)initWithStream:(ITByteStream*)stream delegate:(id <ITDataReceiver>)d {
+       if (self == [super init]) {
+               data = [stream->data copy];
+               lock = [[NSLock alloc] init];
+               delegate = [d retain];
+       }
+       return 0;
+}
+
+- (oneway void)dealloc {
+       [lock lock];
+       [data release];
+       [lock unlock];
+       [lock release];
+       [super dealloc];
 }
+
+- (id <ITDataReceiver>)setDelegate:(id <ITDataReceiver>)d {
+       id old = delegate;
+       [delegate release];
+       delegate = [d retain];
+       return old;
+}
+
+- (id <ITDataReceiver>)delegate {
+       return delegate;
+}
+
+- (int)availableDataLength {
+       int len;
+       [lock lock];
+       len = [data length];
+       [lock unlock];
+       return len;
+}
+
+- (NSData*)readDataOfLength:(int)length {
+       NSData *ret;
+       NSRange range = {0, length};
+       [lock lock];
+       ret = [data subdataWithRange:range];
+       [data replaceBytesInRange:range withBytes:nil length:0];
+       [lock unlock];
+       return ret;
+}
+
+- (NSData*)readAllData {
+       NSData *ret;
+       [lock lock];
+       ret = [data autorelease];
+       data = [[NSMutableData alloc] init];
+       [lock unlock];
+       return ret;
+}
+
+- (void)writeData:(in NSData*)_data {
+       [lock lock];
+       [data appendData:_data];
+       [lock unlock];
+       [delegate newDataAdded:self];
+}
+
+- (void)writeBytes:(in char *)b len:(long)length {
+       [lock lock];
+       [data appendBytes:b length:length];
+       [lock unlock];
+       [delegate newDataAdded:self];
+}
+
+- (void)lockStream {
+       [lock lock];
+}
+
+- (void)unlockStream {
+       [lock unlock];
+}
+
+- (void)shortenData:(long)length {
+       NSRange range = {0, length};
+       [data replaceBytesInRange:range withBytes:nil length:0];
+}
+
 @end