224 lines
5.1 KiB
Java
224 lines
5.1 KiB
Java
package it.cavallium.buffer;
|
|
|
|
import it.cavallium.stream.SafeByteArrayInputStream;
|
|
import it.cavallium.stream.SafeByteArrayOutputStream;
|
|
import it.cavallium.stream.SafeDataOutput;
|
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
|
import it.unimi.dsi.fastutil.bytes.ByteList;
|
|
import java.nio.charset.Charset;
|
|
import java.util.RandomAccess;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.jetbrains.annotations.VisibleForTesting;
|
|
|
|
public interface Buf extends ByteList, RandomAccess {
|
|
static Buf wrap(ByteList bytes) {
|
|
if (bytes instanceof Buf buf) {
|
|
return buf;
|
|
} else if (bytes instanceof ByteArrayList byteArrayList) {
|
|
return ByteListBuf.wrap(byteArrayList.elements(), byteArrayList.size());
|
|
} else {
|
|
return ByteListBuf.wrap(bytes.toByteArray());
|
|
}
|
|
}
|
|
static Buf wrap(ByteList bytes, int from, int to) {
|
|
if (bytes instanceof Buf buf) {
|
|
return buf.subList(from, to);
|
|
} else if (bytes instanceof ByteArrayList byteArrayList) {
|
|
return ByteListBuf.wrap(byteArrayList.elements(), byteArrayList.size()).subList(from, to);
|
|
} else {
|
|
return ByteListBuf.wrap(bytes.toByteArray()).subList(from, to);
|
|
}
|
|
}
|
|
|
|
static Buf wrap(byte... bytes) {
|
|
return ByteListBuf.wrap(bytes);
|
|
}
|
|
|
|
static Buf wrap(byte[] bytes, int from, int to) {
|
|
return ByteListBuf.wrap(bytes, to).subList(from, to);
|
|
}
|
|
|
|
static Buf create(int initialCapacity) {
|
|
return new ByteListBuf(initialCapacity);
|
|
}
|
|
|
|
static Buf copyOf(byte[] original) {
|
|
return new ByteListBuf(original);
|
|
}
|
|
|
|
static Buf create() {
|
|
return new ByteListBuf();
|
|
}
|
|
|
|
static Buf wrap(byte[] array, int length) {
|
|
return ByteListBuf.wrap(array, length);
|
|
}
|
|
|
|
static Buf createZeroes(int length) {
|
|
return ByteListBuf.wrap(new byte[length], length);
|
|
}
|
|
|
|
/**
|
|
* Get this element as an array, converting it if needed
|
|
*/
|
|
byte @NotNull[] asArray();
|
|
|
|
/**
|
|
* Get this element as an array, only if it's already an array, otherwise return null
|
|
*/
|
|
byte @Nullable[] asArrayStrict();
|
|
|
|
/**
|
|
* Get this element as an array with equal or bigger size, converting it if needed
|
|
* The returned array may be bigger than expected!
|
|
*/
|
|
byte[] asUnboundedArray();
|
|
|
|
/**
|
|
* Get this element as an array with equal or bigger size, only if it's already an array, otherwise return null
|
|
* The returned array may be bigger than expected!
|
|
*/
|
|
byte @Nullable[] asUnboundedArrayStrict();
|
|
|
|
boolean isMutable();
|
|
|
|
Buf freeze();
|
|
|
|
@Override
|
|
Buf subList(int from, int to);
|
|
|
|
@VisibleForTesting
|
|
Buf subListForced(int from, int to);
|
|
|
|
Buf copyOfRange(int from, int to);
|
|
|
|
Buf copy();
|
|
|
|
SafeByteArrayInputStream binaryInputStream();
|
|
|
|
void writeTo(SafeDataOutput dataOutput);
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default long getLong(int i) {
|
|
byte b1 = getByte(i);
|
|
byte b2 = getByte(i + 1);
|
|
byte b3 = getByte(i + 2);
|
|
byte b4 = getByte(i + 3);
|
|
byte b5 = getByte(i + 4);
|
|
byte b6 = getByte(i + 5);
|
|
byte b7 = getByte(i + 6);
|
|
byte b8 = getByte(i + 7);
|
|
return (b1 & 0xFFL) << 56
|
|
| (b2 & 0xFFL) << 48
|
|
| (b3 & 0xFFL) << 40
|
|
| (b4 & 0xFFL) << 32
|
|
| (b5 & 0xFFL) << 24
|
|
| (b6 & 0xFFL) << 16
|
|
| (b7 & 0xFFL) << 8
|
|
| (b8 & 0xFFL);
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default int getInt(int i) {
|
|
byte b1 = getByte(i);
|
|
byte b2 = getByte(i + 1);
|
|
byte b3 = getByte(i + 2);
|
|
byte b4 = getByte(i + 3);
|
|
return b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default float getFloat(int i) {
|
|
return Float.intBitsToFloat(getInt(i));
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default double getDouble(int i) {
|
|
return Double.longBitsToDouble(getLong(i));
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default boolean getBoolean(int i) {
|
|
return getByte(i) != 0;
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default void setBoolean(int i, boolean val) {
|
|
set(i, val ? (byte) 1 : 0);
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default void setByte(int i, byte val) {
|
|
set(i, val);
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default void setInt(int i, int val) {
|
|
set(i, (byte) (val >> 24));
|
|
set(i + 1, (byte) (val >> 16));
|
|
set(i + 2, (byte) (val >> 8));
|
|
set(i + 3, (byte) val);
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default void setLong(int i, long val) {
|
|
set(i, (byte) (val >> 56));
|
|
set(i + 1, (byte) (val >> 48));
|
|
set(i + 2, (byte) (val >> 40));
|
|
set(i + 3, (byte) (val >> 32));
|
|
set(i + 4, (byte) (val >> 24));
|
|
set(i + 5, (byte) (val >> 16));
|
|
set(i + 6, (byte) (val >> 8));
|
|
set(i + 7, (byte) val);
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default void setFloat(int i, float val) {
|
|
setInt(i, Float.floatToRawIntBits(val));
|
|
}
|
|
|
|
/**
|
|
* @param i byte offset
|
|
*/
|
|
default void setDouble(int i, double val) {
|
|
setLong(i, Double.doubleToRawLongBits(val));
|
|
}
|
|
|
|
default SafeByteArrayOutputStream binaryOutputStream() {
|
|
return binaryOutputStream(0, size());
|
|
}
|
|
|
|
default SafeByteArrayOutputStream binaryOutputStream(int from) {
|
|
return binaryOutputStream(from, size());
|
|
}
|
|
|
|
SafeByteArrayOutputStream binaryOutputStream(int from, int to);
|
|
|
|
boolean equals(int aStartIndex, Buf b, int bStartIndex, int length);
|
|
|
|
boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length);
|
|
|
|
String toString(Charset charset);
|
|
}
|