コード例 #1
0
        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);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
        }