public override void Write(byte[] buffer, int offset, int count) { // workitem 7159 // calculate the CRC on the unccompressed data (before writing) _crc?.SlurpBlock(buffer.AsSpan(offset, count)); if (_streamMode == StreamMode.Undefined) { _streamMode = StreamMode.Writer; } else if (_streamMode != StreamMode.Writer) { throw new ZlibException("Cannot Write after Reading."); } if (count == 0) { return; } // first reference of z property will initialize the private var _z Z.InputBuffer = buffer; _z.NextIn = offset; _z.AvailableBytesIn = count; bool done; do { _z.OutputBuffer = WorkingBuffer; _z.NextOut = 0; _z.AvailableBytesOut = _workingBuffer.Length; int rc = WantCompress ? _z.Deflate(_flushMode) : _z.Inflate(_flushMode); if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) { throw new ZlibException((WantCompress ? "de" : "in") + "flating: " + _z.Message); } //if (_workingBuffer.Length - _z.AvailableBytesOut > 0) _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; // If GZIP and de-compress, we're done when 8 bytes remain. if (_flavor == ZlibStreamFlavor.GZIP && !WantCompress) { done = _z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0; } }while (!done); }
private void DeflateOne(object?wi) { if (wi == null) { throw new ArgumentNullException(nameof(wi)); } // compress one buffer var workitem = (WorkItem)wi; try { int myItem = workitem.index; var crc = new Crc.Crc32(); // calc CRC on the buffer crc.SlurpBlock(workitem.buffer.AsSpan(0, workitem.inputBytesAvailable)); // deflate it int rc = 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 (Exception exc1) { lock (_eLock) { // expose the exception to the main thread if (_pendingException != null) { _pendingException = exc1; } } } }