async ValueTask <int> ReadCore(int count, bool async, CancellationToken cancellationToken = default)
        {
            if (_isConsumed)
            {
                return(0);
            }

            if (_leftToReadInDataMsg == 0)
            {
                IBackendMessage msg;
                try
                {
                    // We've consumed the current DataMessage (or haven't yet received the first),
                    // read the next message
                    msg = await _connector.ReadMessage(async, cancellationToken);
                }
                catch
                {
                    Cleanup();
                    throw;
                }

                switch (msg.Code)
                {
                case BackendMessageCode.CopyData:
                    _leftToReadInDataMsg = ((CopyDataMessage)msg).Length;
                    break;

                case BackendMessageCode.CopyDone:
                    Expect <CommandCompleteMessage>(await _connector.ReadMessage(async, cancellationToken), _connector);
                    Expect <ReadyForQueryMessage>(await _connector.ReadMessage(async, cancellationToken), _connector);
                    _isConsumed = true;
                    return(0);

                default:
                    throw _connector.UnexpectedMessageReceived(msg.Code);
                }
            }

            Debug.Assert(_leftToReadInDataMsg > 0);

            // If our buffer is empty, read in more. Otherwise return whatever is there, even if the
            // user asked for more (normal socket behavior)
            if (_readBuf.ReadBytesLeft == 0)
            {
                await _readBuf.ReadMore(async, cancellationToken);
            }

            Debug.Assert(_readBuf.ReadBytesLeft > 0);

            var maxCount = Math.Min(_readBuf.ReadBytesLeft, _leftToReadInDataMsg);

            if (count > maxCount)
            {
                count = maxCount;
            }

            _leftToReadInDataMsg -= count;
            return(count);
        }
示例#2
0
        async Task <int> Read(byte[] buffer, int offset, int count, bool async)
        {
            CheckDisposed();
            if (!CanRead)
            {
                throw new InvalidOperationException("Stream not open for reading");
            }

            if (_isConsumed)
            {
                return(0);
            }

            if (_leftToReadInDataMsg == 0)
            {
                // We've consumed the current DataMessage (or haven't yet received the first),
                // read the next message
                var msg = await _connector.ReadMessage(async);

                switch (msg.Code)
                {
                case BackendMessageCode.CopyData:
                    _leftToReadInDataMsg = ((CopyDataMessage)msg).Length;
                    break;

                case BackendMessageCode.CopyDone:
                    Expect <CommandCompleteMessage>(await _connector.ReadMessage(async), _connector);
                    Expect <ReadyForQueryMessage>(await _connector.ReadMessage(async), _connector);
                    _isConsumed = true;
                    return(0);

                default:
                    throw _connector.UnexpectedMessageReceived(msg.Code);
                }
            }

            Debug.Assert(_leftToReadInDataMsg > 0);

            // If our buffer is empty, read in more. Otherwise return whatever is there, even if the
            // user asked for more (normal socket behavior)
            if (_readBuf.ReadBytesLeft == 0)
            {
                await _readBuf.ReadMore(async);
            }

            Debug.Assert(_readBuf.ReadBytesLeft > 0);

            var maxCount = Math.Min(_readBuf.ReadBytesLeft, _leftToReadInDataMsg);

            if (count > maxCount)
            {
                count = maxCount;
            }

            _leftToReadInDataMsg -= count;
            _readBuf.ReadBytes(buffer, offset, count);
            return(count);
        }