/*
 *  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.common;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

import org.apache.mina.common.support.ByteBufferHexDumper;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

/**
 * A byte buffer used by MINA applications.
 * <p>
 * This is a replacement for {@link java.nio.ByteBuffer}. Please refer to
 * {@link java.nio.ByteBuffer} and {@link java.nio.Buffer} documentation for
 * usage.  MINA does not use NIO {@link java.nio.ByteBuffer} directly for two
 * reasons:
 * <ul>
 * <li>It doesn't provide useful getters and putters such as
 * <code>fill</code>, <code>get/putString</code>, and
 * <code>get/putAsciiInt()</code> enough.</li>
 * <li>It is hard to distinguish if the buffer is created from MINA buffer
 * pool or not.  MINA have to return used buffers back to pool.</li>
 * <li>It is difficult to write variable-length data due to its fixed
 * capacity</li>
 * </ul>
 * </p>
 *
 * <h2>Allocation</h2>
 * <p>
 * You can get a heap buffer from buffer pool:
 * <pre>
 * ByteBuffer buf = ByteBuffer.allocate(1024, false);
 * </pre>
 * you can also get a direct buffer from buffer pool:
 * <pre>
 * ByteBuffer buf = ByteBuffer.allocate(1024, true);
 * </pre>
 * or you can let MINA choose:
 * <pre>
 * ByteBuffer buf = ByteBuffer.allocate(1024);
 * </pre>
 * </p>
 *
 * <h2>Acquire/Release</h2>
 * <p>
 * <b>Please note that you never need to release the allocated buffer</b>
 * because MINA will release it automatically when:
 * <ul>
 * <li>You pass the buffer by calling {@link IoSession#write(Object)}.</li>
 * <li>You pass the buffer by calling {@link IoFilter.NextFilter#filterWrite(IoSession,IoFilter.WriteRequest)}.</li>
 * <li>You pass the buffer by calling {@link ProtocolEncoderOutput#write(ByteBuffer)}.</li>
 * </ul>
 * And, you don't need to release any {@link ByteBuffer} which is passed as a parameter
 * of {@link IoHandler#messageReceived(IoSession, Object)} method.  They are released
 * automatically when the method returns.
 * <p>
 * You have to release buffers manually by calling {@link #release()} when:
 * <ul>
 * <li>You allocated a buffer, but didn't pass the buffer to any of two methods above.</li>
 * <li>You called {@link #acquire()} to prevent the buffer from being released.</li>
 * </ul>
 * </p>
 *
 * <h2>Wrapping existing NIO buffers and arrays</h2>
 * <p>
 * This class provides a few <tt>wrap(...)</tt> methods that wraps
 * any NIO buffers and byte arrays.  Wrapped MINA buffers are not returned
 * to the buffer pool by default to prevent unexpected memory leakage by default.
 * In case you want to make it pooled, you can call {@link #setPooled(boolean)}
 * with <tt>true</tt> flag to enable pooling.
 *
 * <h2>AutoExpand</h2>
 * <p>
 * Writing variable-length data using NIO <tt>ByteBuffers</tt> is not really
 * easy, and it is because its size is fixed.  MINA <tt>ByteBuffer</tt>
 * introduces <tt>autoExpand</tt> property.  If <tt>autoExpand</tt> property
 * is true, you never get {@link BufferOverflowException} or
 * {@link IndexOutOfBoundsException} (except when index is negative).
 * It automatically expands its capacity and limit value.  For example:
 * <pre>
 * String greeting = messageBundle.getMessage( "hello" );
 * ByteBuffer buf = ByteBuffer.allocate( 16 );
 * // Turn on autoExpand (it is off by default)
 * buf.setAutoExpand( true );
 * buf.putString( greeting, utf8encoder );
 * </pre>
 * NIO <tt>ByteBuffer</tt> is reallocated by MINA <tt>ByteBuffer</tt> behind
 * the scene if the encoded data is larger than 16 bytes.  Its capacity will
 * increase by two times, and its limit will increase to the last position
 * the string is written.
 * </p>
 *
 * <h2>Derived Buffers</h2>
 * <p>
 * Derived buffers are the buffers which were created by
 * {@link #duplicate()}, {@link #slice()}, or {@link #asReadOnlyBuffer()}.
 * They are useful especially when you broadcast the same messages to
 * multiple {@link IoSession}s.  Please note that the derived buffers are
 * neither pooled nor auto-expandable.  Trying to expand a derived buffer will
 * raise {@link IllegalStateException}.
 * </p>
 *
 * <h2>Changing Buffer Allocation and Management Policy</h2>
 * <p>
 * MINA provides a {@link ByteBufferAllocator} interface to let you override
 * the default buffer management behavior.  There are two allocators provided
 * out-of-the-box:
 * <ul>
 * <li>{@link PooledByteBufferAllocator} (Default)</li>
 * <li>{@link SimpleByteBufferAllocator}</li>
 * </ul>
 * You can change the allocator by calling {@link #setAllocator(ByteBufferAllocator)}.
 * </p>
 *
 * @author The Apache Directory Project (mina-dev@directory.apache.org)
 * @version $Rev$, $Date$
 * @noinspection StaticNonFinalField
 * @see ByteBufferAllocator
 */
public abstract class ByteBuffer implements Comparable
{
    private static ByteBufferAllocator allocator = new PooledByteBufferAllocator();

    private static boolean useDirectBuffers = true;

    /**
     * Returns the current allocator which manages the allocated buffers.
     */
    public static ByteBufferAllocator getAllocator()
    {
        return allocator;
    }

    /**
     * Changes the current allocator with the specified one to manage
     * the allocated buffers from now.
     */
    public static void setAllocator( ByteBufferAllocator newAllocator )
    {
        if( newAllocator == null )
        {
            throw new NullPointerException( "allocator" );
        }

        ByteBufferAllocator oldAllocator = allocator;

        allocator = newAllocator;

        if( null != oldAllocator )
        {
            oldAllocator.dispose();
        }
    }

