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.
221 lines
5.6 KiB
221 lines
5.6 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; |
|
// } |
|
|
|
}
|
|
|