/* * 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.Collections; import org.apache.mina.core.buffer.IoBuffer; /** * A <code>ByteArray</code> backed by a <code>IoBuffer</code>. This class * is abstract. Subclasses need to override the <code>free()</code> method. An * implementation backed by a heap <code>IoBuffer</code> can be created with * a <code>SimpleByteArrayFactory</code>. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public abstract class BufferByteArray extends AbstractByteArray { /** * The backing <code>IoBuffer</code>. */ protected IoBuffer bb; /** * * Creates a new instance of BufferByteArray and uses the supplied * {@link IoBuffer} to back this class * * @param bb * The backing buffer */ public BufferByteArray(IoBuffer bb) { this.bb = bb; } /** * @inheritDoc */ public Iterable<IoBuffer> getIoBuffers() { return Collections.singletonList(bb); } /** * @inheritDoc */ public IoBuffer getSingleIoBuffer() { return bb; } /** * @inheritDoc * * Calling <code>free()</code> on the returned slice has no effect. */ public ByteArray slice(int index, int length) { int oldLimit = bb.limit(); bb.position(index); bb.limit(index + length); IoBuffer slice = bb.slice(); bb.limit(oldLimit); return new BufferByteArray(slice) { @Override public void free() { // Do nothing. } }; } /** * @inheritDoc */ public abstract void free(); /** * @inheritDoc */ public Cursor cursor() { return new CursorImpl(); } /** * @inheritDoc */ public Cursor cursor(int index) { return new CursorImpl(index); } /** * @inheritDoc */ public int first() { return 0; } /** * @inheritDoc */ public int last() { return bb.limit(); } /** * @inheritDoc */ public ByteOrder order() { return bb.order(); } /** * @inheritDoc */ public void order(ByteOrder order) { bb.order(order); } /** * @inheritDoc */ public byte get(int index) { return bb.get(index); } /** * @inheritDoc */ public void put(int index, byte b) { bb.put(index, b); } /** * @inheritDoc */ public void get(int index, IoBuffer other) { bb.position(index); other.put(bb); } /** * @inheritDoc */ public void put(int index, IoBuffer other) { bb.position(index); bb.put(other); } /** * @inheritDoc */ public short getShort(int index) { return bb.getShort(index); } /** * @inheritDoc */ public void putShort(int index, short s) { bb.putShort(index, s); } /** * @inheritDoc */ public int getInt(int index) { return bb.getInt(index); } /** * @inheritDoc */ public void putInt(int index, int i) { bb.putInt(index, i); } /** * @inheritDoc */ public long getLong(int index) { return bb.getLong(index); } /** * @inheritDoc */ public void putLong(int index, long l) { bb.putLong(index, l); } /** * @inheritDoc */ public float getFloat(int index) { return bb.getFloat(index); } /** * @inheritDoc */ public void putFloat(int index, float f) { bb.putFloat(index, f); } /** * @inheritDoc */ public double getDouble(int index) { return bb.getDouble(index); } /** * @inheritDoc */ public void putDouble(int index, double d) { bb.putDouble(index, d); } /** * @inheritDoc */ public char getChar(int index) { return bb.getChar(index); } /** * @inheritDoc */ public void putChar(int index, char c) { bb.putChar(index, c); } private class CursorImpl implements Cursor { private int index; public CursorImpl() { // This space intentionally blank. } public CursorImpl(int index) { setIndex(index); } /** * @inheritDoc */ public int getRemaining() { return last() - index; } /** * @inheritDoc */ public boolean hasRemaining() { return getRemaining() > 0; } /** * @inheritDoc */ public int getIndex() { return index; } /** * @inheritDoc */ public void setIndex(int index) { if (index < 0 || index > last()) { throw new IndexOutOfBoundsException(); } this.index = index; } public void skip(int length) { setIndex(index + length); } public ByteArray slice(int length) { ByteArray slice = BufferByteArray.this.slice(index, length); index += length; return slice; } /** * @inheritDoc */ public ByteOrder order() { return BufferByteArray.this.order(); } /** * @inheritDoc */ public byte get() { byte b = BufferByteArray.this.get(index); index += 1; return b; } /** * @inheritDoc */ public void put(byte b) { BufferByteArray.this.put(index, b); index += 1; } /** * @inheritDoc */ public void get(IoBuffer bb) { int size = Math.min(getRemaining(), bb.remaining()); BufferByteArray.this.get(index, bb); index += size; } /** * @inheritDoc */ public void put(IoBuffer bb) { int size = bb.remaining(); BufferByteArray.this.put(index, bb); index += size; } /** * @inheritDoc */ public short getShort() { short s = BufferByteArray.this.getShort(index); index += 2; return s; } /** * @inheritDoc */ public void putShort(short s) { BufferByteArray.this.putShort(index, s); index += 2; } /** * @inheritDoc */ public int getInt() { int i = BufferByteArray.this.getInt(index); index += 4; return i; } /** * @inheritDoc */ public void putInt(int i) { BufferByteArray.this.putInt(index, i); index += 4; } /** * @inheritDoc */ public long getLong() { long l = BufferByteArray.this.getLong(index); index += 8; return l; } /** * @inheritDoc */ public void putLong(long l) { BufferByteArray.this.putLong(index, l); index += 8; } /** * @inheritDoc */ public float getFloat() { float f = BufferByteArray.this.getFloat(index); index += 4; return f; } /** * @inheritDoc */ public void putFloat(float f) { BufferByteArray.this.putFloat(index, f); index += 4; } /** * @inheritDoc */ public double getDouble() { double d = BufferByteArray.this.getDouble(index); index += 8; return d; } /** * @inheritDoc */ public void putDouble(double d) { BufferByteArray.this.putDouble(index, d); index += 8; } /** * @inheritDoc */ public char getChar() { char c = BufferByteArray.this.getChar(index); index += 2; return c; } /** * @inheritDoc */ public void putChar(char c) { BufferByteArray.this.putChar(index, c); index += 2; } } }