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) { crc = new CRC32(); } }
private bool _ExtractTo( int index, Stream output, int outBufRemain ) { XUnzipFileInfo fileInfo = _GetFileInfo ( index ); BinaryReader br = new BinaryReader ( inputStream ); if ( fileInfo.offsetData == -1 ) { if ( inputStream.Seek ( fileInfo.offsetLocalHeader, SeekOrigin.Begin ) != fileInfo.offsetLocalHeader ) throw new Exception ( XUNZIP_ERR.CANT_READ_FILE.ToString () ); if ( !ReadLocalHeader ( ref fileInfo, br ) ) return false; } inputStream.Seek ( fileInfo.offsetData, SeekOrigin.Begin ); byte [] bufIn; int inputRemain; int outputRemain; int toRead; uint crc32 = 0; bufIn = new byte [ 32768 ]; inputRemain = fileInfo.compressedSize; outputRemain = fileInfo.uncompressedSize; if ( fileInfo.method == XUNZIP_COMPRESSION_METHOD.METHOD_STORE ) { CRC32 crcGen = new CRC32 (); while ( inputRemain > 0 ) { toRead = System.Math.Min ( System.Math.Min ( 32768, inputRemain ), outputRemain ); int temp = br.Read ( bufIn, 0, toRead ); output.Write ( bufIn, 0, toRead ); crcGen.Update ( bufIn, 0, toRead ); crc32 = crcGen.Result; inputRemain -= toRead; outputRemain -= temp; } } else { DeflateStream stream = new DeflateStream ( inputStream, CompressionMode.Decompress ); CRC32 crcGen = new CRC32 (); while ( inputRemain > 0 ) { toRead = System.Math.Min ( System.Math.Min ( 32768, inputRemain ), outputRemain ); int temp = stream.Read ( bufIn, 0, outputRemain ); output.Write ( bufIn, 0, temp ); crcGen.Update ( bufIn, 0, toRead ); crc32 = crcGen.Result; inputRemain -= toRead; outputRemain -= temp; } } //if ( crc32 != fileInfo.crc32 ) //return false; if ( outputRemain > 0 ) return false; output.Position = 0; return true; }
private void _PerpetualWriterMethod(object state) { TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod START"); try { do { // wait for the next session TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.WaitOne(begin) PWM"); _sessionReset.WaitOne(); TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.WaitOne(done) PWM"); if (_isDisposed) break; TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.Reset() PWM"); _sessionReset.Reset(); // repeatedly write buffers as they become ready WorkItem workitem = null; var c = new CRC32(); do { workitem = _pool[_nextToWrite % _pc]; lock (workitem) { if (_noMoreInputForThisSegment) TraceOutput(TraceBits.Write, "Write drain wi({0}) stat({1}) canuse({2}) cba({3})", workitem.index, workitem.status, (workitem.status == (int)WorkItem.Status.Compressed), workitem.compressedBytesAvailable); do { if (workitem.status == (int)WorkItem.Status.Compressed) { TraceOutput(TraceBits.WriteBegin, "Write begin wi({0}) stat({1}) cba({2})", workitem.index, workitem.status, workitem.compressedBytesAvailable); workitem.status = (int)WorkItem.Status.Writing; _outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable); c.Combine(workitem.crc, workitem.inputBytesAvailable); _totalBytesProcessed += workitem.inputBytesAvailable; _nextToWrite++; workitem.inputBytesAvailable = 0; workitem.status = (int)WorkItem.Status.Done; TraceOutput(TraceBits.WriteDone, "Write done wi({0}) stat({1}) cba({2})", workitem.index, workitem.status, workitem.compressedBytesAvailable); Monitor.Pulse(workitem); break; } else { int wcycles = 0; // I've locked a workitem I cannot use. // Therefore, wake someone else up, and then release the lock. while (workitem.status != (int)WorkItem.Status.Compressed) { TraceOutput(TraceBits.WriteWait, "Write waiting wi({0}) stat({1}) nw({2}) nf({3}) nomore({4})", workitem.index, workitem.status, _nextToWrite, _nextToFill, _noMoreInputForThisSegment); if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill) break; wcycles++; // wake up someone else Monitor.Pulse(workitem); // release and wait Monitor.Wait(workitem); if (workitem.status == (int)WorkItem.Status.Compressed) TraceOutput(TraceBits.WriteWait, "Write A-OK wi({0}) stat({1}) iba({2}) cba({3}) cyc({4})", workitem.index, workitem.status, workitem.inputBytesAvailable, workitem.compressedBytesAvailable, wcycles); } if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill) break; } } while (true); } if (_noMoreInputForThisSegment) TraceOutput(TraceBits.Write, "Write nomore nw({0}) nf({1}) break({2})", _nextToWrite, _nextToFill, (_nextToWrite == _nextToFill)); if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill) break; } while (true); // Finish: // After writing a series of buffers, closing each one with // Flush.Sync, we now write the final one as Flush.Finish, and // then stop. var buffer = new byte[128]; var compressor = new ZlibCodec(); int rc = compressor.InitializeDeflate(_compressLevel, false); compressor.InputBuffer = null; compressor.NextIn = 0; compressor.AvailableBytesIn = 0; compressor.OutputBuffer = buffer; compressor.NextOut = 0; compressor.AvailableBytesOut = buffer.Length; rc = compressor.Deflate(FlushType.Finish); if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) throw new Exception("deflating: " + compressor.Message); if (buffer.Length - compressor.AvailableBytesOut > 0) { TraceOutput(TraceBits.WriteBegin, "Write begin flush bytes({0})", buffer.Length - compressor.AvailableBytesOut); _outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); TraceOutput(TraceBits.WriteBegin, "Write done flush"); } compressor.EndDeflate(); _Crc32 = c.Crc32Result; // signal that writing is complete: TraceOutput(TraceBits.Synch, "Synch _writingDone.Set() PWM"); _writingDone.Set(); } while (true); } catch (Exception exc1) { lock (_eLock) { // expose the exception to the main thread if (_pendingException != null) _pendingException = exc1; } } TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS"); }
private void _DeflateOne(Object wi) { var workitem = (WorkItem)wi; try { // compress one buffer //int myItem = workitem.index; lock (workitem) { if (workitem.status != (int)WorkItem.Status.Filled) throw new InvalidOperationException(); var crc = new CRC32(); // use the workitem: // calc CRC on the buffer crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable); // deflate it DeflateOneSegment(workitem); // update status workitem.status = (int)WorkItem.Status.Compressed; workitem.crc = crc.Crc32Result; TraceOutput(TraceBits.Compress, "Compress wi({0}) stat({1}) len({2})", workitem.index, workitem.status, workitem.compressedBytesAvailable ); // release the item Monitor.Pulse(workitem); } } catch (Exception exc1) { lock (_eLock) { // expose the exception to the main thread if (_pendingException != null) _pendingException = exc1; } } }
private void _PerpetualWriterMethod(object state) { try { WorkItem item; CRC32 crc; TR_0020: while (true) { this._sessionReset.WaitOne(); if (this._isDisposed) { break; } this._sessionReset.Reset(); item = null; crc = new CRC32(); goto TR_001C; } return; TR_000E: if (this._noMoreInputForThisSegment) { } if (!this._noMoreInputForThisSegment || (this._nextToWrite != this._nextToFill)) { goto TR_001C; } else { byte[] buffer = new byte[0x80]; ZlibCodec codec = new ZlibCodec(); int num2 = codec.InitializeDeflate(this._compressLevel, false); codec.InputBuffer = null; codec.NextIn = 0; codec.AvailableBytesIn = 0; codec.OutputBuffer = buffer; codec.NextOut = 0; codec.AvailableBytesOut = buffer.Length; num2 = codec.Deflate(FlushType.Finish); if ((num2 != 1) && (num2 != 0)) { throw new Exception("deflating: " + codec.Message); } if ((buffer.Length - codec.AvailableBytesOut) > 0) { this._outStream.Write(buffer, 0, buffer.Length - codec.AvailableBytesOut); } codec.EndDeflate(); this._Crc32 = crc.Crc32Result; this._writingDone.Set(); } goto TR_0020; TR_001C: while (true) { item = this._pool[this._nextToWrite % this._pc]; object obj2 = item; lock (obj2) { if (this._noMoreInputForThisSegment) { } while (true) { if (item.status != 4) { int num = 0; while (true) { if ((item.status != 4) && (!this._noMoreInputForThisSegment || (this._nextToWrite != this._nextToFill))) { num++; Monitor.Pulse(item); Monitor.Wait(item); if (item.status == 4) { } continue; } if (!this._noMoreInputForThisSegment || (this._nextToWrite != this._nextToFill)) { break; } break; } continue; } else { item.status = 5; this._outStream.Write(item.compressed, 0, item.compressedBytesAvailable); crc.Combine(item.crc, item.inputBytesAvailable); this._totalBytesProcessed += item.inputBytesAvailable; this._nextToWrite++; item.inputBytesAvailable = 0; item.status = 6; Monitor.Pulse(item); } break; } } break; } goto TR_000E; } catch (Exception exception) { lock (this._eLock) { if (this._pendingException != null) { this._pendingException = exception; } } } }
// 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, Stream stream) { _innerStream = stream; _Crc32 = new CRC32(); _lengthLimit = length; _leaveOpen = leaveOpen; }