2022-07-20 13:18:57 +02:00
|
|
|
package fr.pandacube.lib.net;
|
2016-07-04 17:13:24 +02:00
|
|
|
|
2021-03-21 20:17:31 +01:00
|
|
|
import java.nio.charset.Charset;
|
2022-07-10 00:55:56 +02:00
|
|
|
import java.nio.charset.StandardCharsets;
|
2016-07-04 17:13:24 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.List;
|
|
|
|
|
2022-07-20 13:18:57 +02:00
|
|
|
import com.google.common.annotations.Beta;
|
|
|
|
|
|
|
|
@Beta
|
2020-02-08 15:43:19 +01:00
|
|
|
public final class ByteBuffer implements Cloneable {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2022-07-10 00:55:56 +02:00
|
|
|
public static final Charset NETWORK_CHARSET = StandardCharsets.UTF_8;
|
2021-03-21 20:17:31 +01:00
|
|
|
|
2016-07-04 17:13:24 +02:00
|
|
|
private java.nio.ByteBuffer buff;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2020-02-08 15:43:19 +01:00
|
|
|
public ByteBuffer() {
|
|
|
|
this(16);
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2020-02-08 15:43:19 +01:00
|
|
|
public ByteBuffer(int initSize) {
|
2016-07-04 17:13:24 +02:00
|
|
|
buff = java.nio.ByteBuffer.allocate(initSize);
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2020-02-08 15:43:19 +01:00
|
|
|
/**
|
|
|
|
* Create a ByteBuffer that is initially <b>backed</b> by the provided byte array.
|
|
|
|
* The position of this buffer will be 0.
|
|
|
|
* If this ByteBuffer needs a biffer array, the provided array is replaced by a new one,
|
|
|
|
* making the provided array not related to this ByteBuffer anymore.
|
|
|
|
* @param data array of byte that serve as a backend for this ByteBuffer.
|
|
|
|
*/
|
|
|
|
public ByteBuffer(byte[] data) {
|
|
|
|
buff = java.nio.ByteBuffer.wrap(data);
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2016-07-04 17:13:24 +02:00
|
|
|
private void askForBufferExtension(int needed) {
|
2016-07-31 12:57:39 +02:00
|
|
|
while (buff.remaining() < needed) {
|
|
|
|
java.nio.ByteBuffer newBuff = java.nio.ByteBuffer.wrap(Arrays.copyOf(buff.array(), buff.array().length * 2));
|
|
|
|
newBuff.position(buff.position());
|
|
|
|
buff = newBuff;
|
|
|
|
}
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|
|
|
|
|
2020-02-08 15:43:19 +01:00
|
|
|
/**
|
|
|
|
* This clone method also clone the underlying array.
|
|
|
|
*/
|
2022-07-22 18:37:15 +02:00
|
|
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
2016-07-04 17:13:24 +02:00
|
|
|
@Override
|
|
|
|
public ByteBuffer clone() {
|
2020-02-08 15:43:19 +01:00
|
|
|
return new ByteBuffer(Arrays.copyOf(buff.array(), buff.array().length));
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#get()
|
|
|
|
*/
|
|
|
|
public byte getByte() {
|
|
|
|
return buff.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#get(byte[])
|
|
|
|
*/
|
2016-09-08 14:16:07 +02:00
|
|
|
public byte[] getByteArray(byte[] b) {
|
2016-07-04 17:13:24 +02:00
|
|
|
buff.get(b);
|
|
|
|
return b;
|
|
|
|
}
|
2016-09-08 14:16:07 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the next byte array wich is preceded with his size as integer,
|
|
|
|
* or null if the founded size is negative.
|
|
|
|
*/
|
|
|
|
public byte[] getSizedByteArray() {
|
|
|
|
int size = getInt();
|
|
|
|
if (size < 0) return null;
|
|
|
|
return getByteArray(new byte[size]);
|
|
|
|
}
|
2016-07-04 17:13:24 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#getChar()
|
|
|
|
*/
|
|
|
|
public char getChar() {
|
|
|
|
return buff.getChar();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#getShort()
|
|
|
|
*/
|
|
|
|
public short getShort() {
|
|
|
|
return buff.getShort();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#getInt()
|
|
|
|
*/
|
|
|
|
public int getInt() {
|
|
|
|
return buff.getInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#getLong()
|
|
|
|
*/
|
|
|
|
public long getLong() {
|
|
|
|
return buff.getLong();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#getFloat()
|
|
|
|
*/
|
|
|
|
public float getFloat() {
|
|
|
|
return buff.getFloat();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#getDouble()
|
|
|
|
*/
|
|
|
|
public double getDouble() {
|
|
|
|
return buff.getDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#put(byte)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putByte(byte b) {
|
|
|
|
askForBufferExtension(Byte.BYTES);
|
|
|
|
buff.put(b);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#put(byte[])
|
|
|
|
*/
|
2016-09-08 14:16:07 +02:00
|
|
|
public ByteBuffer putByteArray(byte[] b) {
|
2016-07-14 14:22:23 +02:00
|
|
|
askForBufferExtension(b.length * Byte.BYTES);
|
2016-07-04 17:13:24 +02:00
|
|
|
buff.put(b);
|
|
|
|
return this;
|
|
|
|
}
|
2016-09-08 14:16:07 +02:00
|
|
|
|
|
|
|
public ByteBuffer putSizedByteArray(byte[] b) {
|
|
|
|
if (b == null) {
|
|
|
|
return putInt(-1);
|
|
|
|
}
|
|
|
|
putInt(b.length);
|
|
|
|
return putByteArray(b);
|
|
|
|
}
|
2016-07-04 17:13:24 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#putChar(char)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putChar(char value) {
|
|
|
|
askForBufferExtension(Character.BYTES);
|
|
|
|
buff.putChar(value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#putShort(short)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putShort(short value) {
|
|
|
|
askForBufferExtension(Short.BYTES);
|
|
|
|
buff.putShort(value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#putInt(int)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putInt(int value) {
|
|
|
|
askForBufferExtension(Integer.BYTES);
|
|
|
|
buff.putInt(value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#putLong(long)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putLong(long value) {
|
|
|
|
askForBufferExtension(Long.BYTES);
|
|
|
|
buff.putLong(value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#putFloat(float)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putFloat(float value) {
|
|
|
|
askForBufferExtension(Float.BYTES);
|
|
|
|
buff.putFloat(value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#putDouble(double)
|
|
|
|
*/
|
|
|
|
public ByteBuffer putDouble(double value) {
|
|
|
|
askForBufferExtension(Double.BYTES);
|
|
|
|
buff.putDouble(value);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#position()
|
|
|
|
*/
|
|
|
|
public int getPosition() {
|
|
|
|
return buff.position();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#position(int)
|
|
|
|
*/
|
|
|
|
public void setPosition(int p) {
|
|
|
|
buff.position(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#capacity()
|
|
|
|
*/
|
|
|
|
public int capacity() {
|
|
|
|
return buff.capacity();
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2016-09-08 14:16:07 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param s null String are supported
|
|
|
|
*/
|
2016-07-04 17:13:24 +02:00
|
|
|
public ByteBuffer putString(String s) {
|
2016-09-08 14:16:07 +02:00
|
|
|
if (s == null) {
|
|
|
|
return putInt(-1);
|
|
|
|
}
|
2021-03-21 20:17:31 +01:00
|
|
|
return putSizedByteArray(s.getBytes(NETWORK_CHARSET));
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2016-09-08 14:16:07 +02:00
|
|
|
/**
|
|
|
|
* returned string can be null
|
|
|
|
*/
|
2016-07-04 17:13:24 +02:00
|
|
|
public String getString() {
|
2016-09-08 14:16:07 +02:00
|
|
|
byte[] binaryString = getSizedByteArray();
|
2021-03-21 20:17:31 +01:00
|
|
|
return (binaryString == null) ? null : new String(binaryString, NETWORK_CHARSET);
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2016-09-08 14:16:07 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param list The list can be null, and any String can be null too.
|
|
|
|
*/
|
|
|
|
public ByteBuffer putListOfString(List<String> list) {
|
|
|
|
if (list == null) {
|
|
|
|
return putInt(-1);
|
|
|
|
}
|
|
|
|
putInt(list.size());
|
|
|
|
for (String str : list)
|
|
|
|
putString(str);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return a List of String. The list can be null, and any element can be null too.
|
|
|
|
*/
|
2020-02-08 15:43:19 +01:00
|
|
|
public List<String> getListOfString() {
|
2016-09-08 14:16:07 +02:00
|
|
|
int size = getInt();
|
|
|
|
if (size < 0)
|
|
|
|
return null;
|
|
|
|
List<String> list = new ArrayList<>();
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
list.add(getString());
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2016-07-04 17:13:24 +02:00
|
|
|
/**
|
|
|
|
* @see java.nio.ByteBuffer#array()
|
|
|
|
*/
|
|
|
|
public byte[] array() {
|
|
|
|
return buff.array();
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2016-07-04 17:13:24 +02:00
|
|
|
}
|