    public static boolean isUseDirectBuffers()
    {
        return useDirectBuffers;
    }

    public static void setUseDirectBuffers( boolean useDirectBuffers )
    {
        ByteBuffer.useDirectBuffers = useDirectBuffers;
    }

    /**
     * Returns the direct or heap buffer which is capable of the specified
     * size.  This method tries to allocate direct buffer first, and then
     * tries heap buffer if direct buffer memory is exhausted.  Please use
     * {@link #allocate(int, boolean)} to allocate buffers of specific type.
     *
     * @param capacity the capacity of the buffer
     */
    public static ByteBuffer allocate( int capacity )
    {
        if( useDirectBuffers )
        {
            try
            {
                // first try to allocate direct buffer
                return allocate( capacity, true );
            }
            catch( OutOfMemoryError e )
            {
                // fall through to heap buffer
            }
        }

        return allocate( capacity, false );
    }

    /**
     * Returns the buffer which is capable of the specified size.
     *
     * @param capacity the capacity of the buffer
     * @param direct   <tt>true</tt> to get a direct buffer,
     *                 <tt>false</tt> to get a heap buffer.
     */
    public static ByteBuffer allocate( int capacity, boolean direct )
    {
        return allocator.allocate( capacity, direct );
    }

    /**
     * Wraps the specified NIO {@link java.nio.ByteBuffer} into MINA buffer.
     */
    public static ByteBuffer wrap( java.nio.ByteBuffer nioBuffer )
    {
        return allocator.wrap( nioBuffer );
    }

    /**
     * Wraps the specified byte array into MINA heap buffer.
     */
    public static ByteBuffer wrap( byte[] byteArray )
    {
        return wrap( java.nio.ByteBuffer.wrap( byteArray ) );
    }

    /**
     * Wraps the specified byte array into MINA heap buffer.
     * Please note that MINA buffers are going to be pooled, and
     * therefore there can be waste of memory if you wrap
     * your byte array specifying <tt>offset</tt> and <tt>length</tt>.
     */
    public static ByteBuffer wrap( byte[] byteArray, int offset, int length )
    {
        return wrap( java.nio.ByteBuffer.wrap( byteArray, offset, length ) );
    }

    protected ByteBuffer()
    {
    }

    /**
     * Increases the internal reference count of this buffer to defer
     * automatic release.  You have to invoke {@link #release()} as many
     * as you invoked this method to release this buffer.
     *
     * @throws IllegalStateException if you attempt to acquire already
     *                               released buffer.
     */
    public abstract void acquire();

    /**
     * Releases the specified buffer to buffer pool.
     *
     * @throws IllegalStateException if you attempt to release already
     *                               released buffer.
     */
    public abstract void release();

    /**
     * Returns the underlying NIO buffer instance.
     */
    public abstract java.nio.ByteBuffer buf();

    /**
     * @see java.nio.ByteBuffer#isDirect()
     */
    public abstract boolean isDirect();
    
    /**
     * @see java.nio.ByteBuffer#isReadOnly()
     */
    public abstract boolean isReadOnly();

    /**
     * @see java.nio.ByteBuffer#capacity()
     */
    public abstract int capacity();
    
    /**
     * Changes the capacity of this buffer.
     */
    public abstract ByteBuffer capacity( int newCapacity );
    
    /**
     * Returns <tt>true</tt> if and only if <tt>autoExpand</tt> is turned on.
     */
    public abstract boolean isAutoExpand();

    /**
     * Turns on or off <tt>autoExpand</tt>.
     */
    public abstract ByteBuffer setAutoExpand( boolean autoExpand );

    /**
     * Changes the capacity and limit of this buffer so this buffer get
     * the specified <tt>expectedRemaining</tt> room from the current position.
     * This method works even if you didn't set <tt>autoExpand</tt> to
     * <tt>true</tt>.
     */
    public ByteBuffer expand( int expectedRemaining )
    {
        return expand( position(), expectedRemaining );
    }
    
    /**
     * Changes the capacity and limit of this buffer so this buffer get
     * the specified <tt>expectedRemaining</tt> room from the specified
     * <tt>pos</tt>.
     * This method works even if you didn't set <tt>autoExpand</tt> to
     * <tt>true</tt>.
     */
    public abstract ByteBuffer expand( int pos, int expectedRemaining );

    /**
     * Returns <tt>true</tt> if and only if this buffer is returned back
     * to the buffer pool when released.
     * <p>
     * The default value of this property is <tt>true</tt> if and only if you
     * allocated this buffer using {@link #allocate(int)} or {@link #allocate(int, boolean)},
     * or <tt>false</tt> otherwise. (i.e. {@link #wrap(byte[])}, {@link #wrap(byte[], int, int)},
     * and {@link #wrap(java.nio.ByteBuffer)})
     */
    public abstract boolean isPooled();

    /**
     * Sets whether this buffer is returned back to the buffer pool when released.
     * <p>
     * The default value of this property is <tt>true</tt> if and only if you
     * allocated this buffer using {@link #allocate(int)} or {@link #allocate(int, boolean)},
     * or <tt>false</tt> otherwise. (i.e. {@link #wrap(byte[])}, {@link #wrap(byte[], int, int)},
     * and {@link #wrap(java.nio.ByteBuffer)})
     */
    public abstract void setPooled( boolean pooled );

    /**
     * @see java.nio.Buffer#position()
     */
    public abstract int position();

    /**
     * @see java.nio.Buffer#position(int)
     */
    public abstract ByteBuffer position( int newPosition );
    
    /**
     * @see java.nio.Buffer#limit()
     */
    public abstract int limit();

    /**
     * @see java.nio.Buffer#limit(int)
     */
    public abstract ByteBuffer limit( int newLimit );

