public ZlibBaseStream(System.IO.Stream stream, CompressionMode compressionMode, CompressionLevel level, ZlibStreamFlavor flavor, bool leaveOpen) : base() { this._flushMode = FlushType.None; //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT]; this._stream = stream; this._leaveOpen = leaveOpen; this._compressionMode = compressionMode; this._flavor = flavor; this._level = level; // workitem 7159 if (flavor == ZlibStreamFlavor.GZIP) { this.crc = new CRC32(); } }
// This ctor is private - no validation is done here. This is to allow the use // of a (specific) negative value for the _lengthLimit, to indicate that there // is no length set. So we validate the length limit in those ctors that use an // explicit param, otherwise we don't validate, because it could be our special // value. private CrcCalculatorStream (bool leaveOpen, Int64 length, System.IO.Stream stream, CRC32 crc32) : base() { _innerStream = stream; _Crc32 = crc32 ?? new CRC32(); _lengthLimit = length; _leaveOpen = leaveOpen; }
/// <summary> /// A constructor allowing the specification of the length of the stream /// to read, as well as whether to keep the underlying stream open upon /// Close(), and the CRC32 instance to use. /// </summary> /// <remarks> /// <para> /// The stream uses the specified CRC32 instance, which allows the /// application to specify how the CRC gets calculated. /// </para> /// </remarks> /// <param name="stream">The underlying stream</param> /// <param name="length">The length of the stream to slurp</param> /// <param name="leaveOpen">true to leave the underlying stream /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param> /// <param name="crc32">the CRC32 instance to use to calculate the CRC32</param> public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen, CRC32 crc32) : this(leaveOpen, length, stream, crc32) { if (length < 0) throw new ArgumentException("length"); }
/// <summary> /// Resets the stream for use with another stream. /// </summary> /// <remarks> /// Because the ParallelDeflateOutputStream is expensive to create, it /// has been designed so that it can be recycled and re-used. You have /// to call Close() on the stream first, then you can call Reset() on /// it, to use it again on another stream. /// </remarks> /// /// <param name="stream"> /// The new output stream for this era. /// </param> /// /// <example> /// <code> /// ParallelDeflateOutputStream deflater = null; /// foreach (var inputFile in listOfFiles) /// { /// string outputFile = inputFile + ".compressed"; /// using (System.IO.Stream input = System.IO.File.OpenRead(inputFile)) /// { /// using (var outStream = System.IO.File.Create(outputFile)) /// { /// if (deflater == null) /// deflater = new ParallelDeflateOutputStream(outStream, /// CompressionLevel.Best, /// CompressionStrategy.Default, /// true); /// deflater.Reset(outStream); /// /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) /// { /// deflater.Write(buffer, 0, n); /// } /// } /// } /// } /// </code> /// </example> public void Reset(Stream stream) { TraceOutput(TraceBits.Session, "-------------------------------------------------------"); TraceOutput(TraceBits.Session, "Reset {0:X8} firstDone({1})", this.GetHashCode(), _firstWriteDone); if (!_firstWriteDone) return; // reset all status _toWrite.Clear(); _toFill.Clear(); foreach (var workitem in _pool) { _toFill.Enqueue(workitem.index); workitem.ordinal = -1; } _firstWriteDone = false; _totalBytesProcessed = 0L; _runningCrc = new CRC32(); _isClosed= false; _currentlyFilling = -1; _lastFilled = -1; _lastWritten = -1; _latestCompressed = -1; _outStream = stream; }
private void _InitializePoolOfWorkItems() { _toWrite = new Queue<int>(); _toFill = new Queue<int>(); _pool = new System.Collections.Generic.List<WorkItem>(); int nTasks = BufferPairsPerCore * Environment.ProcessorCount; nTasks = Math.Min(nTasks, _maxBufferPairs); for(int i=0; i < nTasks; i++) { _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy, i)); _toFill.Enqueue(i); } _newlyCompressedBlob = new AutoResetEvent(false); _runningCrc = new CRC32(); _currentlyFilling = -1; _lastFilled = -1; _lastWritten = -1; _latestCompressed = -1; }
private void _DeflateOne(Object wi) { // compress one buffer WorkItem workitem = (WorkItem) wi; try { int myItem = workitem.index; CRC32 crc = new CRC32(); // calc CRC on the buffer crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable); // deflate it DeflateOneSegment(workitem); // update status workitem.crc = crc.Crc32Result; TraceOutput(TraceBits.Compress, "Compress wi({0}) ord({1}) len({2})", workitem.index, workitem.ordinal, workitem.compressedBytesAvailable ); lock(_latestLock) { if (workitem.ordinal > _latestCompressed) _latestCompressed = workitem.ordinal; } lock (_toWrite) { _toWrite.Enqueue(workitem.index); } _newlyCompressedBlob.Set(); } catch (System.Exception exc1) { lock(_eLock) { // expose the exception to the main thread if (_pendingException!=null) _pendingException = exc1; } } }