/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.mina.codec;

import java.io.IOException;
import java.io.InputStream;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.InvalidMarkException;
import java.nio.ReadOnlyBufferException;

/**
 * A proxy class used to manage ByteBuffers as if they were just a big ByteBuffer. We can add as many buffers as needed,
 * when accumulating data. From the user PoV, the methods are the very same than what we can get from ByteBuffer. <br/>
 * IoBuffer instances are *not* thread safe.
 * 
 * The IoBuffer uses a single-chained queue to handle the multiple Buffers. Thus, the sequential access is 
 * very efficient and the random access is not. It fits well the common usage of IoBuffer.
 * 
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public final class IoBuffer {
    private static final int BYTE_MASK = 0xff;

    private static final long BYTE_MASK_L = 0xffl;

    /**
     * @see ByteBuffer#allocate(int)
     */
    public static IoBuffer allocate(int capacity) {
        return wrap(ByteBuffer.allocate(capacity));
    }

    /**
     * @see ByteBuffer#allocateDirect(int)
     */
    public static IoBuffer allocateDirect(int capacity) {
        return wrap(ByteBuffer.allocateDirect(capacity));
    }

    /**
     * Build a new instance of {@link IoBuffer}
     * 
     * @return a new instance of {@link IoBuffer}
     */
    public static IoBuffer newInstance() {
        return new IoBuffer();
    }

    /**
     * @see ByteBuffer#wrap(byte[])
     */
    public static IoBuffer wrap(byte[]... arrays) {
        IoBuffer ioBuffer = new IoBuffer();
        for (byte[] array : arrays) {
            ioBuffer.add(ByteBuffer.wrap(array));
        }
        return ioBuffer;
    }

    /**
     * @see ByteBuffer#wrap(byte[], int, int)
     */
    public static IoBuffer wrap(byte[] array, int offset, int length) {
        return wrap(ByteBuffer.wrap(array, offset, length));
    }

    /**
     * Build new IoBuffer containing 
     * 
     * @param buffers
     * @return the new {@link IoBuffer}
     */
    public static IoBuffer wrap(ByteBuffer... buffers) {
        IoBuffer ioBuffer = new IoBuffer();
        for (ByteBuffer b : buffers) {
            ioBuffer.add(b);
        }
        return ioBuffer;
    }

    private ByteOrder bo = ByteOrder.BIG_ENDIAN;

    private int capacity = 0;

    private boolean direct = true;

    private BufferNode head, tail;

    /** The maximal position in the IoBuffer */
    private Pointer limit = new Pointer();

    /** The current position in the buffer */
    private Pointer mark = new Pointer();

    /** The marked position, for the next reset() */
    private Pointer position = new Pointer();

    /** If the buffer is readonly */
    private boolean readonly = false;

    private IoBuffer() {
        limit(0);
        position(0);
        mark = null;
    }

    /**
     * Add one or more ByteBuffer to the current IoBuffer
     * 
     * @param buffers
     * @return the current {@link IoBuffer}
     */
    public IoBuffer add(ByteBuffer... buffers) {
        for (ByteBuffer buffer : buffers) {
            enqueue(buffer.slice());
        }
        return this;
    }

    /**
     * @see ByteBuffer#array()
     */
    public byte[] array() {
        if (capacity == 0) {
            return new byte[0];
        }
        if (head.hasNext()) {
            throw new UnsupportedOperationException();
        }
        return head.getBuffer().array();
    }

    /**
     * @see ByteBuffer#arrayOffset()
     */
    public int arrayOffset() {
        if (capacity == 0) {
            return 0;
        }
        if (head.hasNext()) {
            throw new UnsupportedOperationException();
        }
        return head.getBuffer().arrayOffset();
    }

    /**
     * Provides an input stream which is actually reading the {@link IoBuffer}
     * instance.
     * <p>
     * Further reads on the returned inputstream move the reading head of the {@link IoBuffer}
     * instance used for it's creation</i>
     *
     * @return an input stream
     */
    public InputStream asInputStream() {
        return new InputStream() {

            @Override
            public int read() throws IOException {
                return hasRemaining() ? get() & BYTE_MASK : -1;
            }

            @Override
            public int read(byte[] b, int off, int len) throws IOException {
                if (!hasRemaining()) {
                    return -1;
                }

                int toRead = Math.min(remaining(), len);
                get(b, off, toRead);
                return toRead;
            }
        };
    }

    /**
     * @see ByteBuffer#asReadOnlyBuffer()
     */
    public IoBuffer asReadOnlyBuffer() {
        IoBuffer buffer = duplicate();
        buffer.readonly = true;
        return buffer;
    }

    /**
     * @see ByteBuffer#capacity()
     */
    public int capacity() {
        return capacity;
    }

    /**
     * @see ByteBuffer#clear()
     */
    public IoBuffer clear() {
        position = getPointerByPosition(0);
        limit = getPointerByPosition(capacity);
        mark = null;
        return this;
    }

    /**
     * @see ByteBuffer#compact()
     */
    public IoBuffer compact() {
        for (int i = 0; i < remaining(); i++) {
            put(i, get(i + position.getPosition()));
        }
        position(limit() - position());
        limit(capacity);
        mark = null;
        return this;
    }

    /**
     * Returns a copy of the current {@link IoBuffer}, with an independent copy if the postion, limit and mark.
     * 
     * @return the copied {@link IoBuffer}
     */
    public IoBuffer duplicate() {
        IoBuffer buffer = new IoBuffer();

        for (BufferNode node = head; node != null; node = node.getNext()) {
            ByteBuffer byteBuffer = node.getBuffer().duplicate();
            byteBuffer.rewind();
            buffer.enqueue(byteBuffer);
        }
        buffer.position(position());
        buffer.limit(limit());
        buffer.mark = mark != null ? getPointerByPosition(mark.getPosition()) : null;

        buffer.readonly = readonly;
        return buffer;
    }

    private void enqueue(ByteBuffer buffer) {

        if (buffer.isReadOnly()) {
            readonly = true;
        }

        if (!buffer.isDirect()) {
            direct = false;
        }
        if (buffer.remaining() > 0) {
            BufferNode newnode = new BufferNode(buffer, capacity);
            capacity += buffer.capacity();

            if (head == null) {
                head = newnode;
                position = getPointerByPosition(0);
            } else {
                tail.setNext(newnode);
            }
            tail = newnode;

            limit = getPointerByPosition(capacity);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object ob) {
        if (this == ob) {
            return true;
        }
        if (!(ob instanceof IoBuffer)) {
            return false;
        }
        IoBuffer that = (IoBuffer) ob;
        if (this.remaining() != that.remaining()) {
            return false;
        }
        int p = this.position();
        int q = that.position();
        while (this.hasRemaining() && that.hasRemaining()) {
            if (this.get() != that.get()) {
                this.position(p);
                that.position(q);
                return false;
            }

        }
        this.position(p);
        that.position(q);
        return true;
    }

    /**
     * Extends the current IoBuffer capacity.
     * 
     * @param size the number of bytes to extend the current IoBuffer 
     * @return the current {@link IoBuffer}
     */
    public IoBuffer extend(int size) {
        ByteBuffer extension = isDirect() ? ByteBuffer.allocateDirect(size) : ByteBuffer.allocate(size);
        add(extension);
        return this;
    }

    /**
     * @see ByteBuffer#flip()
     */
    public IoBuffer flip() {
        limit = position;
        position = getPointerByPosition(0);
        return this;
    }

    /**
     * @see ByteBuffer#get()
     */
    public byte get() {
        if (!hasRemaining()) {
            throw new BufferUnderflowException();
        }

        return get(position);
    }

    /**
     * @see ByteBuffer#get(byte[])
     */
    public IoBuffer get(byte[] dst) {
        get(dst, 0, dst.length);
        return this;
    }

    /**
     * @see ByteBuffer#get(byte[], int,int)
     */
    public IoBuffer get(byte[] dst, int offset, int length) {
        if (remaining() < length) {
            throw new BufferUnderflowException();
        }
        int remainsToCopy = length;
        int currentOffset = offset;

        while (remainsToCopy > 0) {
            position.updatePos();
            position.getNode().getBuffer().position(position.getPositionInNode());
            ByteBuffer currentBuffer = position.getNode().getBuffer();
            int blocksize = Math.min(remainsToCopy, currentBuffer.remaining());
            position.getNode().getBuffer().get(dst, currentOffset, blocksize);

            currentOffset += blocksize;
            remainsToCopy -= blocksize;

            position.incrementPosition(blocksize);

            position.getNode().getBuffer().position(0);
        }
        return this;
    }

    /**
     * @see ByteBuffer#get(int)
     */
    public byte get(int index) {
        if (index >= limit.getPosition()) {
            throw new IndexOutOfBoundsException();
        }
        return get(getPointerByPosition(index));
    }

    private byte get(Pointer pos) {
        pos.updatePos();
        byte b = pos.getNode().getBuffer().get(pos.getPositionInNode());
        pos.incrPosition();
        return b;
    }

    /**
     * @see ByteBuffer#getChar()
     */
    public char getChar() {
        return getChar(position);
    }

    /**
     * @see ByteBuffer#getChar(int)
     */
    public char getChar(int index) {
        return getChar(getPointerByPosition(index));
    }

    private char getChar(Pointer position) {
        return (char) getShort(position);
    }

    /**
    * @see ByteBuffer#getDouble()
    */
    public double getDouble() {
        return Double.longBitsToDouble(getLong());
    }

    /**
     * @see ByteBuffer#getDouble(int)
     */
    public double getDouble(int index) {
        return getDouble(getPointerByPosition(index));
    }

    private double getDouble(Pointer pos) {
        return Double.longBitsToDouble(getLong(pos));
    }

    /**
     * @see ByteBuffer#getFloat()
     */
    public float getFloat() {
        return getFloat(position);
    }

    /**
     * @see ByteBuffer#getFloat(int)
     */
    public float getFloat(int index) {
        return getFloat(getPointerByPosition(index));
    }

    private float getFloat(Pointer pos) {
        return Float.intBitsToFloat(getInt(pos));
    }

    /**
     * @see ByteBuffer#getInt()
     */
    public int getInt() {
        return getInt(position);
    }

    /**
     * @see ByteBuffer#getInt(int)
     */
    public int getInt(int index) {
        return getInt(getPointerByPosition(index));
    }

    private int getInt(Pointer pos) {
        if (pos.getPosition() > capacity - Integer.SIZE / Byte.SIZE) {
            throw new BufferUnderflowException();
        }

        int out = 0;
        for (int i = 0; i < Integer.SIZE; i += Byte.SIZE) {
            out |= (get(pos) & BYTE_MASK) << (bo == ByteOrder.BIG_ENDIAN ? (Integer.SIZE - Byte.SIZE) - i : i);
        }
        return out;
    }

    /**
     * @see ByteBuffer#getLong()
     */
    public long getLong() {
        return getLong(position);
    }

    /**
     * @see ByteBuffer#getLong(int)
     */
    public long getLong(int index) {
        return getLong(getPointerByPosition(index));
    }

    private long getLong(Pointer pos) {
        if (pos.getPosition() > capacity - Long.SIZE / Byte.SIZE) {
            throw new BufferUnderflowException();
        }

        long out = 0;
        for (int i = 0; i < Long.SIZE; i += Byte.SIZE) {
            out |= (get(pos) & BYTE_MASK_L) << (bo == ByteOrder.BIG_ENDIAN ? (Long.SIZE - Byte.SIZE) - i : i);
        }
        return out;
    }

    private Pointer getPointerByPosition(int pos) {
        return new Pointer(pos);
    }

    /**
     * @see ByteBuffer#getShort()
     */
    public short getShort() {
        return getShort(position);
    }

    /**
     * @see ByteBuffer#getShort(int)
     */
    public long getShort(int index) {
        return getShort(getPointerByPosition(index));
    }

    private short getShort(Pointer pos) {
        if (pos.getPosition() > capacity - Short.SIZE / Byte.SIZE) {
            throw new BufferUnderflowException();
        }
        if (bo == ByteOrder.BIG_ENDIAN) {
            return (short) ((get(pos) & BYTE_MASK) << Byte.SIZE | (get(pos) & BYTE_MASK));
        } else {
            return (short) ((get(pos) & BYTE_MASK) | (get(pos) & BYTE_MASK) << Byte.SIZE);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        int hash = 0;
        Pointer oldPos = position.duplicate();
        while (hasRemaining()) {
            hash *= 31; // NOSONAR, standard way of hashing
            hash += get();
        }
        position = oldPos;
        return hash;
    }

    /**
     * @see ByteBuffer#hasRemaining()
     */
    public boolean hasRemaining() {
        return remaining() > 0;
    }

    /**
     * @see ByteBuffer#isDirect()
     */
    public boolean isDirect() {
        return direct;
    }

    /**
     * @see ByteBuffer#isReadOnly()
     */
    public boolean isReadOnly() {
        return readonly;
    }

    /**
     * @see ByteBuffer#limit()
     */
    public int limit() {
        return limit.getPosition();
    }

    /**
     * @see ByteBuffer#limit(int)
     */
    public void limit(int newLimit) {
        this.limit = getPointerByPosition(newLimit);
    }

    /**
     * @see ByteBuffer#mark()
     */
    public void mark() {
        this.limit = position.duplicate();
    }

    /**
     * Returns the byte order used by this Iouffer when converting bytes from/to other primitive
     * types.
     * <p>
     * The default byte order of byte buffer is always {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
     * 
     * @return the byte order used by this IoBuffer when converting bytes from/to other primitive types.
     * 
     * @see ByteBuffer#order()
     */
    public ByteOrder order() {
        return bo;
    }

    /**
     * Sets the byte order of this IoBuffer.
     * 
     * @param byteOrder the byte order to set. If {@code null} then the order will be {@link ByteOrder#LITTLE_ENDIAN
     *        LITTLE_ENDIAN}.
     * @return this IoBuffer.
     * @see ByteBuffer#order(ByteOrder)
     */
    public IoBuffer order(ByteOrder bo) {
        this.bo = bo != null ? bo : ByteOrder.LITTLE_ENDIAN;

        return this;
    }

    /**
     * @see ByteBuffer#position()
     */
    public int position() {
        return position.getPosition();
    }

    /**
     * @see ByteBuffer#position(int)
     */
    public void position(int newPosition) {
        if (newPosition > limit() || newPosition < 0) {
            throw new IllegalArgumentException();
        }

        if (mark != null && mark.getPosition() > newPosition) {
            mark = null;
        }

        this.position.setPosition(newPosition);
    }

    /**
     * @see ByteBuffer#put(byte)
     */
    public IoBuffer put(byte b) {
        if (readonly) {
            throw new ReadOnlyBufferException();
        }
        if (position.getPosition() >= limit.getPosition()) {
            throw new BufferUnderflowException();
        }

        put(position, b);
        return this;
    }

    /**
     * @see ByteBuffer#put(byte[])
     */
    public IoBuffer put(byte[] src) {
        put(src, 0, src.length);
        return this;
    }

    /**
     * @see ByteBuffer#put(ByteBuffer)
     */
    public IoBuffer put(ByteBuffer src) {

        if (remaining() < src.remaining()) {
            throw new BufferOverflowException();
        }
        if (isReadOnly()) {
            throw new ReadOnlyBufferException();
        }

        while (src.hasRemaining()) {
            put(src.get());
        }

        return this;
    }

    /**
     * @see ByteBuffer#put(ByteBuffer)
     */
    public IoBuffer put(IoBuffer src) {
        if (src == this) { // NOSONAR, checking the instance
            throw new IllegalArgumentException();
        }

        if (remaining() < src.remaining()) {
            throw new BufferOverflowException();
        }
        if (isReadOnly()) {
            throw new ReadOnlyBufferException();
        }

        while (src.hasRemaining()) {
            put(src.get());
        }

        return this;
    }

    /**
     * @see ByteBuffer#put(byte[], int, int)
     */
    public IoBuffer put(byte[] src, int offset, int length) {
        if (readonly) {
            throw new ReadOnlyBufferException();
        }
        if (remaining() < length) {
            throw new BufferUnderflowException();
        }

        int remainsToCopy = length;
        int currentOffset = offset;
        position.getNode().getBuffer().position(position.getPositionInNode());
        while (remainsToCopy > 0) {
            position.updatePos();

            ByteBuffer currentBuffer = position.getNode().getBuffer();
            int blocksize = Math.min(remainsToCopy, currentBuffer.remaining());
            position.getNode().getBuffer().put(src, currentOffset, blocksize);

            currentOffset += blocksize;
            remainsToCopy -= blocksize;

            position.incrementPosition(blocksize);
        }
        position.getNode().getBuffer().position(0);
        return this;
    }

    /**
     * @see ByteBuffer#put(int, byte)
     */
    public IoBuffer put(int index, byte value) {
        if (index >= limit.getPosition()) {
            throw new IndexOutOfBoundsException();
        }
        Pointer p = getPointerByPosition(index);
        put(p, value);
        return this;
    }

    private IoBuffer put(Pointer pos, byte b) {
        pos.updatePos();
        pos.getNode().getBuffer().put(pos.getPositionInNode(), b);
        pos.incrPosition();
        return this;
    }

    /**
     * @see ByteBuffer#putChar(char)
     */
    public IoBuffer putChar(char value) {
        return putChar(position, value);
    }

    /**
     * @see ByteBuffer#putChar(int, char)
     */
    public IoBuffer putChar(int index, char value) {
        return putChar(getPointerByPosition(index), value);
    }

    private IoBuffer putChar(Pointer index, char value) {
        return putShort(index, (short) value);
    }

    /**
     * @see ByteBuffer#putDouble(double)
     */
    public IoBuffer putDouble(double value) {
        return putDouble(position, value);
    }

    /**
     * @see ByteBuffer#putDouble(int, double)
     */
    public IoBuffer putDouble(int index, double value) {
        return putDouble(getPointerByPosition(index), value);
    }

    private IoBuffer putDouble(Pointer pos, double value) {
        return putLong(pos, Double.doubleToLongBits(value));
    }

    /**
     * @see ByteBuffer#putFloat(float)
     */
    public IoBuffer putFloat(float value) {
        return putFloat(position, value);
    }

    /**
     * @see ByteBuffer#putFloat(int, float)
     */
    public IoBuffer putFloat(int index, float value) {
        return putFloat(getPointerByPosition(index), value);
    }

    private IoBuffer putFloat(Pointer pointer, float value) {
        return putInt(pointer, Float.floatToIntBits(value));
    }

    /**
     * @see ByteBuffer#putInt(int)
     */
    public IoBuffer putInt(int value) {
        return putInt(position, value);
    }

    /**
     * @see ByteBuffer#putInt(int, int)
     */
    public IoBuffer putInt(int index, int value) {
        return putInt(getPointerByPosition(index), value);
    }

    private IoBuffer putInt(Pointer pointer, int value) {
        if (position.getPosition() > pointer.getPosition()
                || pointer.getPosition() > limit.getPosition() - Integer.SIZE / Byte.SIZE) {
            throw new BufferUnderflowException();
        }
        for (int i = 0; i < Integer.SIZE; i += Byte.SIZE) {
            put(pointer, (byte) (value >> (bo == ByteOrder.BIG_ENDIAN ? (Integer.SIZE - Byte.SIZE) - i : i)));
        }
        return this;
    }

    /**
     * @see ByteBuffer#putLong(int, int)
     */
    public IoBuffer putLong(int index, long value) {
        return putLong(getPointerByPosition(index), value);
    }

    /**
     * @see ByteBuffer#putLong(long)
     */
    public IoBuffer putLong(long value) {
        return putLong(position, value);
    }

    private IoBuffer putLong(Pointer pointer, long value) {
        if (position.getPosition() > pointer.getPosition()
                || pointer.getPosition() > limit.getPosition() - Long.SIZE / Byte.SIZE) {
            throw new BufferUnderflowException();
        }
        for (int i = 0; i < Long.SIZE; i += Byte.SIZE) {
            put(pointer, (byte) (value >> (bo == ByteOrder.BIG_ENDIAN ? (Long.SIZE - Byte.SIZE) - i : i)));
        }

        return this;
    }

    /**
     * @see ByteBuffer#putShort(int, short)
     */
    public IoBuffer putShort(int index, short value) {
        return putShort(getPointerByPosition(index), value);
    }

    private IoBuffer putShort(Pointer pointer, short value) {
        if (position.getPosition() > pointer.getPosition()
                || pointer.getPosition() > limit.getPosition() - Short.SIZE / Byte.SIZE) {
            throw new BufferUnderflowException();
        }
        for (int i = 0; i < Short.SIZE; i += Byte.SIZE) {
            put(pointer, (byte) (value >> (bo == ByteOrder.BIG_ENDIAN ? Byte.SIZE - i : i)));
        }
        return this;
    }

    /**
     * @see ByteBuffer#putShort(short)
     */
    public IoBuffer putShort(short value) {
        return putShort(position, value);
    }

    /**
     * @see ByteBuffer#remaining()
     */
    public int remaining() {
        return limit() - position();
    }

    /**
     * @see ByteBuffer#reset()
     */
    public IoBuffer reset() {
        if (mark == null) {
            throw new InvalidMarkException();
        }
        position = mark.duplicate();
        return this;
    }

    /**
     * @see ByteBuffer#rewind()
     */
    public IoBuffer rewind() {
        position(0);
        mark = getPointerByPosition(-1);
        return this;
    }

    /**
     * @see ByteBuffer#slice()
     */
    public IoBuffer slice() {
        position.updatePos();
        IoBuffer out = new IoBuffer();
        out.order(order());

        position.getNode().getBuffer().position(position.getPositionInNode());
        if (hasRemaining()) {
            tail.getBuffer().limit(limit.getPositionInNode());
            for (BufferNode node = position.getNode(); node != limit.getNode(); node = node.getNext()) {
                if (node != head) { //NOSONAR, check if instances are the same. 
                    node.getBuffer().position(0);
                }
                out.add(node.getBuffer());
            }
            if (tail != head) { //NOSONAR, check if instances are the same. 
                tail.getBuffer().position(0);
            }
            out.add(tail.getBuffer().slice());
            tail.getBuffer().limit(tail.getBuffer().capacity());
        }
        position.getNode().getBuffer().position(0);

        return out;
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append(getClass().getName());
        sb.append("[pos=");
        sb.append(position());
        sb.append(" lim=");
        sb.append(limit());
        sb.append(" cap=");
        sb.append(capacity());
        sb.append("]");
        return sb.toString();
    }

    private static final class BufferNode {
        private final ByteBuffer buffer;

        private BufferNode next;

        private final int offset;

        public BufferNode(ByteBuffer buffer, int offset) {
            this.buffer = buffer;
            this.offset = offset;
        }

        public ByteBuffer getBuffer() {
            return buffer;
        }

        public BufferNode getNext() {
            return next;
        }

        public boolean hasNext() {
            return next != null;
        }

        public void setNext(BufferNode next) {
            this.next = next;
        }

        @Override
        public String toString() {
            return "BufferNode [offset=" + offset + ", buffer=" + buffer + "]";
        }
    }

    private final class Pointer {

        private BufferNode node;

        private int positionInBuffer;

        public Pointer(int position) {
            this();

            setPosition(position);
        }

        public Pointer() {
        }

        public Pointer duplicate() {
            return new Pointer(getPosition());
        }

        private BufferNode getBufferNodeByPosition(int pos) {
            if (head == null) {
                return null;
            }
            BufferNode currentNode = head;
            int rpos = pos;
            while (rpos >= currentNode.getBuffer().capacity() && currentNode.hasNext()) {

                rpos -= currentNode.getBuffer().capacity();
                currentNode = currentNode.getNext();
            }

            return currentNode;
        }

        public BufferNode getNode() {
            return node;
        }

        public int getPosition() {
            return positionInBuffer + (node == null ? 0 : node.offset);
        }

        public int getPositionInNode() {
            return positionInBuffer;
        }

        public void incrPosition() {
            incrementPosition(1);
        }

        public void setPosition(int newPosition) {
            if (node == null || node.offset < newPosition) {

                node = getBufferNodeByPosition(newPosition);

            } else {
                node = head;
            }
            positionInBuffer = node == null ? 0 : newPosition - node.offset;
            updatePos();
        }

        public void incrementPosition(int positionIncrement) {
            positionInBuffer += positionIncrement;
        }

        @Override
        public String toString() {
            StringBuffer sb = new StringBuffer();
            sb.append(getClass().getName());
            sb.append("[pos=");
            sb.append(getPosition());
            sb.append(", node=");
            sb.append(getNode());
            sb.append("]");
            return sb.toString();
        }

        public void updatePos() {
            while (node != null && positionInBuffer >= node.getBuffer().capacity() && node.hasNext()) {
                positionInBuffer -= node.getBuffer().capacity();
                node = node.getNext();
            }
        }
    }
}