    /**
     * @see java.nio.Buffer#mark()
     */
    public abstract ByteBuffer mark();
    
    /**
     * Returns the position of the current mark.  This method returns <tt>-1</tt> if no
     * mark is set.
     */
    public abstract int markValue();

    /**
     * @see java.nio.Buffer#reset()
     */
    public abstract ByteBuffer reset();
    
    /**
     * @see java.nio.Buffer#clear()
     */
    public abstract ByteBuffer clear();
    
    /**
     * Clears this buffer and fills its content with <tt>NUL</tt>.
     * The position is set to zero, the limit is set to the capacity,
     * and the mark is discarded.
     */
    public ByteBuffer sweep()
    {
        clear();
        return fillAndReset( remaining() );
    }

    /**
     * Clears this buffer and fills its content with <tt>value</tt>.
     * The position is set to zero, the limit is set to the capacity,
     * and the mark is discarded.
     */
    public ByteBuffer sweep( byte value )
    {
        clear();
        return fillAndReset( value, remaining() );
    }

    /**
     * @see java.nio.Buffer#flip()
     */
    public abstract ByteBuffer flip();

    /**
     * @see java.nio.Buffer#rewind()
     */
    public abstract ByteBuffer rewind();

    /**
     * @see java.nio.Buffer#remaining()
     */
    public int remaining()
    {
        return limit() - position();
    }

    /**
     * @see java.nio.Buffer#hasRemaining()
     */
    public boolean hasRemaining()
    {
        return remaining() > 0;
    }

    /**
     * @see java.nio.ByteBuffer#duplicate()
     */
    public abstract ByteBuffer duplicate();

    /**
     * @see java.nio.ByteBuffer#slice()
     */
    public abstract ByteBuffer slice();

    /**
     * @see java.nio.ByteBuffer#asReadOnlyBuffer()
     */
    public abstract ByteBuffer asReadOnlyBuffer();

    /**
     * @see java.nio.ByteBuffer#array()
     */
    public abstract byte[] array();

    /**
     * @see java.nio.ByteBuffer#arrayOffset()
     */
    public abstract int arrayOffset();

    /**
     * @see java.nio.ByteBuffer#get()
     */
    public abstract byte get();

    /**
     * Reads one unsigned byte as a short integer.
     */
    public short getUnsigned()
    {
        return (short)( get() & 0xff );
    }

    /**
     * @see java.nio.ByteBuffer#put(byte)
     */
    public abstract ByteBuffer put( byte b );

    /**
     * @see java.nio.ByteBuffer#get(int)
     */
    public abstract byte get( int index );

    /**
     * Reads one byte as an unsigned short integer.
     */
    public short getUnsigned( int index )
    {
        return (short)( get( index ) & 0xff );
    }

    /**
     * @see java.nio.ByteBuffer#put(int, byte)
     */
    public abstract ByteBuffer put( int index, byte b );

    /**
     * @see java.nio.ByteBuffer#get(byte[], int, int)
     */
    public abstract ByteBuffer get( byte[] dst, int offset, int length );

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

    /**
     * Writes the content of the specified <tt>src</tt> into this buffer.
     */
    public abstract ByteBuffer put( java.nio.ByteBuffer src );

    /**
     * Writes the content of the specified <tt>src</tt> into this buffer.
     */
    public ByteBuffer put( ByteBuffer src )
    {
        return put( src.buf() );
    }

    /**
     * @see java.nio.ByteBuffer#put(byte[], int, int)
     */
    public abstract ByteBuffer put( byte[] src, int offset, int length );

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

    /**
     * @see java.nio.ByteBuffer#compact()
     */
    public abstract ByteBuffer compact();

    public String toString()
    {
        StringBuffer buf = new StringBuffer();
        if( isDirect() )
        {
            buf.append( "DirectBuffer" );
        }
        else
        {
            buf.append( "HeapBuffer" );
        }
        buf.append( "[pos=" );
        buf.append( position() );
        buf.append( " lim=" );
        buf.append( limit() );
        buf.append( " cap=" );
        buf.append( capacity() );
        buf.append( ": " );
        buf.append( getHexDump() );
        buf.append( ']' );
        return buf.toString();
    }

    public int hashCode()
    {
        int h = 1;
        int p = position();
        for( int i = limit() - 1; i >= p; i -- )
        {
            h = 31 * h + get( i );
        }
        return h;
    }

    public boolean equals( Object o )
    {
        if( !( o instanceof ByteBuffer ) )
        {
            return false;
        }

        ByteBuffer that = (ByteBuffer)o;
        if( this.remaining() != that.remaining() )
        {
            return false;
        }

        int p = this.position();
        for( int i = this.limit() - 1, j = that.limit() - 1; i >= p; i --, j -- )
        {
            byte v1 = this.get( i );
            byte v2 = that.get( j );
            if( v1 != v2 )
            {
                return false;
            }
        }
        return true;
    }

    public int compareTo( Object o )
    {
        ByteBuffer that = (ByteBuffer)o;
        int n = this.position() + Math.min( this.remaining(), that.remaining() );
        for( int i = this.position(), j = that.position(); i < n; i ++, j ++ )
        {
            byte v1 = this.get( i );
            byte v2 = that.get( j );
            if( v1 == v2 )
            {
                continue;
            }
            if( v1 < v2 )
            {
                return -1;
            }

            return +1;
        }
        return this.remaining() - that.remaining();
    }

    /**
     * @see java.nio.ByteBuffer#order()
     */
    public abstract ByteOrder order();

    /**
     * @see java.nio.ByteBuffer#order(ByteOrder)
     */
    public abstract ByteBuffer order( ByteOrder bo );

    /**
     * @see java.nio.ByteBuffer#getChar()
     */
    public abstract char getChar();

