|
|
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
|
|
// Magicbane Emulator Project © 2013 - 2022
|
|
|
|
// www.magicbane.com
|
|
|
|
|
|
|
|
|
|
|
|
package engine.util;
|
|
|
|
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
import java.nio.BufferOverflowException;
|
|
|
|
import java.nio.BufferUnderflowException;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
|
|
|
|
public class ByteBufferUtils {
|
|
|
|
public static String getString(ByteBuffer bb)
|
|
|
|
throws BufferUnderflowException {
|
|
|
|
return getString(bb, false, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getString(ByteBuffer bb, boolean switchEndian, boolean small)
|
|
|
|
throws BufferUnderflowException {
|
|
|
|
String out = "";
|
|
|
|
synchronized (bb) {
|
|
|
|
|
|
|
|
//This version works with non-latin characters
|
|
|
|
int stringLen;
|
|
|
|
if (small)
|
|
|
|
stringLen = (int) bb.get();
|
|
|
|
else
|
|
|
|
stringLen = bb.getInt();
|
|
|
|
if (switchEndian)
|
|
|
|
stringLen = ((Integer.reverseBytes(stringLen)) * 2);
|
|
|
|
else
|
|
|
|
stringLen *= 2;
|
|
|
|
byte[] b = new byte[stringLen];
|
|
|
|
for (int i = 0; i < stringLen; i += 2) {
|
|
|
|
if (switchEndian) {
|
|
|
|
b[i + 1] = bb.get();
|
|
|
|
b[i] = bb.get();
|
|
|
|
} else {
|
|
|
|
b[i] = bb.get();
|
|
|
|
b[i + 1] = bb.get();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
out = new String(b, "UTF-16BE");
|
|
|
|
} catch (UnsupportedEncodingException e) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void putString(ByteBuffer bb, String data, boolean small)
|
|
|
|
throws BufferOverflowException {
|
|
|
|
putString(bb, data, false, small);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void putString(ByteBuffer bb, String data,
|
|
|
|
boolean switchEndian, boolean small) throws BufferOverflowException {
|
|
|
|
if (data == null) {
|
|
|
|
data = "";
|
|
|
|
}
|
|
|
|
char[] chars = data.toCharArray();
|
|
|
|
|
|
|
|
int length = chars.length;
|
|
|
|
if (small && length > 255)
|
|
|
|
length = 255; //limit for smallString
|
|
|
|
|
|
|
|
synchronized (bb) {
|
|
|
|
// Write length
|
|
|
|
if (small)
|
|
|
|
bb.put((byte) length);
|
|
|
|
else {
|
|
|
|
if (switchEndian) {
|
|
|
|
bb.putInt(Integer.reverseBytes(length));
|
|
|
|
} else {
|
|
|
|
bb.putInt(length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write chars
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
char c = chars[i];
|
|
|
|
if (switchEndian) {
|
|
|
|
bb.putChar(Character.reverseBytes(c));
|
|
|
|
} else {
|
|
|
|
bb.putChar(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getHexString(ByteBuffer bb)
|
|
|
|
throws BufferUnderflowException {
|
|
|
|
return getHexString(bb, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getHexString(ByteBuffer bb, boolean switchEndian)
|
|
|
|
throws BufferUnderflowException {
|
|
|
|
String out = "";
|
|
|
|
synchronized (bb) {
|
|
|
|
// Read len
|
|
|
|
int stringLen = bb.getInt();
|
|
|
|
|
|
|
|
if (switchEndian) {
|
|
|
|
stringLen = Integer.reverseBytes(stringLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read len worth of chars
|
|
|
|
for (int i = 0; i < stringLen; ++i) {
|
|
|
|
out += Integer.toString((bb.get() & 0xff) + 0x100, 16)
|
|
|
|
.substring(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void putHexString(ByteBuffer bb, String data)
|
|
|
|
throws BufferOverflowException {
|
|
|
|
putHexString(bb, data, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void putHexString(ByteBuffer bb, String data,
|
|
|
|
boolean switchEndian) throws BufferOverflowException {
|
|
|
|
|
|
|
|
if (data == null) {
|
|
|
|
data = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
byte[] bts = new byte[data.length() / 2];
|
|
|
|
|
|
|
|
for (int i = 0; i < bts.length; i++) {
|
|
|
|
bts[i] = (byte) Integer.parseInt(data.substring(2 * i, 2 * i + 1),
|
|
|
|
16);
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (bb) {
|
|
|
|
if (switchEndian) {
|
|
|
|
bb.putInt(Integer.reverseBytes(data.length() / 2));
|
|
|
|
} else {
|
|
|
|
bb.putInt(data.length() / 2);
|
|
|
|
}
|
|
|
|
bb.put(bts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getUnicodeString(ByteBuffer bb)
|
|
|
|
throws BufferUnderflowException {
|
|
|
|
return getUnicodeString(bb, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getUnicodeString(ByteBuffer bb, boolean switchEndian)
|
|
|
|
throws BufferUnderflowException {
|
|
|
|
byte[] out;
|
|
|
|
short thisChar;
|
|
|
|
synchronized (bb) {
|
|
|
|
// Read len
|
|
|
|
int stringLen = bb.getInt();
|
|
|
|
if (switchEndian) {
|
|
|
|
stringLen = Integer.reverseBytes(stringLen);
|
|
|
|
}
|
|
|
|
out = new byte[stringLen];
|
|
|
|
// Read len worth of chars
|
|
|
|
for (int i = 0; i < stringLen; ++i) {
|
|
|
|
thisChar = bb.getShort();
|
|
|
|
if (switchEndian)
|
|
|
|
Short.reverseBytes(thisChar);
|
|
|
|
out[i] = (byte) (thisChar & 0xff); // ignore first byte
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new String(out);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void putUnicodeString(ByteBuffer bb, String data)
|
|
|
|
throws BufferOverflowException {
|
|
|
|
putUnicodeString(bb, data, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void putUnicodeString(ByteBuffer bb, String data,
|
|
|
|
boolean switchEndian) throws BufferOverflowException {
|
|
|
|
byte[] out;
|
|
|
|
short thisChar;
|
|
|
|
if (data == null)
|
|
|
|
return;
|
|
|
|
out = new byte[data.length()];
|
|
|
|
out = data.getBytes();
|
|
|
|
|
|
|
|
for (byte b : out) {
|
|
|
|
thisChar = b;
|
|
|
|
if (switchEndian)
|
|
|
|
thisChar = Short.reverseBytes(thisChar);
|
|
|
|
bb.putShort(thisChar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean checkByteBufferNearFull(ByteBuffer bb) {
|
|
|
|
return bb.position() >= (bb.capacity() * 0.9);
|
|
|
|
}
|
|
|
|
|
|
|
|
//FIXME: Replace these!!!
|
|
|
|
// public static ByteBuffer resizeByteBuffer(ByteBuffer bb, int multiplyer) {
|
|
|
|
//
|
|
|
|
// ByteBuffer out = ByteBuffer.allocate(bb.capacity() * multiplyer);
|
|
|
|
//
|
|
|
|
// // Copy the data to a temp buf
|
|
|
|
// bb.flip();
|
|
|
|
// out.put(bb);
|
|
|
|
//
|
|
|
|
// return out;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public static ByteBuffer shrinkByteBuffer(ByteBuffer bb) {
|
|
|
|
//
|
|
|
|
// bb.flip();
|
|
|
|
// ByteBuffer out = ByteBuffer.allocate(bb.remaining());
|
|
|
|
// out.put(bb);
|
|
|
|
// return out;
|
|
|
|
// }
|
|
|
|
|
|
|
|
}
|