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; if (buffer.Length > 0) { unsafe { var handle = buffer.Pin(); handles.Add(handle); _inflater.SetInput((IntPtr)handle.Pointer, buffer.Length); var wbuffer = writerBuffer.GetMemory(); handle = wbuffer.Pin(); handles.Add(handle); int written = _inflater.Inflate((IntPtr)handle.Pointer, wbuffer.Length); writerBuffer.Advance(written); var consumed = buffer.Length - _inflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); } } reader.AdvanceTo(inputBuffer.End); await writerBuffer.FlushAsync(); } reader.Complete(); writer.Complete(); _inflater.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; if (memory.Length > 0) { unsafe { void *pointer; if (memory.TryGetPointer(out pointer)) { _inflater.SetInput((IntPtr)pointer, memory.Length); void *writePointer; writerBuffer.Ensure(); if (writerBuffer.Memory.TryGetPointer(out writePointer)) { int written = _inflater.Inflate((IntPtr)writePointer, writerBuffer.Memory.Length); writerBuffer.Advance(written); } else { throw new InvalidOperationException("Pointer needs to be pinned"); } } else { throw new InvalidOperationException("Pointer needs to be pinned"); } var consumed = memory.Length - _inflater.AvailableInput; inputBuffer = inputBuffer.Slice(0, consumed); } } reader.Advance(inputBuffer.End); await writerBuffer.FlushAsync(); } reader.Complete(); writer.Complete(); _inflater.Dispose(); }