Beispiel #1
0
        internal T Read <T>(NpgsqlBuffer buf, int len, FieldDescription fieldDescription = null)
        {
            T result;

            var asSimpleReader = this as ISimpleTypeReader <T>;

            if (asSimpleReader != null)
            {
                buf.Ensure(len);
                result = asSimpleReader.Read(buf, len, fieldDescription);
            }
            else
            {
                var asChunkingReader = this as IChunkingTypeReader <T>;
                if (asChunkingReader == null)
                {
                    if (fieldDescription == null)
                    {
                        throw new InvalidCastException("Can't cast database type to " + typeof(T).Name);
                    }
                    throw new InvalidCastException(String.Format("Can't cast database type {0} to {1}", fieldDescription.Handler.PgName, typeof(T).Name));
                }

                asChunkingReader.PrepareRead(buf, len, fieldDescription);
                while (!asChunkingReader.Read(out result))
                {
                    buf.ReadMore();
                }
            }

            return(result);
        }
Beispiel #2
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);
        }