    /**
     * @see java.nio.ByteBuffer#putChar(char)
     */
    public abstract ByteBuffer putChar( char value );

    /**
     * @see java.nio.ByteBuffer#getChar(int)
     */
    public abstract char getChar( int index );

    /**
     * @see java.nio.ByteBuffer#putChar(int, char)
     */
    public abstract ByteBuffer putChar( int index, char value );

    /**
     * @see java.nio.ByteBuffer#asCharBuffer()
     */
    public abstract CharBuffer asCharBuffer();

    /**
     * @see java.nio.ByteBuffer#getShort()
     */
    public abstract short getShort();

    /**
     * Reads two bytes unsigned integer.
     */
    public int getUnsignedShort()
    {
        return getShort() & 0xffff;
    }

    /**
     * @see java.nio.ByteBuffer#putShort(short)
     */
    public abstract ByteBuffer putShort( short value );

    /**
     * @see java.nio.ByteBuffer#getShort()
     */
    public abstract short getShort( int index );

    /**
     * Reads two bytes unsigned integer.
     */
    public int getUnsignedShort( int index )
    {
        return getShort( index ) & 0xffff;
    }

    /**
     * @see java.nio.ByteBuffer#putShort(int, short)
     */
    public abstract ByteBuffer putShort( int index, short value );

    /**
     * @see java.nio.ByteBuffer#asShortBuffer()
     */
    public abstract ShortBuffer asShortBuffer();

    /**
     * @see java.nio.ByteBuffer#getInt()
     */
    public abstract int getInt();

    /**
     * Reads four bytes unsigned integer.
     */
    public long getUnsignedInt()
    {
        return getInt() & 0xffffffffL;
    }

    /**
     * @see java.nio.ByteBuffer#putInt(int)
     */
    public abstract ByteBuffer putInt( int value );

    /**
     * @see java.nio.ByteBuffer#getInt(int)
     */
    public abstract int getInt( int index );

    /**
     * Reads four bytes unsigned integer.
     */
    public long getUnsignedInt( int index )
    {
        return getInt( index ) & 0xffffffffL;
    }

    /**
     * @see java.nio.ByteBuffer#putInt(int, int)
     */
    public abstract ByteBuffer putInt( int index, int value );

    /**
     * @see java.nio.ByteBuffer#asIntBuffer()
     */
    public abstract IntBuffer asIntBuffer();

    /**
     * @see java.nio.ByteBuffer#getLong()
     */
    public abstract long getLong();

    /**
     * @see java.nio.ByteBuffer#putLong(int, long)
     */
    public abstract ByteBuffer putLong( long value );

    /**
     * @see java.nio.ByteBuffer#getLong(int)
     */
    public abstract long getLong( int index );

    /**
     * @see java.nio.ByteBuffer#putLong(int, long)
     */
    public abstract ByteBuffer putLong( int index, long value );

    /**
     * @see java.nio.ByteBuffer#asLongBuffer()
     */
    public abstract LongBuffer asLongBuffer();

    /**
     * @see java.nio.ByteBuffer#getFloat()
     */
    public abstract float getFloat();

    /**
     * @see java.nio.ByteBuffer#putFloat(float)
     */
    public abstract ByteBuffer putFloat( float value );

    /**
     * @see java.nio.ByteBuffer#getFloat(int)
     */
    public abstract float getFloat( int index );

    /**
     * @see java.nio.ByteBuffer#putFloat(int, float)
     */
    public abstract ByteBuffer putFloat( int index, float value );

    /**
     * @see java.nio.ByteBuffer#asFloatBuffer()
     */
    public abstract FloatBuffer asFloatBuffer();

    /**
     * @see java.nio.ByteBuffer#getDouble()
     */
    public abstract double getDouble();

    /**
     * @see java.nio.ByteBuffer#putDouble(double)
     */
    public abstract ByteBuffer putDouble( double value );

    /**
     * @see java.nio.ByteBuffer#getDouble(int)
     */
    public abstract double getDouble( int index );

    /**
     * @see java.nio.ByteBuffer#putDouble(int, double)
     */
    public abstract ByteBuffer putDouble( int index, double value );

    /**
     * @see java.nio.ByteBuffer#asDoubleBuffer()
     */
    public abstract DoubleBuffer asDoubleBuffer();

    /**
     * Returns an {@link InputStream} that reads the data from this buffer.
     * {@link InputStream#read()} returns <tt>-1</tt> if the buffer position
     * reaches to the limit.
     */
    public InputStream asInputStream()
    {
        return new InputStream()
        {
            public int available()
            {
                return ByteBuffer.this.remaining();
            }

            public synchronized void mark( int readlimit )
            {
                ByteBuffer.this.mark();
            }

            public boolean markSupported()
            {
                return true;
            }

            public int read()
            {
                if( ByteBuffer.this.hasRemaining() )
                {
                    return ByteBuffer.this.get() & 0xff;
                }
                else
                {
                    return -1;
                }
            }

            public int read( byte[] b, int off, int len )
            {
                int remaining = ByteBuffer.this.remaining();
                if( remaining > 0 )
                {
                    int readBytes = Math.min( remaining, len );
                    ByteBuffer.this.get( b, off, readBytes );
                    return readBytes;
                }
                else
                {
                    return -1;
                }
            }

            public synchronized void reset()
            {
                ByteBuffer.this.reset();
            }

            public long skip( long n )
            {
                int bytes;
                if( n > Integer.MAX_VALUE )
                {
                    bytes = ByteBuffer.this.remaining();
                }
                else
                {
                    bytes = Math.min( ByteBuffer.this.remaining(), (int)n );
                }
                ByteBuffer.this.skip( bytes );
                return bytes;
            }
        };
    }

    /**
     * Returns an {@link OutputStream} that appends the data into this buffer.
     * Please note that the {@link OutputStream#write(int)} will throw a
     * {@link BufferOverflowException} instead of an {@link IOException}
     * in case of buffer overflow.  Please set <tt>autoExpand</tt> property by
     * calling {@link #setAutoExpand(boolean)} to prevent the unexpected runtime
     * exception.
     */
    public OutputStream asOutputStream()
    {
        return new OutputStream()
        {
            public void write( byte[] b, int off, int len )
            {
                ByteBuffer.this.put( b, off, len );
            }

            public void write( int b )
            {
                ByteBuffer.this.put( (byte)b );
            }
        };
    }

    /**
     * Returns hexdump of this buffer.
     */
    public String getHexDump()
    {
        return ByteBufferHexDumper.getHexdump( this );
    }

    ////////////////////////////////
    // String getters and putters //
    ////////////////////////////////

    /**
     * Reads a <code>NUL</code>-terminated string from this buffer using the
     * specified <code>decoder</code> and returns it.  This method reads
     * until the limit of this buffer if no <tt>NUL</tt> is found.
     */
    public String getString( CharsetDecoder decoder ) throws CharacterCodingException
    {
        if( !hasRemaining() )
        {
            return "";
        }

        boolean utf16 = decoder.charset().name().startsWith( "UTF-16" );

        int oldPos = position();
        int oldLimit = limit();
        int end;

        if( !utf16 )
        {
            while( hasRemaining() )
            {
                if( get() == 0 )
                {
                    break;
                }
            }

            end = position();
            if( end == oldLimit && get( end - 1 ) != 0 )
            {
                limit( end );
            }
            else
            {
                limit( end - 1 );
            }
        }
        else
        {
            while( remaining() >= 2 )
            {
            	boolean highZero = ( get() == 0 );
            	boolean lowZero = ( get() == 0 );
            	if( highZero && lowZero )
                {
                    break;
                }
            }

            end = position();
            if( end == oldLimit || end == oldLimit - 1 )
            {
                limit( end );
            }
            else
            {
                limit( end - 2 );
            }
        }

        position( oldPos );
        if( !hasRemaining() )
        {
            limit( oldLimit );
            position( end );
            return "";
        }
        decoder.reset();

        int expectedLength = (int)( remaining() * decoder.averageCharsPerByte() ) + 1;
        CharBuffer out = CharBuffer.allocate( expectedLength );
        for( ; ; )
        {
            CoderResult cr;
            if( hasRemaining() )
            {
                cr = decoder.decode( buf(), out, true );
            }
            else
            {
                cr = decoder.flush( out );
            }

            if( cr.isUnderflow() )
            {
                break;
            }

            if( cr.isOverflow() )
            {
                CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength );
                out.flip();
                o.put( out );
                out = o;
                continue;
            }

            if( cr.isError() )
            {
            	// Revert the buffer back to the previous state.
            	limit( oldLimit );
            	position( oldPos );
            	cr.throwException();
            }
        }

