// Copyright 2005 Nick Mathewson, Roger Dingledine // See LICENSE file for copying information package net.freehaven.tor.control; import java.util.Arrays; import java.util.List; /** * Static class to do bytewise structure manipulation in Java. */ /* XXXX There must be a better way to do most of this. * XXXX The string logic here uses default encoding, which is stupid. */ final class Bytes { /** * Write the two-byte value in 's' into the byte array 'ba', starting at * the index 'pos'. */ public static void setU16(byte[] ba, int pos, short s) { ba[pos] = (byte) ((s >> 8) & 0xff); ba[pos + 1] = (byte) ((s) & 0xff); } /** * Write the four-byte value in 'i' into the byte array 'ba', starting at * the index 'pos'. */ public static void setU32(byte[] ba, int pos, int i) { ba[pos] = (byte) ((i >> 24) & 0xff); ba[pos + 1] = (byte) ((i >> 16) & 0xff); ba[pos + 2] = (byte) ((i >> 8) & 0xff); ba[pos + 3] = (byte) ((i) & 0xff); } /** * Return the four-byte value starting at index 'pos' within 'ba' */ public static int getU32(byte[] ba, int pos) { return ((ba[pos] & 0xff) << 24) | ((ba[pos + 1] & 0xff) << 16) | ((ba[pos + 2] & 0xff) << 8) | ((ba[pos + 3] & 0xff)); } public static String getU32S(byte[] ba, int pos) { return String.valueOf((getU32(ba, pos)) & 0xffffffffL); } /** * Return the two-byte value starting at index 'pos' within 'ba' */ public static int getU16(byte[] ba, int pos) { return ((ba[pos] & 0xff) << 8) | ((ba[pos + 1] & 0xff)); } /** * Return the string starting at position 'pos' of ba and extending * until a zero byte or the end of the string. */ public static String getNulTerminatedStr(byte[] ba, int pos) { int len, maxlen = ba.length - pos; for (len = 0; len < maxlen; ++len) { if (ba[pos + len] == 0) break; } return new String(ba, pos, len); } /** * Read bytes from 'ba' starting at 'pos', dividing them into strings * along the character in 'split' and writing them into 'lst' */ public static void splitStr(List<String> lst, byte[] ba, int pos, byte split) { while (pos < ba.length && ba[pos] != 0) { int len; for (len = 0; pos + len < ba.length; ++len) { if (ba[pos + len] == 0 || ba[pos + len] == split) break; } if (len > 0) lst.add(new String(ba, pos, len)); pos += len; if (ba[pos] == split) ++pos; } } /** * Read bytes from 'ba' starting at 'pos', dividing them into strings * along the character in 'split' and writing them into 'lst' */ public static List<String> splitStr(List<String> lst, String str) { // split string on spaces, include trailing/leading String[] tokenArray = str.split(" ", -1); if (lst == null) { lst = Arrays.asList(tokenArray); } else { lst.addAll(Arrays.asList(tokenArray)); } return lst; } private static final char[] NYBBLES = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; public static final String hex(byte[] ba) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < ba.length; ++i) { int b = (ba[i]) & 0xff; buf.append(NYBBLES[b >> 4]); buf.append(NYBBLES[b & 0x0f]); } return buf.toString(); } private Bytes() { } ; }