private Finish ( byte outputBuffer, int &bytesRead ) : bool | ||
outputBuffer | byte | |
bytesRead | int | |
return | bool |
// This is called by Dispose: private void PurgeBuffers(bool disposing) { if (!disposing) { return; } if (_stream == null) { return; } if (_mode != CompressionMode.Compress) { return; } // Some deflaters (e.g. ZLib) write more than zero bytes for zero byte inputs. // This round-trips and we should be ok with this, but our legacy managed deflater // always wrote zero output for zero input and upstack code (e.g. ZipArchiveEntry) // took dependencies on it. Thus, make sure to only "flush" when we actually had // some input: if (_wroteBytes) { // Compress any bytes left WriteDeflaterOutput(); // Pull out any bytes left inside deflater: bool finished; do { int compressedBytes; finished = _deflater.Finish(_buffer, out compressedBytes); if (compressedBytes > 0) { _stream.Write(_buffer, 0, compressedBytes); } } while (!finished); } else { // In case of zero length buffer, we still need to clean up the native created stream before // the object get disposed because eventually ZLibNative.ReleaseHandle will get called during // the dispose operation and although it frees the stream but it return error code because the // stream state was still marked as in use. The symptoms of this problem will not be seen except // if running any diagnostic tools which check for disposing safe handle objects bool finished; do { int compressedBytes; finished = _deflater.Finish(_buffer, out compressedBytes); } while (!finished); } }
// Close this stream. public override void Close() { if (stream != null) { if (deflater != null) { int temp; deflater.Finish(); while (!deflater.IsFinished) { temp = deflater.Deflate(buf, 0, buf.Length); if (temp <= 0) { if (!deflater.IsFinished) { throw new IOException ("IO_Compress_Input"); } break; } stream.Write(buf, 0, temp); } } if (!leaveOpen) { stream.Close(); } stream = null; inflater = null; deflater = null; buf = null; } }
protected override void Dispose(bool disposing) { try { // Flush on the underlying stream can throw (ex., low disk space) if (disposing && _stream != null) { Flush(); // Need to do close the output stream in compression mode if (_mode == CompressionMode.Compress && _stream != null) { int bytesCompressed; // compress any bytes left. while (!deflater.NeedsInput()) { bytesCompressed = deflater.GetDeflateOutput(buffer); if (bytesCompressed != 0) { _stream.Write(buffer, 0, bytesCompressed); } } // Write the end of compressed stream data. // We can safely do this since the buffer is large enough. bytesCompressed = deflater.Finish(buffer); if (bytesCompressed > 0) { _stream.Write(buffer, 0, bytesCompressed); } } } } finally { try { // Attempt to close the stream even if there was an IO error from Flushing. // Note that Stream.Close() can potentially throw here (may or may not be // due to the same Flush error). In this case, we still need to ensure // cleaning up internal resources, hence the finally block. if (disposing && !_leaveOpen && _stream != null) { _stream.Close(); } } finally { _stream = null; base.Dispose(disposing); } } }
// Note: The .NET Framework SDK 2.0 version of this class does // not have BeginWrite and EndWrite for some inexplicable reason. // Close this stream. public override void Close() { if (stream != null) { if (deflater != null) { int temp; deflater.Finish(); while (!deflater.IsFinished) { temp = deflater.Deflate(buf, 0, buf.Length); if (temp <= 0) { if (!deflater.IsFinished) { throw new IOException (S._("IO_Compress_Input")); } break; } stream.Write(buf, 0, temp); } byte[] footer = new byte [8]; temp = (int)(crc32.Value); footer[0] = (byte)temp; footer[1] = (byte)(temp << 8); footer[2] = (byte)(temp << 16); footer[3] = (byte)(temp << 24); temp = deflater.TotalIn; footer[4] = (byte)temp; footer[5] = (byte)(temp << 8); footer[6] = (byte)(temp << 16); footer[7] = (byte)(temp << 24); stream.Write(footer, 0, 8); } if (!leaveOpen) { stream.Close(); } stream = null; inflater = null; deflater = null; buf = null; } }