package the8472.bencode;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public class Utils {
/*
* all byte[]/buffer/String conversions use ISO_8859_1 by default because it's round-trip compatible to unicode codepoints 0-255. i.e. it's suitable for binary data of unspecified encodings.
*
* this will garble actual UTF-8 strings, decode those manually if it's meant to be human-readable
*/
public static void str2buf(String in, ByteBuffer out) {
if(out.remaining() < in.length())
throw new BufferOverflowException();
for(int i=0;i<in.length();i++) {
char c = in.charAt(i);
if(c > 0xff)
throw new IllegalArgumentException("only strings with codepoints 0x00 - 0xff are supported. for proper unicode handling convert strings manually. attempted to encode: "+in);
out.put((byte) c);
}
}
public static ByteBuffer str2buf(String str) {
return ByteBuffer.wrap(str.getBytes(StandardCharsets.ISO_8859_1));
}
public static String buf2str(ByteBuffer buf) {
byte[] arr;
int offset;
int len;
if(buf.hasArray()) {
arr = buf.array();
offset = buf.arrayOffset() + buf.position();
len = buf.remaining();
} else {
arr = new byte[buf.remaining()];
buf.get(arr, buf.position(), arr.length);
offset = 0;
len = arr.length;
}
return new String(arr,offset,len, StandardCharsets.ISO_8859_1);
}
public static byte[] buf2ary(ByteBuffer buf) {
byte[] out = new byte[buf.remaining()];
buf.get(out);
return out;
}
public static byte[] str2ary(String str) {
return str.getBytes(StandardCharsets.ISO_8859_1);
}
public static String prettyPrint(Object o) {
StringBuilder b = new StringBuilder(1024);
new PrettyPrinter(b).prettyPrintInternal(o);
return b.toString();
}
public static String stripToAscii(byte[] arr) {
return stripToAscii(ByteBuffer.wrap(arr));
}
public static String stripToAscii(ByteBuffer buf) {
int length = buf.remaining();
char[] out = new char[buf.remaining()];
for(int i=0;i<length ;i++) {
char b = (char)(buf.get(buf.position() + i) & 0xff);
if(b < ' ' || b > '~')
b = '�';
out[i] = b;
}
return new String(out);
}
static void toHex(byte[] toHex, StringBuilder builder, int maxBytes)
{
if(toHex.length < maxBytes)
maxBytes = toHex.length;
builder.ensureCapacity(maxBytes * 2);
for (int i = 0; i < maxBytes; i++) {
int nibble = (toHex[i] & 0xF0) >> 4;
builder.append((char)(nibble < 0x0A ? '0'+nibble : 'A'+nibble-10 ));
nibble = toHex[i] & 0x0F;
builder.append((char)(nibble < 0x0A ? '0'+nibble : 'A'+nibble-10 ));
}
}
public static byte[] hex2ary(CharSequence hex) {
byte[] bytes = new byte[hex.length()/2];
for (int i = 0; i < hex.length(); i += 2)
bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16));
return bytes;
}
}