blob: 51f568f9cfe1fc8771dc5251242e6bda808977ed [file] [log] [blame]
/*
* 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.qpid.protonj2.buffer;
import java.nio.ByteBuffer;
/**
* ProtonBuffer wrapper around a NIO ByteBuffer instance.
*/
public class ProtonNioByteBuffer extends ProtonAbstractBuffer {
// TODO - Operations in this class assume the originating buffer is zero indexed, one alternative is to
// slice but that might have unintended consequences.
private final ByteBuffer buffer;
/**
* Creates a {@link ProtonNioByteBuffer} that wraps the given ByteBuffer instance.
*
* @param buffer
* The ByteBuffer instance to wrap.
*/
public ProtonNioByteBuffer(ByteBuffer buffer) {
this(buffer, buffer.remaining());
}
/**
* Creates a {@link ProtonNioByteBuffer} that wraps the given ByteBuffer instance.
*
* @param buffer
* The ByteBuffer instance to wrap.
* @param writeIndex
* The write index to assign to this newly created ByteBuffer wrapper.
*/
public ProtonNioByteBuffer(ByteBuffer buffer, int writeIndex) {
super(buffer.remaining());
this.buffer = buffer.slice();
setIndex(0, writeIndex);
}
@Override
public ByteBuffer unwrap() {
return buffer;
}
@Override
public boolean hasArray() {
return buffer.hasArray();
}
@Override
public byte[] getArray() {
return buffer.array();
}
@Override
public int getArrayOffset() {
return buffer.arrayOffset();
}
@Override
public int capacity() {
return buffer.remaining();
}
@Override
public ProtonBuffer capacity(int newCapacity) {
if (newCapacity < 0) {
throw new IllegalArgumentException("Cannot alter a buffer's capacity to a negative value: " + newCapacity);
} else {
throw new UnsupportedOperationException("NIO Buffer wrapper cannot adjust capacity");
}
}
@Override
public byte getByte(int index) {
return buffer.get(index);
}
@Override
public short getShort(int index) {
return buffer.getShort(index);
}
@Override
public int getInt(int index) {
return buffer.getInt(index);
}
@Override
public long getLong(int index) {
return buffer.getLong(index);
}
@Override
public ProtonBuffer getBytes(int index, ProtonBuffer destination, int destinationIndex, int length) {
checkDestinationIndex(index, length, destinationIndex, destination.capacity());
if (hasArray()) {
destination.setBytes(destinationIndex, getArray(), getArrayOffset() + index, length);
} else if (destination.hasArray()) {
int position = buffer.position();
buffer.position(index);
buffer.get(destination.getArray(), destination.getArrayOffset() + destinationIndex, length);
buffer.position(position);
} else {
while (length-- > 0) {
destination.setByte(destinationIndex++, buffer.get(index++));
}
}
return this;
}
@Override
public ProtonBuffer getBytes(int index, byte[] destination, int offset, int length) {
checkDestinationIndex(index, length, offset, destination.length);
if (hasArray()) {
System.arraycopy(getArray(), getArrayOffset() + index, destination, offset, length);
} else {
final int position = buffer.position();
buffer.position(index);
buffer.get(destination, offset, length);
buffer.position(position);
}
return this;
}
@Override
public ProtonBuffer getBytes(int index, ByteBuffer destination) {
checkIndex(index, destination.remaining());
if (destination.hasArray()) {
final int position = buffer.position();
buffer.position(index);
buffer.get(destination.array(), destination.arrayOffset() + destination.position(), destination.remaining());
buffer.position(position);
destination.position(destination.limit());
} else if (hasArray()) {
destination.put(getArray(), getArrayOffset() + index, destination.remaining());
} else {
while (destination.hasRemaining()) {
destination.put(getByte(index++));
}
}
return this;
}
@Override
public ProtonBuffer setByte(int index, int value) {
buffer.put(index, (byte) value);
return this;
}
@Override
public ProtonBuffer setShort(int index, int value) {
buffer.putShort(index, (short) value);
return this;
}
@Override
public ProtonBuffer setInt(int index, int value) {
buffer.putInt(index, value);
return this;
}
@Override
public ProtonBuffer setLong(int index, long value) {
buffer.putLong(index, value);
return this;
}
@Override
public ProtonBuffer setBytes(int index, ProtonBuffer source, int sourceIndex, int length) {
checkSourceIndex(index, length, sourceIndex, source.capacity());
if (source.hasArray()) {
final int position = buffer.position();
buffer.position(index);
buffer.put(source.getArray(), source.getArrayOffset() + sourceIndex, length);
buffer.position(position);
} else if (hasArray()) {
source.getBytes(sourceIndex, getArray(), getArrayOffset() + index, length);
} else {
while (length-- > 0) {
buffer.put(index++, source.getByte(sourceIndex++));
}
}
return this;
}
@Override
public ProtonBuffer setBytes(int index, byte[] source, int sourceIndex, int length) {
checkSourceIndex(index, length, sourceIndex, source.length);
final int position = buffer.position();
buffer.position(index);
buffer.put(source, sourceIndex, length);
buffer.position(position);
return this;
}
@Override
public ProtonBuffer setBytes(int index, ByteBuffer source) {
checkSourceIndex(index, source.remaining(), source.position(), source.capacity());
final int position = buffer.position();
buffer.position(index);
buffer.put(source);
buffer.position(position);
return this;
}
@Override
public ProtonBuffer copy(int index, int length) {
ProtonByteBuffer buffer = new ProtonByteBuffer(length);
getBytes(index, buffer, length);
return buffer;
}
@Override
public ByteBuffer toByteBuffer(int index, int length) {
checkIndex(index, length);
int position = buffer.position();
int limit = buffer.limit();
buffer.position(index);
buffer.limit(index + length);
final ByteBuffer result = buffer.slice();
buffer.limit(limit);
buffer.position(position);
return result;
}
}