There is a desire to expose compression-algorithm specific configuration when constructing compression streams. The same options can be used for ZLibStream, DeflateStream, GZipStream. Named those options with Zlib prefix same as the native library name they use another prefix we considered is Deflate - the algorithm name, the prefix needed because we have existing CompressionLevel enum that used for all compression streams including BrotliStream and it cannot be used for fine tuning the compression level for specific stream
| publicenumCompressionLevel |
| { |
| Optimal=0, |
| Fastest=1, |
| NoCompression=2, |
| SmallestSize=3, |
| } |
API Proposal
namespaceSystem.IO.Compression{publicenumZlibCompressionLevel{DefaultCompression=-1,NoCompression=0,Level1=1,BestSpeed=Level1,Level2=2,Level3=3,Level4=4,Level5=5,Level6=6,Level7=7,Level8=8,Level9=9,BestCompression=Level9,}publicenumZlibCompressionStrategy{DefaultStrategy=0,Filtered=1,HuffmanOnly=2,Rle=3,Fixed=4}publicenumZlibFlushMode{NoFlush=0,PartialFlush=1,SyncFlush=2,FullFlush=3,Finish=4,}publicsealedclassZLibStream:Stream{// CompressionMode.CompresspublicZLibStream(Streamstream,ZlibCompressionLevelcompressionLevel=ZlibCompressionLevel.DefaultCompression,ZlibCompressionStrategystrategy=ZlibCompressionStrategy.DefaultStrategy,boolleaveOpen=false);publicZlibFlushModeFlushMode{get;set;}}publicpartialclassDeflateStream:Stream{publicDeflateStream(Streamstream,ZlibCompressionLevelcompressionLevel=ZlibCompressionLevel.DefaultCompression,ZlibCompressionStrategystrategy=ZlibCompressionStrategy.DefaultStrategy,boolleaveOpen=false);publicZlibFlushModeFlushMode{get;set;}}publicpartialclassGZipStream:Stream{publicGZipStream(Streamstream,ZlibCompressionLevelcompressionLevel=ZlibCompressionLevel.DefaultCompression,ZlibCompressionStrategystrategy=ZlibCompressionStrategy.DefaultStrategy,boolleaveOpen=false){}publicZlibFlushModeFlushMode{get;set;}}publicenumBrotliCompressionQuality{NoCompression,Quality1,Quality2,Quality3,Quality4,Quality5,Quality6,Quality7,Quality8,Quality9,Quality10,Quality11}publicsealedpartialclassBrotliStream:System.IO.Stream{publicBrotliStream(Streamstream,BrotliCompressionQualityquality=BrotliCompressionQuality.Quality4,boolleaveOpen=false){}}}ZlibCompressionLevel, ZlibCompressionStrategy are only for Compress mode.
Currently ZlibFlushMode.NoFlush used in normal Read/Write operations, ZlibFlushMode.SyncFlush used for Stream.Flush and ZlibFlushMode.Finish is used on dispose. The value set by the new FlushMode property will be used for normal Read/Write operations only.
The MemoryLevel and/or WindowBits options are omitted because there is no ask for them, we could add these and other options if/when they are requested.
API Usage
privateMemoryStreamCompressStream(StreamuncompressedStream){varcompressorOutput=newMemoryStream();using(varcompressionStream=newZLibStream(compressorOutput,compressionLevel:ZlibCompressionLevel.Level5,strategy:ZlibCompressionStrategy.Filtered,leaveOpen:true)){compressionStream.FlushMode=ZlibFlushMode.NoFlush;varbuffer=newbyte[4096];intbytesRead;while((bytesRead=uncompressedStream.Read(buffer,0,buffer.Length))>0){compressionStream.Write(buffer,0,bytesRead);}}compressorOutput.Position=0;returncompressorOutput;}Alternative Designs
An alternative design would introduce an options type, maybe per each stream, like so:
namespaceSystem.IO.Compression{publicclassBrotliOptions{publicreadonlyBrotliCompressionQualityQuality{get;}publicreadonlyintWindowBits{get;}publicBrotliOptions(BrotliCompressionQualityquality=BrotliCompressionQuality.Level4,intwindowBits=22){}}publicsealedclassBrotliStream:Stream{publicBrotliStream(Streamstream,BrotliOptionsoptions,boolleaveOpen=false);}publicstructZLibOptions{publicintWindowBits{get;}publicZlibMemoryLevelMemoryLevel{get;}publicintCompressionLevel{get;}publicintCompressionStrategy{get;}publicZlibOptions(ZlibCompressionLevelcompressionLevel=ZlibCompressionLevel.DefaultCompression,ZlibCompressionStrategystrategy=ZlibCompressionStrategy.DefaultStrategy,ZlibMemoryLevelmemoryLevel=ZlibMemoryLevel.Level8,intwindowBits=-1);}publicsealedclassZLibStream:Stream{publicZLibStream(Streamstream,ZLibOptionsoptions,boolleaveOpen=false);}publicclassDeflateStream:Stream{publicDeflateStream(Streamstream,ZLibOptionsoptions,boolleaveOpen=false);}publicclassGZipStream:Stream{publicGZipStream(Streamstream,ZLibOptionsoptions,boolleaveOpen=false);}}We can then decide whether we want to be in the business of defining enums for the underlying types or whether we consider them passthru.
There is a desire to expose compression-algorithm specific configuration when constructing compression streams. The same options can be used for
ZLibStream,DeflateStream,GZipStream. Named those options withZlibprefix same as the native library name they use another prefix we considered isDeflate- the algorithm name, the prefix needed because we have existingCompressionLevelenum that used for all compression streams includingBrotliStreamand it cannot be used for fine tuning the compression level for specific streamruntime/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs
Lines 9 to 15 in d710379
API Proposal
ZlibCompressionLevel,ZlibCompressionStrategyare only for Compress mode.Currently
ZlibFlushMode.NoFlushused in normalRead/Writeoperations,ZlibFlushMode.SyncFlushused for Stream.Flush andZlibFlushMode.Finishis used on dispose. The value set by the newFlushModeproperty will be used for normalRead/Writeoperations only.The
MemoryLeveland/orWindowBitsoptions are omitted because there is no ask for them, we could add these and other options if/when they are requested.API Usage
Alternative Designs
An alternative design would introduce an options type, maybe per each stream, like so:
We can then decide whether we want to be in the business of defining enums for the underlying types or whether we consider them passthru.