2008-02-19 18:06:52 +00:00
|
|
|
/* Copyright (c) 2008, Avian Contributors
|
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2007-09-28 18:16:25 +00:00
|
|
|
package java.nio;
|
|
|
|
|
2007-11-15 18:53:01 +00:00
|
|
|
public class ByteBuffer implements Comparable<ByteBuffer> {
|
2007-09-28 18:16:25 +00:00
|
|
|
private final byte[] array;
|
|
|
|
private int arrayOffset;
|
|
|
|
private int capacity;
|
|
|
|
private int position;
|
|
|
|
private int limit;
|
2007-10-11 21:41:23 +00:00
|
|
|
private final boolean readOnly;
|
2007-09-28 18:16:25 +00:00
|
|
|
|
|
|
|
public static ByteBuffer allocate(int capacity) {
|
2007-10-11 21:41:23 +00:00
|
|
|
return new ByteBuffer(new byte[capacity], false);
|
2007-09-28 18:16:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static ByteBuffer wrap(byte[] array) {
|
2007-10-11 21:41:23 +00:00
|
|
|
return new ByteBuffer(array, false);
|
2007-09-28 18:16:25 +00:00
|
|
|
}
|
|
|
|
|
2007-10-11 21:41:23 +00:00
|
|
|
private ByteBuffer(byte[] array, boolean readOnly) {
|
2007-09-28 18:16:25 +00:00
|
|
|
this.array = array;
|
2007-10-11 21:41:23 +00:00
|
|
|
this.readOnly = readOnly;
|
2007-09-28 18:16:25 +00:00
|
|
|
arrayOffset = 0;
|
|
|
|
capacity = array.length;
|
|
|
|
limit = capacity;
|
|
|
|
position = 0;
|
|
|
|
}
|
|
|
|
|
2007-11-15 18:53:01 +00:00
|
|
|
public int compareTo(ByteBuffer o) {
|
|
|
|
int end = (remaining() < o.remaining() ? remaining() : o.remaining());
|
|
|
|
|
|
|
|
for (int i = 0; i < end; ++i) {
|
|
|
|
int d = get(position + i) - o.get(o.position + i);
|
|
|
|
if (d != 0) {
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return remaining() - o.remaining();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o instanceof ByteBuffer && compareTo((ByteBuffer) o) == 0;
|
|
|
|
}
|
|
|
|
|
2007-09-28 18:16:25 +00:00
|
|
|
public byte[] array() {
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
2007-10-11 15:59:52 +00:00
|
|
|
public ByteBuffer clear() {
|
|
|
|
position = 0;
|
|
|
|
limit = capacity;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2007-09-28 18:16:25 +00:00
|
|
|
public ByteBuffer slice() {
|
2007-10-11 21:41:23 +00:00
|
|
|
ByteBuffer buf = new ByteBuffer(array, true);
|
2007-09-28 18:16:25 +00:00
|
|
|
buf.arrayOffset = arrayOffset + position;
|
|
|
|
buf.position = 0;
|
2007-10-11 21:41:23 +00:00
|
|
|
buf.capacity = remaining();
|
2007-09-28 18:16:25 +00:00
|
|
|
buf.limit = buf.capacity;
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int limit() {
|
|
|
|
return limit;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int remaining() {
|
|
|
|
return limit-position;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int position() {
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int capacity() {
|
|
|
|
return capacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int arrayOffset() {
|
|
|
|
return arrayOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer compact() {
|
|
|
|
if (position != 0) {
|
|
|
|
System.arraycopy(array, arrayOffset+position, array, arrayOffset, remaining());
|
|
|
|
}
|
2007-10-05 21:32:56 +00:00
|
|
|
position=remaining();
|
|
|
|
limit(capacity());
|
|
|
|
|
2007-09-28 18:16:25 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer limit(int newLimit) {
|
|
|
|
limit = newLimit;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer position(int newPosition) {
|
|
|
|
position = newPosition;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer put(byte val) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(1);
|
2007-09-28 19:18:28 +00:00
|
|
|
array[arrayOffset+(position++)] = val;
|
2007-09-28 18:16:25 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer put(ByteBuffer src) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(src.remaining());
|
2007-09-28 18:16:25 +00:00
|
|
|
put(src.array, src.arrayOffset + src.position, src.remaining());
|
2007-10-11 21:41:23 +00:00
|
|
|
src.position += src.remaining();
|
2007-09-28 18:16:25 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer put(byte[] arr) {
|
|
|
|
return put(arr, 0, arr.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer put(byte[] arr, int offset, int len) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(len);
|
2007-09-28 18:19:13 +00:00
|
|
|
System.arraycopy(arr, offset, array, arrayOffset+position, len);
|
2007-09-28 18:16:25 +00:00
|
|
|
position += len;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer putInt(int position, int val) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(position, 4);
|
2007-09-28 18:16:25 +00:00
|
|
|
array[arrayOffset+position] = (byte)((val >> 24) & 0xff);
|
|
|
|
array[arrayOffset+position+1] = (byte)((val >> 16) & 0xff);
|
|
|
|
array[arrayOffset+position+2] = (byte)((val >> 8) & 0xff);
|
|
|
|
array[arrayOffset+position+3] = (byte)((val ) & 0xff);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer putInt(int val) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(4);
|
2007-09-28 18:16:25 +00:00
|
|
|
putInt(position, val);
|
|
|
|
position += 4;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer putShort(short val) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(2);
|
2007-09-28 18:16:25 +00:00
|
|
|
put((byte)((val >> 8) & 0xff));
|
|
|
|
put((byte)(val & 0xff));
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer putLong(long val) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkPut(8);
|
2007-09-28 18:16:25 +00:00
|
|
|
putInt((int)(val >> 32));
|
|
|
|
putInt((int)val);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasRemaining() {
|
|
|
|
return remaining() > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public byte get() {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkGet(1);
|
2007-09-28 18:16:25 +00:00
|
|
|
return array[arrayOffset+(position++)];
|
|
|
|
}
|
|
|
|
|
2007-11-09 21:32:33 +00:00
|
|
|
public ByteBuffer get(byte[] dst) {
|
|
|
|
return get(dst, 0, dst.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer get(byte[] dst, int offset, int length) {
|
|
|
|
checkGet(length);
|
|
|
|
System.arraycopy(array, arrayOffset + position, dst, offset, length);
|
|
|
|
position += length;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2007-09-28 18:16:25 +00:00
|
|
|
public byte get(int position) {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkGet(position, 1);
|
2007-09-28 18:16:25 +00:00
|
|
|
return array[arrayOffset+position];
|
|
|
|
}
|
|
|
|
|
|
|
|
public ByteBuffer flip() {
|
2007-09-28 18:18:01 +00:00
|
|
|
limit = position;
|
|
|
|
position = 0;
|
2007-09-28 18:16:25 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getInt() {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkGet(4);
|
2007-09-28 18:16:25 +00:00
|
|
|
int i = get() << 24;
|
|
|
|
i |= (get() & 0xff) << 16;
|
|
|
|
i |= (get() & 0xff) << 8;
|
|
|
|
i |= (get() & 0xff);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
public short getShort() {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkGet(2);
|
2007-09-28 18:16:25 +00:00
|
|
|
short s = (short)(get() << 8);
|
|
|
|
s |= get() & 0xff;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getLong() {
|
2007-10-11 21:41:23 +00:00
|
|
|
checkGet(8);
|
2007-10-11 22:42:33 +00:00
|
|
|
long l = (long)getInt() << 32;
|
2007-10-31 15:27:26 +00:00
|
|
|
l |= (long)getInt() & 0xffffffffL;
|
2007-09-28 18:16:25 +00:00
|
|
|
return l;
|
|
|
|
}
|
2007-10-11 21:41:23 +00:00
|
|
|
|
|
|
|
private void checkPut(int amount) {
|
|
|
|
if (readOnly) throw new ReadOnlyBufferException();
|
|
|
|
if (amount > limit-position) throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkPut(int position, int amount) {
|
|
|
|
if (readOnly) throw new ReadOnlyBufferException();
|
|
|
|
if (position < 0 || position+amount > limit)
|
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkGet(int amount) {
|
|
|
|
if (amount > limit-position) throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkGet(int position, int amount) {
|
|
|
|
if (position < 0 || position+amount > limit)
|
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
2007-10-30 20:55:00 +00:00
|
|
|
|
|
|
|
public String toString() {
|
|
|
|
return "(ByteBuffer with array: " + array + " arrayOffset: " + arrayOffset + " position: " + position + " remaining; " + remaining() + ")";
|
|
|
|
}
|
2007-09-28 18:16:25 +00:00
|
|
|
}
|