From fc047ffd2c67b277d9d67a04831f3d227d0a93d3 Mon Sep 17 00:00:00 2001 From: Jim Dovey Date: Wed, 22 Apr 2009 11:05:15 -0400 Subject: [PATCH] Added ability to specify input & output buffer sizes for memory-based Gzip streams. --- Compression/AQGzipInputStream.m | 26 +++++++++++++++++ Compression/AQGzipOutputStream.m | 26 +++++++++++++++++ Compression/AQGzipStream.h | 12 ++++++-- Compression/_AQGzipStreamInternal.h | 4 +++ Compression/_AQGzipStreamInternal.m | 44 +++++++++++++++++++++++------ 5 files changed, 101 insertions(+), 11 deletions(-) diff --git a/Compression/AQGzipInputStream.m b/Compression/AQGzipInputStream.m index 2144d10..5715822 100644 --- a/Compression/AQGzipInputStream.m +++ b/Compression/AQGzipInputStream.m @@ -69,6 +69,32 @@ - (NSStreamStatus) streamStatus return ( _internal.status ); } +- (NSInteger) inputBufferSize +{ + return ( _internal.inputSize ); +} + +- (void) setInputBufferSize: (NSInteger) value +{ + if ( _internal.status != NSStreamStatusNotOpen ) + return; + + _internal.inputSize = value; +} + +- (NSInteger) outputBufferSize +{ + return ( _internal.outputSize ); +} + +- (void) setOutputBufferSize: (NSInteger) value +{ + if ( _internal.status != NSStreamStatusNotOpen ) + return; + + _internal.outputSize = value; +} + - (void) open { if ( _internal.status != NSStreamStatusNotOpen ) diff --git a/Compression/AQGzipOutputStream.m b/Compression/AQGzipOutputStream.m index 72f1fbd..415a7a1 100644 --- a/Compression/AQGzipOutputStream.m +++ b/Compression/AQGzipOutputStream.m @@ -101,6 +101,32 @@ - (void) setCompressionLevel: (AQGzipCompressionLevel) newLevel _level = newLevel; } +- (NSInteger) inputBufferSize +{ + return ( _internal.inputSize ); +} + +- (void) setInputBufferSize: (NSInteger) value +{ + if ( _internal.status != NSStreamStatusNotOpen ) + return; + + _internal.inputSize = value; +} + +- (NSInteger) outputBufferSize +{ + return ( _internal.outputSize ); +} + +- (void) setOutputBufferSize: (NSInteger) value +{ + if ( _internal.status != NSStreamStatusNotOpen ) + return; + + _internal.outputSize = value; +} + - (void) open { if ( _internal.status != NSStreamStatusNotOpen ) diff --git a/Compression/AQGzipStream.h b/Compression/AQGzipStream.h index 5168774..7169af3 100644 --- a/Compression/AQGzipStream.h +++ b/Compression/AQGzipStream.h @@ -55,8 +55,14 @@ typedef NSInteger AQGzipCompressionLevel; //////////////////////////////////////////////////////////////////////// +// all these properties can only be set prior to opening the stream + +@protocol AQGzipMemoryStreamOptimisation +@property (nonatomic) NSInteger inputBufferSize; +@property (nonatomic) NSInteger outputBufferSize; +@end + @protocol AQGzipOutputCompressor -// can only be set prior to opening the stream @property (nonatomic) AQGzipCompressionLevel compressionLevel; @end @@ -66,7 +72,7 @@ typedef NSInteger AQGzipCompressionLevel; // need to be subclasses of different parents // My way around this is for each thing to *contain* a common instance, which stores // all the common state information, etc. -@interface AQGzipInputStream : NSInputStream +@interface AQGzipInputStream : NSInputStream { NSInputStream * _compressedDataStream; _AQGzipStreamInternal * _internal; @@ -79,7 +85,7 @@ typedef NSInteger AQGzipCompressionLevel; @end -@interface AQGzipOutputStream : NSOutputStream +@interface AQGzipOutputStream : NSOutputStream { NSOutputStream * _outputStream; _AQGzipStreamInternal * _internal; diff --git a/Compression/_AQGzipStreamInternal.h b/Compression/_AQGzipStreamInternal.h index a387152..9c8debe 100644 --- a/Compression/_AQGzipStreamInternal.h +++ b/Compression/_AQGzipStreamInternal.h @@ -53,6 +53,8 @@ NSError * _error; NSStreamStatus _status; id __weak _delegate; + NSInteger _inputSize; + NSInteger _outputSize; Bytef * _input; Bytef * _output; NSUInteger _writeOffset; @@ -70,6 +72,8 @@ @property (NS_NONATOMIC_IPHONEONLY retain) NSError * error; @property (NS_NONATOMIC_IPHONEONLY readwrite) NSStreamStatus status; @property (NS_NONATOMIC_IPHONEONLY assign) id __weak delegate; +@property (nonatomic) NSInteger inputSize; +@property (nonatomic) NSInteger outputSize; @property (nonatomic, readonly) Bytef * input; @property (nonatomic, readonly) Bytef * output; @property (NS_NONATOMIC_IPHONEONLY assign) NSUInteger writeOffset; diff --git a/Compression/_AQGzipStreamInternal.m b/Compression/_AQGzipStreamInternal.m index 7c8c513..3e8c400 100644 --- a/Compression/_AQGzipStreamInternal.m +++ b/Compression/_AQGzipStreamInternal.m @@ -61,6 +61,8 @@ # define ATOMIC_ZSTREAM_SET(val, nval) _zStream->val = nval #endif +#define DEFAULT_BUFFER_SIZE (1024) + NSString * const AQZlibErrorDomain = @"AQZlibErrorDomain"; NSError * CreateZlibError( z_stream *pZ, int err ) @@ -116,6 +118,8 @@ @implementation _AQGzipStreamInternal @synthesize error=_error; @synthesize status=_status; @synthesize delegate=_delegate; +@synthesize inputSize=_inputSize; +@synthesize outputSize=_outputSize; @synthesize input=_input; @synthesize output=_output; @synthesize writeOffset=_writeOffset; @@ -128,21 +132,23 @@ - (id) init if ( [super init] == nil ) return ( nil ); + _inputSize = _outputSize = DEFAULT_BUFFER_SIZE; + #if TARGET_OS_IPHONE _zStream = NSZoneMalloc( [self zone], sizeof(z_stream) ); - _input = NSZoneMalloc( [self zone], 1024 ); - _output = NSZoneMalloc( [self zone], 1024 ); + _input = NSZoneMalloc( [self zone], _inputSize ); + _output = NSZoneMalloc( [self zone], _outputSize ); #else _zStream = NSAllocateCollectable( sizeof(z_stream), 0 ); - _input = NSAllocateCollectable( 1024, 0 ); - _output = NSAllocateCollectable( 1024, 0 ); + _input = NSAllocateCollectable( _inputSize, 0 ); + _output = NSAllocateCollectable( _outputSize, 0 ); #endif _zStream->next_in = _input; _zStream->avail_in = 0; _zStream->total_in = 0; _zStream->next_out = _output; - _zStream->avail_out = 1024; + _zStream->avail_out = _outputSize; _zStream->total_out = 0; _zStream->zalloc = NULL; _zStream->zfree = NULL; @@ -176,6 +182,28 @@ - (void) finalize [super finalize]; } +- (void) setInputSize: (NSInteger) inputSize +{ + _inputSize = inputSize; +#if TARGET_OS_IPHONE + NSZoneRealloc( [self zone], _input, inputSize ); +#else + NSReallocateCollectable( _input, inputSize, 0 ); +#endif +} + +- (void) setOutputSize: (NSInteger) outputSize +{ + _outputSize = outputSize; +#if TARGET_OS_IPHONE + NSZoneRealloc( [self zone], _output, outputSize ); +#else + NSReallocateCollectable( _output, outputSize, 0 ); +#endif + + _zStream->avail_out = outputSize; +} + - (void) createRunloopSourceForStream: (id) stream { // allocate with receive right @@ -325,7 +353,7 @@ - (char *) msg - (NSInteger) inputRoom { - return ( 1024 - _writeOffset ); + return ( _inputSize - _writeOffset ); } - (void *) inputPtr @@ -383,7 +411,7 @@ - (NSInteger) readOutputToBuffer: (void *) buffer length: (NSInteger) length { // reset output buffer _zStream->next_out = _output; - _zStream->avail_out = 1024; + _zStream->avail_out = _outputSize; _zStream->total_out = 0; _readOffset = 0; } @@ -405,7 +433,7 @@ - (NSInteger) readOutputToStream: (NSOutputStream *) stream { // reset output buffer _zStream->next_out = _output; - _zStream->avail_out = 1024; + _zStream->avail_out = _outputSize; _zStream->total_out = 0; _readOffset = 0; }