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

📄 compositebytearray.java

📁 mina是以Java实现的一个开源的网络程序框架
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* *  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.util.byteaccess;import java.nio.ByteOrder;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.util.byteaccess.ByteArrayList.Node;/** * A ByteArray composed of other ByteArrays. Optimised for fast relative access * via cursors. Absolute access methods are provided, but may perform poorly. * * TODO: Write about laziness of cursor implementation - how movement doesn't * happen until actual get/put. *  * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev$, $Date$ */public final class CompositeByteArray extends AbstractByteArray{    /**     * Allows for efficient detection of component boundaries when using a cursor.     *     * TODO: Is this interface right?     */    public interface CursorListener    {        /**         * Called when the first component in the composite is entered by the cursor.         */        public void enteredFirstComponent( int componentIndex, ByteArray component );        /**         * Called when the next component in the composite is entered by the cursor.         */        public void enteredNextComponent( int componentIndex, ByteArray component );        /**         * Called when the previous component in the composite is entered by the cursor.         */        public void enteredPreviousComponent( int componentIndex, ByteArray component );        /**         * Called when the last component in the composite is entered by the cursor.         */        public void enteredLastComponent( int componentIndex, ByteArray component );    }    /**     * Stores the underlying <code>ByteArray</code>s.     */    private final ByteArrayList bas = new ByteArrayList();    /**     * The byte order for data in the buffer     */    private ByteOrder order;    /**     * May be used in <code>getSingleIoBuffer</code>. Optional.     */    private final ByteArrayFactory byteArrayFactory;    /**     * Creates a new instance of CompositeByteArray.     */    public CompositeByteArray()    {        this( null );    }    /**     *      * Creates a new instance of CompositeByteArray.     *     * @param byteArrayFactory     *  The factory used to create the ByteArray objects     */    public CompositeByteArray( ByteArrayFactory byteArrayFactory )    {        this.byteArrayFactory = byteArrayFactory;    }    /**     * Returns the first {@link ByteArray} in the list     *     * @return     *  The first ByteArray in the list     */    public ByteArray getFirst()    {        if ( bas.isEmpty() )        {            return null;        }        else        {            return bas.getFirst().getByteArray();        }    }    /**     * Adds the specified {@link ByteArray} to the first     * position in the list     *     * @param ba     *  The ByteArray to add to the list     */    public void addFirst( ByteArray ba )    {        addHook( ba );        bas.addFirst( ba );    }    /**     * Remove the first {@link ByteArray} in the list     *     * @return     *  The first ByteArray in the list     */    public ByteArray removeFirst()    {        Node node = bas.removeFirst();        return node == null ? null : node.getByteArray();    }    /**     * Remove component <code>ByteArray</code>s to the given index (splitting     * them if necessary) and returning them in a single <code>ByteArray</code>.     * The caller is responsible for freeing the returned object.     *     * TODO: Document free behaviour more thoroughly.     */    public ByteArray removeTo( int index )    {        if ( index < first() || index > last() )        {            throw new IndexOutOfBoundsException();        }        // Optimisation when removing exactly one component.        //        if (index == start() + getFirst().length()) {        //            ByteArray component = getFirst();        //            removeFirst();        //            return component;        //        }        // Removing        CompositeByteArray prefix = new CompositeByteArray( byteArrayFactory );        int remaining = index - first();        while ( remaining > 0 )        {            ByteArray component = removeFirst();            if ( component.last() <= remaining )            {                // Remove entire component.                prefix.addLast( component );                remaining -= component.last();            }            else            {                // Remove part of component. Do this by removing entire                // component then readding remaining bytes.                // TODO: Consider using getIoBuffers(), as would avoid                // performance problems for nested ComponentByteArrays.                IoBuffer bb = component.getSingleIoBuffer();                // get the limit of the buffer                int originalLimit = bb.limit();                // set the position to the beginning of the buffer                bb.position( 0 );                // set the limit of the buffer to what is remaining                bb.limit( remaining );                // create a new IoBuffer, sharing the data with 'bb'                IoBuffer bb1 = bb.slice();                // set the position at the end of the buffer                bb.position( remaining );                // gets the limit of the buffer                bb.limit( originalLimit );                // create a new IoBuffer, sharing teh data with 'bb'                IoBuffer bb2 = bb.slice();                // create a new ByteArray with 'bb1'                ByteArray ba1 = new BufferByteArray( bb1 )                {                    @Override                    public void free()                    {                        // Do not free.  This will get freed                     }                };                // add the new ByteArray to the CompositeByteArray                prefix.addLast( ba1 );                remaining -= ba1.last();                                // final for anonymous inner class                final ByteArray componentFinal = component;                 ByteArray ba2 = new BufferByteArray( bb2 )                {                    @Override                    public void free()                    {                        componentFinal.free();                    }                };                // add the new ByteArray to the CompositeByteArray                addFirst( ba2 );            }        }                // return the CompositeByteArray        return prefix;    }    /**     * Adds the specified {@link ByteArray} to the end of the list     *     * @param ba     *  The ByteArray to add to the end of the list     */    public void addLast( ByteArray ba )    {        addHook( ba );        bas.addLast( ba );    }    /**     * Removes the last {@link ByteArray} in the list     *     * @return     *  The ByteArray that was removed     */    public ByteArray removeLast()    {        Node node = bas.removeLast();        return node == null ? null : node.getByteArray();    }    /**     * @inheritDoc     */    public void free()    {        while ( !bas.isEmpty() )        {            Node node = bas.getLast();            node.getByteArray().free();            bas.removeLast();        }    }    private void checkBounds( int index, int accessSize )    {        int lower = index;        int upper = index + accessSize;        if ( lower < first() )        {            throw new IndexOutOfBoundsException( "Index " + lower + " less than start " + first() + "." );        }        if ( upper > last() )        {            throw new IndexOutOfBoundsException( "Index " + upper + " greater than length " + last() + "." );        }    }    /**     * @inheritDoc     */    public Iterable<IoBuffer> getIoBuffers()    {        if ( bas.isEmpty() )        {            return Collections.emptyList();        }        Collection<IoBuffer> result = new ArrayList<IoBuffer>();        Node node = bas.getFirst();        for ( IoBuffer bb : node.getByteArray().getIoBuffers() )        {            result.add( bb );        }        while ( node.hasNextNode() )        {            node = node.getNextNode();            for ( IoBuffer bb : node.getByteArray().getIoBuffers() )            {                result.add( bb );            }        }        return result;    }    /**     * @inheritDoc     */    public IoBuffer getSingleIoBuffer()    {        if ( byteArrayFactory == null )        {            throw new IllegalStateException(                "Can't get single buffer from CompositeByteArray unless it has a ByteArrayFactory." );        }        if ( bas.isEmpty() )        {            ByteArray ba = byteArrayFactory.create( 1 );            return ba.getSingleIoBuffer();        }        int actualLength = last() - first();        {            Node node = bas.getFirst();            ByteArray ba = node.getByteArray();            if ( ba.last() == actualLength )            {                return ba.getSingleIoBuffer();            }        }        // Replace all nodes with a single node.        ByteArray target = byteArrayFactory.create( actualLength );        IoBuffer bb = target.getSingleIoBuffer();        Cursor cursor = cursor();        cursor.put( bb ); // Copy all existing data into target IoBuffer.        while ( !bas.isEmpty() )        {            Node node = bas.getLast();            ByteArray component = node.getByteArray();            bas.removeLast();            component.free();        }        bas.addLast( target );        return bb;    }    /**     * @inheritDoc     */    public Cursor cursor()    {        return new CursorImpl();    }    /**     * @inheritDoc     */    public Cursor cursor( int index )    {        return new CursorImpl( index );    }    /**     * Get a cursor starting at index 0 (which may not be the start of the     * array) and with the given listener.     *      * @param listener     *  Returns a new {@link Cursor} instance     */    public Cursor cursor( CursorListener listener )    {        return new CursorImpl( listener );    }    /**     * Get a cursor starting at the given index and with the given listener.     *      * @param index     *  The position of the array to start the Cursor at     * @param listener     *  The listener for the Cursor that is returned     */    public Cursor cursor( int index, CursorListener listener )    {        return new CursorImpl( index, listener );    }    /**     * @inheritDoc     */    public ByteArray slice( int index, int length )    {        return cursor( index ).slice( length );    }    /**     * @inheritDoc

⌨️ 快捷键说明

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