        limit( oldLimit );
        position( end );
        return out.flip().toString();
    }

    /**
     * Reads a <code>NUL</code>-terminated string from this buffer using the
     * specified <code>decoder</code> and returns it.
     *
     * @param fieldSize the maximum number of bytes to read
     */
    public String getString( int fieldSize, CharsetDecoder decoder ) throws CharacterCodingException
    {
        checkFieldSize( fieldSize );

        if( fieldSize == 0 )
        {
            return "";
        }

        if( !hasRemaining() )
        {
            return "";
        }

        boolean utf16 = decoder.charset().name().startsWith( "UTF-16" );

        if( utf16 && ( ( fieldSize & 1 ) != 0 ) )
        {
            throw new IllegalArgumentException( "fieldSize is not even." );
        }

        int oldPos = position();
        int oldLimit = limit();
        int end = position() + fieldSize;

        if( oldLimit < end )
        {
            throw new BufferUnderflowException();
        }

        int i;

        if( !utf16 )
        {
            for( i = 0; i < fieldSize; i ++ )
            {
                if( get() == 0 )
                {
                    break;
                }
            }

            if( i == fieldSize )
            {
                limit( end );
            }
            else
            {
                limit( position() - 1 );
            }
        }
        else
        {
            for( i = 0; i < fieldSize; i += 2 )
            {
            	boolean highZero = ( get() == 0 );
            	boolean lowZero = ( get() == 0 );
            	if( highZero && lowZero )
                {
                    break;
                }
            }

            if( i == fieldSize )
            {
                limit( end );
            }
            else
            {
                limit( position() - 2 );
            }
        }

        position( oldPos );
        if( !hasRemaining() )
        {
            limit( oldLimit );
            position( end );
            return "";
        }
        decoder.reset();

        int expectedLength = (int)( remaining() * decoder.averageCharsPerByte() ) + 1;
        CharBuffer out = CharBuffer.allocate( expectedLength );
        for( ; ; )
        {
            CoderResult cr;
            if( hasRemaining() )
            {
                cr = decoder.decode( buf(), out, true );
            }
            else
            {
                cr = decoder.flush( out );
            }

            if( cr.isUnderflow() )
            {
                break;
            }

            if( cr.isOverflow() )
            {
                CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength );
                out.flip();
                o.put( out );
                out = o;
                continue;
            }

            if( cr.isError() )
            {
            	// Revert the buffer back to the previous state.
            	limit( oldLimit );
            	position( oldPos );
            	cr.throwException();
            }
        }

        limit( oldLimit );
        position( end );
        return out.flip().toString();
    }

    /**
     * Writes the content of <code>in</code> into this buffer using the
     * specified <code>encoder</code>.  This method doesn't terminate
     * string with <tt>NUL</tt>.  You have to do it by yourself.
     *
     * @throws BufferOverflowException if the specified string doesn't fit
     */
    public ByteBuffer putString(
        CharSequence val, CharsetEncoder encoder ) throws CharacterCodingException
    {
        if( val.length() == 0 )
        {
            return this;
        }

        CharBuffer in = CharBuffer.wrap( val );
        encoder.reset();

        int expandedState = 0;

        for( ; ; )
        {
            CoderResult cr;
            if( in.hasRemaining() )
            {
                cr = encoder.encode( in, buf(), true );
            }
            else
            {
                cr = encoder.flush( buf() );
            }

            if( cr.isUnderflow() )
            {
                break;
            }
            if( cr.isOverflow() )
            {
                if( isAutoExpand() )
                {
                    switch( expandedState )
                    {
                        case 0:
                            autoExpand( (int)Math.ceil( in.remaining() * encoder.averageBytesPerChar() ) );
                            expandedState ++;
                            break;
                        case 1:
                            autoExpand( (int)Math.ceil( in.remaining() * encoder.maxBytesPerChar() ) );
                            expandedState ++;
                            break;
                        default:
                            throw new RuntimeException( "Expanded by " +
                                                        (int)Math.ceil( in.remaining() * encoder.maxBytesPerChar() ) +
                                                        " but that wasn't enough for '" + val + "'" );
                    }
                    continue;
                }
            }
            else
            {
                expandedState = 0;
            }
            cr.throwException();
        }
        return this;
    }

    /**
     * Writes the content of <code>in</code> into this buffer as a
     * <code>NUL</code>-terminated string using the specified
     * <code>encoder</code>.
     * <p>
     * If the charset name of the encoder is UTF-16, you cannot specify
     * odd <code>fieldSize</code>, and this method will append two
     * <code>NUL</code>s as a terminator.
     * <p>
     * Please note that this method doesn't terminate with <code>NUL</code>
     * if the input string is longer than <tt>fieldSize</tt>.
     *
     * @param fieldSize the maximum number of bytes to write
     */
    public ByteBuffer putString(
        CharSequence val, int fieldSize, CharsetEncoder encoder ) throws CharacterCodingException
    {
        checkFieldSize( fieldSize );

        if( fieldSize == 0 )
            return this;

        autoExpand( fieldSize );

        boolean utf16 = encoder.charset().name().startsWith( "UTF-16" );

        if( utf16 && ( ( fieldSize & 1 ) != 0 ) )
        {
            throw new IllegalArgumentException( "fieldSize is not even." );
        }

        int oldLimit = limit();
        int end = position() + fieldSize;

        if( oldLimit < end )
        {
            throw new BufferOverflowException();
        }

        if( val.length() == 0 )
        {
            if( !utf16 )
            {
                put( (byte)0x00 );
            }
            else
            {
                put( (byte)0x00 );
                put( (byte)0x00 );
            }
            position( end );
            return this;
        }

        CharBuffer in = CharBuffer.wrap( val );
        limit( end );
        encoder.reset();

        for( ; ; )
        {
            CoderResult cr;
            if( in.hasRemaining() )
            {
                cr = encoder.encode( in, buf(), true );
            }
            else
            {
                cr = encoder.flush( buf() );
            }

            if( cr.isUnderflow() || cr.isOverflow() )
            {
                break;
            }
            cr.throwException();
        }

        limit( oldLimit );

        if( position() < end )
        {
            if( !utf16 )
            {
                put( (byte)0x00 );
            }
            else
            {
                put( (byte)0x00 );
                put( (byte)0x00 );
            }
        }

        position( end );
        return this;
    }

    /**
     * Reads a string which has a 16-bit length field before the actual
     * encoded string, using the specified <code>decoder</code> and returns it.
     * This method is a shortcut for <tt>getPrefixedString(2, decoder)</tt>.
     */
    public String getPrefixedString( CharsetDecoder decoder ) throws CharacterCodingException
    {
        return getPrefixedString( 2, decoder );
    }

    /**
     * Reads a string which has a length field before the actual
     * encoded string, using the specified <code>decoder</code> and returns it.
     *
     * @param prefixLength the length of the length field (1, 2, or 4)
     */
    public String getPrefixedString( int prefixLength, CharsetDecoder decoder ) throws CharacterCodingException
    {
        if( !prefixedDataAvailable( prefixLength ) )
        {
            throw new BufferUnderflowException();
        }

        int fieldSize = 0;

        switch( prefixLength )
        {
            case 1:
                fieldSize = getUnsigned();
                break;
            case 2:
                fieldSize = getUnsignedShort();
                break;
            case 4:
                fieldSize = getInt();
                break;
        }

        if( fieldSize == 0 )
        {
            return "";
        }

        boolean utf16 = decoder.charset().name().startsWith( "UTF-16" );

        if( utf16 && ( ( fieldSize & 1 ) != 0 ) )
        {
            throw new BufferDataException( "fieldSize is not even for a UTF-16 string." );
        }

        int oldLimit = limit();
        int end = position() + fieldSize;

        if( oldLimit < end )
        {
            throw new BufferUnderflowException();
        }

        limit( end );
        decoder.reset();

        int expectedLength = (int)( remaining() * decoder.averageCharsPerByte() ) + 1;
        CharBuffer out = CharBuffer.allocate( expectedLength );
        for( ; ; )
        {
            CoderResult cr;
            if( hasRemaining() )
            {
                cr = decoder.decode( buf(), out, true );
            }
            else
            {
                cr = decoder.flush( out );
            }

            if( cr.isUnderflow() )
            {
                break;
            }

            if( cr.isOverflow() )
            {
                CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength );
                out.flip();
                o.put( out );
                out = o;
                continue;
            }

            cr.throwException();
        }

        limit( oldLimit );
        position( end );
        return out.flip().toString();
    }

    /**
     * Writes the content of <code>in</code> into this buffer as a
     * string which has a 16-bit length field before the actual
     * encoded string, using the specified <code>encoder</code>.
     * This method is a shortcut for <tt>putPrefixedString(in, 2, 0, encoder)</tt>.
     *
     * @throws BufferOverflowException if the specified string doesn't fit
     */
    public ByteBuffer putPrefixedString( CharSequence in, CharsetEncoder encoder ) throws CharacterCodingException
    {
        return putPrefixedString( in, 2, 0, encoder );
    }

    /**
     * Writes the content of <code>in</code> into this buffer as a
     * string which has a 16-bit length field before the actual
     * encoded string, using the specified <code>encoder</code>.
     * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, 0, encoder)</tt>.
     *
     * @param prefixLength the length of the length field (1, 2, or 4)
     *
     * @throws BufferOverflowException if the specified string doesn't fit
     */
    public ByteBuffer putPrefixedString( CharSequence in, int prefixLength, CharsetEncoder encoder )
        throws CharacterCodingException
    {
        return putPrefixedString( in, prefixLength, 0, encoder );
    }

    /**
     * Writes the content of <code>in</code> into this buffer as a
     * string which has a 16-bit length field before the actual
     * encoded string, using the specified <code>encoder</code>.
     * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)</tt>.
     *
     * @param prefixLength the length of the length field (1, 2, or 4)
     * @param padding      the number of padded <tt>NUL</tt>s (1 (or 0), 2, or 4)
     *
     * @throws BufferOverflowException if the specified string doesn't fit
     */
    public ByteBuffer putPrefixedString( CharSequence in, int prefixLength, int padding, CharsetEncoder encoder )
        throws CharacterCodingException
    {
        return putPrefixedString( in, prefixLength, padding, (byte)0, encoder );
    }

    /**
     * Writes the content of <code>in</code> into this buffer as a
     * string which has a 16-bit length field before the actual
     * encoded string, using the specified <code>encoder</code>.
     *
     * @param prefixLength the length of the length field (1, 2, or 4)
     * @param padding      the number of padded bytes (1 (or 0), 2, or 4)
     * @param padValue     the value of padded bytes
     *
     * @throws BufferOverflowException if the specified string doesn't fit
     */
    public ByteBuffer putPrefixedString( CharSequence val,
                                         int prefixLength,
                                         int padding,
                                         byte padValue,
                                         CharsetEncoder encoder ) throws CharacterCodingException
    {
        int maxLength;
        switch( prefixLength )
        {
            case 1:
                maxLength = 255;
                break;
            case 2:
                maxLength = 65535;
                break;
            case 4:
                maxLength = Integer.MAX_VALUE;
                break;
            default:
                throw new IllegalArgumentException( "prefixLength: " + prefixLength );
        }

        if( val.length() > maxLength )
        {
            throw new IllegalArgumentException( "The specified string is too long." );
        }
        if( val.length() == 0 )
        {
            switch( prefixLength )
            {
                case 1:
                    put( (byte)0 );
                    break;
                case 2:
                    putShort( (short)0 );
                    break;
                case 4:
                    putInt( 0 );
                    break;
            }
            return this;
        }

        int padMask;
        switch( padding )
        {
            case 0:
            case 1:
                padMask = 0;
                break;
            case 2:
                padMask = 1;
                break;
            case 4:
                padMask = 3;
                break;
            default:
                throw new IllegalArgumentException( "padding: " + padding );
        }

        CharBuffer in = CharBuffer.wrap( val );
        int expectedLength = (int)( in.remaining() * encoder.averageBytesPerChar() ) + 1;

        skip( prefixLength ); // make a room for the length field
        int oldPos = position();
        encoder.reset();

        for( ; ; )
        {
            CoderResult cr;
            if( in.hasRemaining() )
            {
                cr = encoder.encode( in, buf(), true );
            }
            else
            {
                cr = encoder.flush( buf() );
            }

            if( position() - oldPos > maxLength )
            {
                throw new IllegalArgumentException( "The specified string is too long." );
            }

            if( cr.isUnderflow() )
            {
                break;
            }
            if( cr.isOverflow() && isAutoExpand() )
            {
                autoExpand( expectedLength );
                continue;
            }
            cr.throwException();
        }

        // Write the length field
        fill( padValue, padding - ( ( position() - oldPos ) & padMask ) );
        int length = position() - oldPos;
        switch( prefixLength )
        {
            case 1:
                put( oldPos - 1, (byte)length );
                break;
            case 2:
                putShort( oldPos - 2, (short)length );
                break;
            case 4:
                putInt( oldPos - 4, length );
                break;
        }
        return this;
    }

    /**
     * Reads a Java object from the buffer using the context {@link ClassLoader}
     * of the current thread.
     */
    public Object getObject() throws ClassNotFoundException
    {
        return getObject( Thread.currentThread().getContextClassLoader() );
    }

    /**
     * Reads a Java object from the buffer using the specified <tt>classLoader</tt>.
     */
    public Object getObject( final ClassLoader classLoader ) throws ClassNotFoundException
    {
        if( !prefixedDataAvailable( 4 ) )
        {
            throw new BufferUnderflowException();
        }

        int length = getInt();
        if( length <= 4 )
        {
            throw new BufferDataException( "Object length should be greater than 4: " + length );
        }

        int oldLimit = limit();
        limit( position() + length );
        try
        {
            ObjectInputStream in = new ObjectInputStream( asInputStream() )
            {
                protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException
                {
                    String className = readUTF();
                    Class clazz = Class.forName( className, true, classLoader );
                    return ObjectStreamClass.lookup( clazz );
                }
            };
            return in.readObject();
        }
        catch( IOException e )
        {
            throw new BufferDataException( e );
        }
        finally
        {
            limit( oldLimit );
        }
    }

    /**
     * Writes the specified Java object to the buffer.
     */
    public ByteBuffer putObject( Object o )
    {
        int oldPos = position();
        skip( 4 ); // Make a room for the length field.
        try
        {
            ObjectOutputStream out = new ObjectOutputStream( asOutputStream() )
            {
                protected void writeClassDescriptor( ObjectStreamClass desc ) throws IOException
                {
                    writeUTF( desc.getName() );
                }
            };
            out.writeObject( o );
            out.flush();
        }
        catch( IOException e )
        {
            throw new BufferDataException( e );
        }

        // Fill the length field
        int newPos = position();
        position( oldPos );
        putInt( newPos - oldPos - 4 );
        position( newPos );
        return this;
    }

    /**
     * Returns <tt>true</tt> if this buffer contains a data which has a data
     * length as a prefix and the buffer has remaining data as enough as
     * specified in the data length field.  This method is identical with
     * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>.
     * Please not that using this method can allow DoS (Denial of Service)
     * attack in case the remote peer sends too big data length value.
     * It is recommended to use {@link #prefixedDataAvailable(int, int)}
     * instead.
     *
     * @param prefixLength the length of the prefix field (1, 2, or 4)
     *
     * @throws IllegalArgumentException if prefixLength is wrong
     * @throws BufferDataException      if data length is negative
     */
    public boolean prefixedDataAvailable( int prefixLength )
    {
        return prefixedDataAvailable( prefixLength, Integer.MAX_VALUE );
    }

    /**
     * Returns <tt>true</tt> if this buffer contains a data which has a data
     * length as a prefix and the buffer has remaining data as enough as
     * specified in the data length field.
     *
     * @param prefixLength  the length of the prefix field (1, 2, or 4)
     * @param maxDataLength the allowed maximum of the read data length
     *
     * @throws IllegalArgumentException if prefixLength is wrong
     * @throws BufferDataException      if data length is negative or greater then <tt>maxDataLength</tt>
     */
    public boolean prefixedDataAvailable( int prefixLength, int maxDataLength )
    {
        if( remaining() < prefixLength )
        {
            return false;
        }

        int dataLength;
        switch( prefixLength )
        {
            case 1:
                dataLength = getUnsigned( position() );
                break;
            case 2:
                dataLength = getUnsignedShort( position() );
                break;
            case 4:
                dataLength = getInt( position() );
                break;
            default:
                throw new IllegalArgumentException( "prefixLength: " + prefixLength );
        }

        if( dataLength < 0 || dataLength > maxDataLength )
        {
            throw new BufferDataException( "dataLength: " + dataLength );
        }

        return remaining() - prefixLength >= dataLength;
    }

    //////////////////////////
    // Skip or fill methods //
    //////////////////////////

    /**
     * Forwards the position of this buffer as the specified <code>size</code>
     * bytes.
     */
    public ByteBuffer skip( int size )
    {
        autoExpand( size );
        return position( position() + size );
    }

    /**
     * Fills this buffer with the specified value.
     * This method moves buffer position forward.
     */
    public ByteBuffer fill( byte value, int size )
    {
        autoExpand( size );
        int q = size >>> 3;
        int r = size & 7;

        if( q > 0 )
        {
            int intValue = value | ( value << 8 ) | ( value << 16 )
                           | ( value << 24 );
            long longValue = intValue;
            longValue <<= 32;
            longValue |= intValue;

            for( int i = q; i > 0; i -- )
            {
                putLong( longValue );
            }
        }

        q = r >>> 2;
        r = r & 3;

        if( q > 0 )
        {
            int intValue = value | ( value << 8 ) | ( value << 16 )
                           | ( value << 24 );
            putInt( intValue );
        }

        q = r >> 1;
        r = r & 1;

        if( q > 0 )
        {
            short shortValue = (short)( value | ( value << 8 ) );
            putShort( shortValue );
        }

        if( r > 0 )
        {
            put( value );
        }

        return this;
    }

    /**
     * Fills this buffer with the specified value.
     * This method does not change buffer position.
     */
    public ByteBuffer fillAndReset( byte value, int size )
    {
        autoExpand( size );
        int pos = position();
        try
        {
            fill( value, size );
        }
        finally
        {
            position( pos );
        }
        return this;
    }

    /**
     * Fills this buffer with <code>NUL (0x00)</code>.
     * This method moves buffer position forward.
     */
    public ByteBuffer fill( int size )
    {
        autoExpand( size );
        int q = size >>> 3;
        int r = size & 7;

        for( int i = q; i > 0; i -- )
        {
            putLong( 0L );
        }

        q = r >>> 2;
        r = r & 3;

        if( q > 0 )
        {
            putInt( 0 );
        }

        q = r >> 1;
        r = r & 1;

        if( q > 0 )
        {
            putShort( (short)0 );
        }

        if( r > 0 )
        {
            put( (byte)0 );
        }

        return this;
    }

    /**
     * Fills this buffer with <code>NUL (0x00)</code>.
     * This method does not change buffer position.
     */
    public ByteBuffer fillAndReset( int size )
    {
        autoExpand( size );
        int pos = position();
        try
        {
            fill( size );
        }
        finally
        {
            position( pos );
        }

        return this;
    }

    /**
     * This method forwards the call to {@link #expand(int)} only when
     * <tt>autoExpand</tt> property is <tt>true</tt>.
     */
    protected ByteBuffer autoExpand( int expectedRemaining )
    {
        if( isAutoExpand() )
        {
            expand( expectedRemaining );
        }
        return this;
    }

    /**
     * This method forwards the call to {@link #expand(int)} only when
     * <tt>autoExpand</tt> property is <tt>true</tt>.
     */
    protected ByteBuffer autoExpand( int pos, int expectedRemaining )
    {
        if( isAutoExpand() )
        {
            expand( pos, expectedRemaining );
        }
        return this;
    }

    private static void checkFieldSize( int fieldSize )
    {
        if( fieldSize < 0 )
        {
            throw new IllegalArgumentException(
                "fieldSize cannot be negative: " + fieldSize );
        }
    }
}
