⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytebuffer.java

📁 apache 的一个socket框架
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* *  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: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (금, 13  7월 2007) $ * @noinspection StaticNonFinalField * @see ByteBufferAllocator */public abstract class ByteBuffer implements Comparable<ByteBuffer> {    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()     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -