Exemple #1
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            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 = _connector.ReadSingleMessage();
                switch (msg.Code)
                {
                case BackendMessageCode.CopyData:
                    _leftToReadInDataMsg = ((CopyDataMessage)msg).Length;
                    break;

                case BackendMessageCode.CopyDone:
                    _connector.ReadExpecting <CommandCompleteMessage>();
                    _connector.ReadExpecting <ReadyForQueryMessage>();
                    _isConsumed = true;
                    return(0);

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

            Contract.Assume(_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 (_buf.ReadBytesLeft == 0)
            {
                _buf.ReadMore();
            }

            Contract.Assert(_buf.ReadBytesLeft > 0);

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

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

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