package net.scapeemulator.cache.util;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import net.scapeemulator.cache.util.crypto.Whirlpool;
/**
* Contains {@link ByteBuffer}-related utility methods.
*
* @author Graham
* @author `Discardedx2
*/
public final class ByteBufferUtils {
/**
* The modified set of 'extended ASCII' characters used by the client.
*/
private static char CHARACTERS[] = { '\u20AC', '\0', '\u201A', '\u0192', '\u201E', '\u2026', '\u2020', '\u2021', '\u02C6', '\u2030', '\u0160', '\u2039', '\u0152', '\0', '\u017D', '\0', '\0',
'\u2018', '\u2019', '\u201C', '\u201D', '\u2022', '\u2013', '\u2014', '\u02DC', '\u2122', '\u0161', '\u203A', '\u0153', '\0', '\u017E', '\u0178' };
public static String getString(ByteBuffer buf) {
StringBuilder bldr = new StringBuilder();
int b;
while ((b = (buf.get() & 0xFF)) != 0) {
bldr.append((char) b);
}
return bldr.toString();
}
/**
* Gets a null-terminated string from the specified buffer, using a modified ISO-8859-1
* character set.
*
* @param buf The buffer.
* @return The decoded string.
*/
public static String getJagexString(ByteBuffer buf) {
StringBuilder bldr = new StringBuilder();
int b;
while ((b = (buf.get() & 0xFF)) != 0) {
if (b >= 127 && b < 160) {
char curChar = CHARACTERS[b - 128];
if (curChar != 0) {
bldr.append(curChar);
}
} else {
bldr.append((char) b);
}
}
return bldr.toString();
}
public static void putJagexString(OutputStream os, String s) throws IOException {
for (char c : s.toCharArray()) {
os.write((byte) c);
}
os.write(0);
}
/**
* Reads a 'tri-byte' from the specified buffer.
*
* @param buf The buffer.
* @return The value.
*/
public static int getTriByte(ByteBuffer buf) {
return ((buf.get() & 0xFF) << 16) | ((buf.get() & 0xFF) << 8) | (buf.get() & 0xFF);
}
/**
* Writes a 'tri-byte' to the specified buffer.
*
* @param buf The buffer.
* @param value The value.
*/
public static void putTriByte(ByteBuffer buf, int value) {
buf.put((byte) (value >> 16));
buf.put((byte) (value >> 8));
buf.put((byte) value);
}
/**
* Calculates the CRC32 checksum of the specified buffer.
*
* @param buffer The buffer.
* @return The CRC32 checksum.
*/
public static int getCrcChecksum(ByteBuffer buffer) {
Checksum crc = new CRC32();
for (int i = 0; i < buffer.limit(); i++) {
crc.update(buffer.get(i));
}
return (int) crc.getValue();
}
/**
* Calculates the whirlpool digest of the specified buffer.
*
* @param buf The buffer.
* @return The 64-byte whirlpool digest.
*/
public static byte[] getWhirlpoolDigest(ByteBuffer buf) {
byte[] bytes = new byte[buf.limit()];
buf.get(bytes);
return Whirlpool.whirlpool(bytes, 0, bytes.length);
}
public static int getSmart(ByteBuffer buf) {
int peek = buf.get(buf.position()) & 0xFF;
if (peek < 128) {
return buf.get() & 0xFF;
} else {
return (buf.getShort() & 0xFFFF) - 32768;
}
}
public static int method797(ByteBuffer buf) {
int peek = buf.get(buf.position()) & 0xFF;
return ~peek > -129 ? -64 + (buf.get() & 0xFF) : (buf.getShort() & 0xFFFF) - '\uc000';
}
/**
* Converts the contents of the specified byte buffer to a string, which is formatted similarly
* to the output of the {@link Arrays#toString()} method.
*
* @param buffer The buffer.
* @return The string.
*/
public static String toString(ByteBuffer buffer) {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < buffer.limit(); i++) {
String hex = Integer.toHexString(buffer.get(i) & 0xFF).toUpperCase();
if (hex.length() == 1)
hex = "0" + hex;
builder.append("0x").append(hex);
if (i != buffer.limit() - 1) {
builder.append(", ");
}
}
builder.append("]");
return builder.toString();
}
/**
* Default private constructor to prevent instantiation.
*/
private ByteBufferUtils() {
}
}