📄 abstractiobuffer.java
字号:
/* * 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.core.buffer;import java.io.EOFException;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.io.StreamCorruptedException;import java.nio.BufferOverflowException;import java.nio.BufferUnderflowException;import java.nio.ByteBuffer;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 java.util.EnumSet;import java.util.Set;/** * A base implementation of {@link IoBuffer}. This implementation * assumes that {@link IoBuffer#buf()} always returns a correct NIO * {@link ByteBuffer} instance. Most implementations could * extend this class and implement their own buffer management mechanism. * * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev: 748210 $, $Date: 2009-02-26 18:05:40 +0100 (Thu, 26 Feb 2009) $ * @see IoBufferAllocator */public abstract class AbstractIoBuffer extends IoBuffer { /** Tells if a buffer has been created from an existing buffer */ private final boolean derived; /** A flag set to true if the buffer can extend automatically */ private boolean autoExpand; /** A flag set to true if the buffer can shrink automatically */ private boolean autoShrink; /** Tells if a buffer can be expanded */ private boolean recapacityAllowed = true; /** The minimum number of bytes the IoBuffer can hold */ private int minimumCapacity; /** A mask for a byte */ private static final long BYTE_MASK = 0xFFL; /** A mask for a short */ private static final long SHORT_MASK = 0xFFFFL; /** A mask for an int */ private static final long INT_MASK = 0xFFFFFFFFL; /** * We don't have any access to Buffer.markValue(), so we need to track it down, * which will cause small extra overhead. */ private int mark = -1; /** * Creates a new parent buffer. * * @param allocator The allocator to use to create new buffers * @param initialCapacity The initial buffer capacity when created */ protected AbstractIoBuffer(IoBufferAllocator allocator, int initialCapacity) { setAllocator(allocator); this.recapacityAllowed = true; this.derived = false; this.minimumCapacity = initialCapacity; } /** * Creates a new derived buffer. A derived buffer uses an existing * buffer properties - the allocator and capacity -. * * @param parent The buffer we get the properties from */ protected AbstractIoBuffer(AbstractIoBuffer parent) { setAllocator(parent.getAllocator()); this.recapacityAllowed = false; this.derived = true; this.minimumCapacity = parent.minimumCapacity; } /** * {@inheritDoc} */ @Override public final boolean isDirect() { return buf().isDirect(); } /** * {@inheritDoc} */ @Override public final boolean isReadOnly() { return buf().isReadOnly(); } /** * Sets the underlying NIO buffer instance. * * @param newBuf The buffer to store within this IoBuffer */ protected abstract void buf(ByteBuffer newBuf); /** * {@inheritDoc} */ @Override public final int minimumCapacity() { return minimumCapacity; } /** * {@inheritDoc} */ @Override public final IoBuffer minimumCapacity(int minimumCapacity) { if (minimumCapacity < 0) { throw new IllegalArgumentException("minimumCapacity: " + minimumCapacity); } this.minimumCapacity = minimumCapacity; return this; } /** * {@inheritDoc} */ @Override public final int capacity() { return buf().capacity(); } /** * {@inheritDoc} */ @Override public final IoBuffer capacity(int newCapacity) { if (!recapacityAllowed) { throw new IllegalStateException( "Derived buffers and their parent can't be expanded."); } // Allocate a new buffer and transfer all settings to it. if (newCapacity > capacity()) { // Expand: //// Save the state. int pos = position(); int limit = limit(); ByteOrder bo = order(); //// Reallocate. ByteBuffer oldBuf = buf(); ByteBuffer newBuf = getAllocator().allocateNioBuffer(newCapacity, isDirect()); oldBuf.clear(); newBuf.put(oldBuf); buf(newBuf); //// Restore the state. buf().limit(limit); if (mark >= 0) { buf().position(mark); buf().mark(); } buf().position(pos); buf().order(bo); } return this; } /** * {@inheritDoc} */ @Override public final boolean isAutoExpand() { return autoExpand && recapacityAllowed; } /** * {@inheritDoc} */ @Override public final boolean isAutoShrink() { return autoShrink && recapacityAllowed; } /** * {@inheritDoc} */ @Override public final boolean isDerived() { return derived; } /** * {@inheritDoc} */ @Override public final IoBuffer setAutoExpand(boolean autoExpand) { if (!recapacityAllowed) { throw new IllegalStateException( "Derived buffers and their parent can't be expanded."); } this.autoExpand = autoExpand; return this; } /** * {@inheritDoc} */ @Override public final IoBuffer setAutoShrink(boolean autoShrink) { if (!recapacityAllowed) { throw new IllegalStateException( "Derived buffers and their parent can't be shrinked."); } this.autoShrink = autoShrink; return this; } /** * {@inheritDoc} */ @Override public final IoBuffer expand(int expectedRemaining) { return expand(position(), expectedRemaining, false); } private IoBuffer expand(int expectedRemaining, boolean autoExpand) { return expand(position(), expectedRemaining, autoExpand); } /** * {@inheritDoc} */ @Override public final IoBuffer expand(int pos, int expectedRemaining) { return expand(pos, expectedRemaining, false); } private IoBuffer expand(int pos, int expectedRemaining, boolean autoExpand) { if (!recapacityAllowed) { throw new IllegalStateException( "Derived buffers and their parent can't be expanded."); } int end = pos + expectedRemaining; int newCapacity; if (autoExpand) { newCapacity = IoBuffer.normalizeCapacity(end); } else { newCapacity = end; } if (newCapacity > capacity()) { // The buffer needs expansion. capacity(newCapacity); } if (end > limit()) { // We call limit() directly to prevent StackOverflowError buf().limit(end); } return this; } /** * {@inheritDoc} */ @Override public final IoBuffer shrink() { if (!recapacityAllowed) { throw new IllegalStateException( "Derived buffers and their parent can't be expanded."); } int position = position(); int capacity = capacity(); int limit = limit(); if (capacity == limit) { return this; } int newCapacity = capacity; int minCapacity = Math.max(minimumCapacity, limit); for (;;) { if (newCapacity >>> 1 < minCapacity) { break; } newCapacity >>>= 1; } newCapacity = Math.max(minCapacity, newCapacity); if (newCapacity == capacity) { return this; } // Shrink and compact: //// Save the state. ByteOrder bo = order(); //// Reallocate. ByteBuffer oldBuf = buf(); ByteBuffer newBuf = getAllocator() .allocateNioBuffer(newCapacity, isDirect()); oldBuf.position(0); oldBuf.limit(limit); newBuf.put(oldBuf); buf(newBuf); //// Restore the state. buf().position(position); buf().limit(limit); buf().order(bo); mark = -1; return this; } /** * {@inheritDoc} */ @Override public final int position() { return buf().position(); } /** * {@inheritDoc} */ @Override public final IoBuffer position(int newPosition) { autoExpand(newPosition, 0); buf().position(newPosition); if (mark > newPosition) { mark = -1; } return this; } /** * {@inheritDoc} */ @Override public final int limit() { return buf().limit(); } /** * {@inheritDoc} */ @Override public final IoBuffer limit(int newLimit) { autoExpand(newLimit, 0); buf().limit(newLimit); if (mark > newLimit) { mark = -1; } return this; } /** * {@inheritDoc} */ @Override public final IoBuffer mark() { buf().mark(); mark = position(); return this; } /** * {@inheritDoc} */ @Override public final int markValue() { return mark; } /** * {@inheritDoc} */ @Override public final IoBuffer reset() { buf().reset(); return this; } /** * {@inheritDoc} */ @Override public final IoBuffer clear() { buf().clear(); mark = -1; return this; } /** * {@inheritDoc} */ @Override public final IoBuffer sweep() { clear(); return fillAndReset(remaining()); } /** * {@inheritDoc} */ @Override public final IoBuffer sweep(byte value) { clear(); return fillAndReset(value, remaining()); } /** * {@inheritDoc} */ @Override public final IoBuffer flip() { buf().flip(); mark = -1; return this; } /** * {@inheritDoc} */ @Override public final IoBuffer rewind() { buf().rewind(); mark = -1; return this; } /** * {@inheritDoc} */ @Override public final int remaining() { return limit() - position(); } /** * {@inheritDoc} */ @Override public final boolean hasRemaining() { return limit() > position(); } /** * {@inheritDoc} */ @Override public final byte get() { return buf().get(); } /** * {@inheritDoc} */ @Override public final short getUnsigned() { return (short) (get() & 0xff); } /** * {@inheritDoc} */ @Override public final IoBuffer put(byte b) { autoExpand(1); buf().put(b); return this;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -