public async Task Execute(PipeReader reader, PipeWriter writer) { List <MemoryHandle> handles = new List <MemoryHandle>(); while (true) { var result = await reader.ReadAsync(); var inputBuffer = result.Buffer; if (inputBuffer.IsEmpty) { if (result.IsCompleted) { break; } reader.AdvanceTo(inputBuffer.End); continue; } var writerBuffer = writer; var buffer = inputBuffer.First; unsafe { var handle = buffer.Pin(); handles.Add(handle); _deflater.SetInput((IntPtr)handle.Pointer, buffer.Length); } while (!_deflater.NeedsInput()) { unsafe { var wbuffer = writerBuffer.GetMemory(); var handle = wbuffer.Pin(); handles.Add(handle); int written = _deflater.ReadDeflateOutput((IntPtr)handle.Pointer, wbuffer.Length); writerBuffer.Advance(written); } } var consumed = buffer.Length - _deflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); reader.AdvanceTo(inputBuffer.End); await writerBuffer.FlushAsync(); } bool flushed = false; do { // Need to do more stuff here var writerBuffer = writer; unsafe { var memory = writerBuffer.GetMemory(); var handle = memory.Pin(); handles.Add(handle); flushed = _deflater.Flush((IntPtr)handle.Pointer, memory.Length, out int compressedBytes); writerBuffer.Advance(compressedBytes); } await writerBuffer.FlushAsync(); }while (flushed); bool finished = false; do { // Need to do more stuff here var writerBuffer = writer; unsafe { var memory = writerBuffer.GetMemory(); var handle = memory.Pin(); handles.Add(handle); finished = _deflater.Finish((IntPtr)handle.Pointer, memory.Length, out int compressedBytes); writerBuffer.Advance(compressedBytes); } await writerBuffer.FlushAsync(); }while (!finished); reader.Complete(); writer.Complete(); _deflater.Dispose(); foreach (var handle in handles) { handle.Dispose(); } }
public async Task Execute(IPipelineReader reader, IPipelineWriter writer) { while (true) { var result = await reader.ReadAsync(); var inputBuffer = result.Buffer; if (inputBuffer.IsEmpty) { if (result.IsCompleted) { break; } reader.Advance(inputBuffer.End); continue; } var writerBuffer = writer.Alloc(); var memory = inputBuffer.First; unsafe { // TODO: Pin pointer if not pinned void *inPointer; if (memory.TryGetPointer(out inPointer)) { _deflater.SetInput((IntPtr)inPointer, memory.Length); } else { throw new InvalidOperationException("Pointer needs to be pinned"); } } while (!_deflater.NeedsInput()) { unsafe { void *outPointer; writerBuffer.Ensure(); if (writerBuffer.Memory.TryGetPointer(out outPointer)) { int written = _deflater.ReadDeflateOutput((IntPtr)outPointer, writerBuffer.Memory.Length); writerBuffer.Advance(written); } else { throw new InvalidOperationException("Pointer needs to be pinned"); } } } var consumed = memory.Length - _deflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); reader.Advance(inputBuffer.End); await writerBuffer.FlushAsync(); } bool flushed = false; do { // Need to do more stuff here var writerBuffer = writer.Alloc(); unsafe { void *pointer; writerBuffer.Ensure(); var memory = writerBuffer.Memory; if (memory.TryGetPointer(out pointer)) { int compressedBytes; flushed = _deflater.Flush((IntPtr)pointer, memory.Length, out compressedBytes); writerBuffer.Advance(compressedBytes); } else { throw new InvalidOperationException("Pointer needs to be pinned"); } } await writerBuffer.FlushAsync(); }while (flushed); bool finished = false; do { // Need to do more stuff here var writerBuffer = writer.Alloc(); unsafe { void *pointer; writerBuffer.Ensure(); var memory = writerBuffer.Memory; if (memory.TryGetPointer(out pointer)) { int compressedBytes; finished = _deflater.Finish((IntPtr)pointer, memory.Length, out compressedBytes); writerBuffer.Advance(compressedBytes); } } await writerBuffer.FlushAsync(); }while (!finished); reader.Complete(); writer.Complete(); _deflater.Dispose(); }