Pchp.Library.Streams.PhpStream.Seek C# (CSharp) Method

Seek() public method

Sets the read/write pointer in the stream to a new position.
public Seek ( int offset, SeekOrigin whence ) : bool
offset int The offset from the position denoted by .
whence SeekOrigin One of the flags.
return bool
        public bool Seek(int offset, SeekOrigin whence)
        {
            if (!CanSeek)
            {
                PhpException.Throw(PhpError.Warning, ErrResources.wrapper_op_unsupported, "Seek");
                return false;
            }

            // This is supported by any stream.
            int current = Tell();
            int newpos = -1;
            if (whence == SeekOrigin.Begin) newpos = offset;
            else if (whence == SeekOrigin.Current) newpos = current + offset;
            else if (whence == SeekOrigin.End)
            {
                int len = RawLength();
                if (len >= 0) newpos = len + offset;
            }

            switch (CurrentAccess)
            {
                case FileAccess.ReadWrite:
                    // Stream not R/W accessed yet. Prepare location and offset.
                    return SeekInternal(offset, current, whence);

                case FileAccess.Read:
                    // Maybe we will be able to seek inside the buffers.
                    if ((newpos >= readOffset) && (newpos < readOffset + ReadBufferLength))
                    {
                        int streamPosition = readOffset + ReadPosition;
                        if (newpos > streamPosition)
                        {
                            // Seek forward
                            // This asserts that ReadBufferLength > 0.
                            int len = readBuffers.Peek().Length;
                            while (newpos - readOffset >= len)
                            {
                                DropReadBuffer();
                                len = readBuffers.Peek().Length;
                            }
                            Debug.Assert(readBuffers.Count > 0);

                            // All superfluous buffers are dropped, seek in the head one.
                            readPosition = newpos - readOffset;
                        }
                        else if (newpos < streamPosition)
                        {
                            // The required position is still in the first buffer
                            //. Debug.Assert(streamPosition == readOffset + readPosition);
                            readPosition = newpos - readOffset;
                        }
                    }
                    else
                    {
                        // Drop all the read buffers and proceed to the actual seeking.
                        readBuffers = null;

                        // Notice that for a filtered stream, seeking is not a good idea
                        if (IsReadFiltered)
                        {
                            PhpException.Throw(PhpError.Notice,
                                ErrResources.stream_seek_filtered, (textReadFilter != null) ? "text" : "filtered");
                        }
                        return SeekInternal(offset, current, whence);
                    }
                    break;

                case FileAccess.Write:
                    // The following does not currently work since other methods do not take unempty writebuffer into account

                    //// Maybe we can seek inside of the buffer but we allow only backward skips.
                    //if ((newpos >= writeOffset) && (newpos < writeOffset + writePosition))
                    //{
                    //    // We are inside the current buffer, great.
                    //    writePosition = newpos - writeOffset;
                    //}
                    //else
                    //{

                    // Flush write buffers and proceed to the default handling.
                    FlushWriteBuffer();

                    // Notice that for a filtered stream, seeking is not a good idea
                    if (IsWriteFiltered)
                    {
                        PhpException.Throw(PhpError.Notice,
                            ErrResources.stream_seek_filtered, (textWriteFilter != null) ? "text" : "filtered");
                    }
                    return SeekInternal(offset, current, whence);
            }
            return true;
            // CHECKME: [PhpStream.Seek]
        }