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