Public Repository for the Magicbane Shadowbane Emulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
7.0 KiB

// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// 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;
// }
}