PipeFilterResult DoFilter_BeforeWriting(ref SmartBuffer buffer, SortedSet <PipeFilter> filters, CancellationToken cancellationToken) { PipeFilterResult rt = default; foreach (var f in filters) { _logger?.LogInformation($"DefaultPipe DoFilter_BeforeWriting {f.ToString()}..."); PipeFilterContext ctx = new PipeFilterContext(f.Client, buffer.Memory, buffer.SignificantLength); try { rt = f.BeforeWriting(ctx); if (!rt.Continue || cancellationToken.IsCancellationRequested) { buffer.Dispose(); rt.Buffer?.Dispose(); break; } buffer.Dispose(); buffer = rt.Buffer; //next filter } catch (Exception ex) { _logger?.LogError(ex, $"DefaultPipe DoFilter_BeforeWriting {f.ToString()} error."); buffer.Dispose(); rt = new PipeFilterResult(ctx.Client, null, false); break; } } return(rt); }
async Task PipeB2A(CancellationToken cancellationToken) { SmartBuffer buffer = SmartBuffer.Rent(_bufferSize);//read buff buffer.SignificantLength = await ClientB.ReadAsync(buffer.Memory, cancellationToken); if (buffer.SignificantLength > 0) { if (_filtersB.Count > 0) { bool locked = false; try { DoFilter_Lock(ref locked); PipeFilterResult filterResult = DoFilter_AfterReading(ref buffer, _filtersB, cancellationToken); if (!filterResult.Continue || cancellationToken.IsCancellationRequested) { ReportBroken(); return; } else { buffer = filterResult.Buffer; } DoFilter_UnLock(ref locked); } finally { DoFilter_UnLock(ref locked); } }//end FilterB if (_filtersA.Count > 0) { bool locked = false; try { DoFilter_Lock(ref locked); PipeFilterResult filterResult = DoFilter_BeforeWriting(ref buffer, _filtersA, cancellationToken); if (!filterResult.Continue || cancellationToken.IsCancellationRequested) { ReportBroken(); return; } else { buffer = filterResult.Buffer; } DoFilter_UnLock(ref locked); } finally { DoFilter_UnLock(ref locked); } }//end FilterA int written = await ClientA.WriteAsync(buffer.Memory, cancellationToken);//Pipe _logger?.LogInformation($"DefaultPipe Pipe B to A {written} bytes."); if (written < 0) { ClientA.Close(); buffer.Dispose(); ReportBroken(); return; } } else if (0 == buffer.SignificantLength) { _logger?.LogInformation($"DefaultPipe read = 0."); } else//<0 { _logger?.LogInformation($"DefaultPipe error, read={buffer.SignificantLength}."); ClientB.Close(); ReportBroken(); return; } buffer.Dispose();//free memory. if (!cancellationToken.IsCancellationRequested) { await PipeB2A(cancellationToken);//continue. } }