public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // enough space left in buffer? var free = WriteBuffer.Capacity - WriteBuffer.Length; if (length > free) { ArraySegment <byte> bufSegment; WriteBuffer.TryGetBuffer(out bufSegment); await InnerTransport.WriteAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); WriteBuffer.SetLength(0); } // do the data even fit into the buffer? // Note we test for < instead of <= to avoid nonsense buffering if (length < WriteBuffer.Capacity) { await WriteBuffer.WriteAsync(buffer, offset, length, cancellationToken); return; } // write thru await InnerTransport.WriteAsync(buffer, offset, length, cancellationToken); }
public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // Relative offset from "off" argument var writtenCount = 0; if (_outputBuffer.Length > 0) { var capa = (int)(_outputBuffer.Capacity - _outputBuffer.Length); var writeSize = capa <= length ? capa : length; await _outputBuffer.WriteAsync(buffer, offset, writeSize, cancellationToken); writtenCount += writeSize; if (writeSize == capa) { //ArraySegment<byte> bufSegment; //_outputBuffer.TryGetBuffer(out bufSegment); var data = _outputBuffer.ToArray(); //await _transport.WriteAsync(bufSegment.Array, cancellationToken); await _transport.WriteAsync(data, cancellationToken); _outputBuffer.SetLength(0); } } while (length - writtenCount >= _bufSize) { await _transport.WriteAsync(buffer, offset + writtenCount, _bufSize, cancellationToken); writtenCount += _bufSize; } var remain = length - writtenCount; if (remain > 0) { if (_outputBuffer.Capacity < _bufSize) { _outputBuffer.Capacity = _bufSize; } await _outputBuffer.WriteAsync(buffer, offset + writtenCount, remain, cancellationToken); } }
public override async Task FlushAsync(CancellationToken cancellationToken) { CheckNotDisposed(); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } //ArraySegment<byte> bufSegment; //_writeBuffer.TryGetBuffer(out bufSegment); //var buf = bufSegment.Array; var buf = _writeBuffer.ToArray(); //var len = (int)_writeBuffer.Length; var dataLen = (int)_writeBuffer.Length - HeaderSize; if (dataLen < 0) { throw new InvalidOperationException(); // logic error actually } // Inject message header into the reserved buffer space EncodeFrameSize(dataLen, buf); // Send the entire message at once await _transport.WriteAsync(buf, cancellationToken); InitWriteBuffer(); await _transport.FlushAsync(cancellationToken); }