public virtual async Task WriteAsync(Stream destination) { if (destination == null) { throw new ArgumentNullException(nameof(destination)); } Archive.Stream.Seek(Offset, SeekOrigin.Begin); using (var brotli = new BrotliStream(Archive.Stream, CompressionMode.Decompress, leaveOpen: true)) { var size = Math.Max(Archive.BufferSize, 1); var buffer = new byte[size]; long entryLength = 0; do { int read = await brotli.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); if (read == 0) { break; } entryLength += read; await destination.WriteAsync(buffer, 0, read).ConfigureAwait(false); var e = new BrZipArchiveProgressEventArgs(Name, entryLength, destination.Position - Offset); OnProgress(this, e); if (e.Cancel) { return; } }while (true); } }
public virtual long AddEntry(string name, Stream entryStream) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (entryStream == null) { throw new ArgumentNullException(nameof(entryStream)); } Stream.Seek(_lastPos, SeekOrigin.Begin); var bytes = Encoding.UTF8.GetBytes(name); _writer.Write(bytes.Length); _writer.Write(bytes); var uncompressedPos = Stream.Position; _writer.Write(0L); // uncompressed _writer.Write(0L); // compressed // write data var pos = Stream.Position; var entryPos = entryStream; var size = Math.Max(DefaultBufferSize, 1); var buffer = new byte[size]; long entryLength = 0; using (var brotli = new BrotliStream(Stream, CompressionMode.Compress, leaveOpen: true)) { do { int read = entryStream.Read(buffer, 0, buffer.Length); if (read == 0) { break; } entryLength += read; brotli.Write(buffer, 0, read); brotli.Flush(); var e = new BrZipArchiveProgressEventArgs(name, entryLength, Stream.Position - pos); OnProgress(this, e); if (e.Cancel) { break; // file inside the archive will be truncated... } }while (true); } _lastPos = Stream.Position; // go back and update lengths Stream.Seek(uncompressedPos, SeekOrigin.Begin); _writer.Write(entryLength); _writer.Write(_lastPos - pos); return(_lastPos - pos); }
protected virtual void OnProgress(object sender, BrZipArchiveProgressEventArgs e) => Progress?.Invoke(sender, e);