183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/*
283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * [The "BSD licence"]
300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke)
483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * All rights reserved.
583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *
683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without
783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions
883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * are met:
983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright
1083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer.
1183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright
1283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer in the
1383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    documentation and/or other materials provided with the distribution.
1483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products
1583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    derived from this software without specific prior written permission.
1683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *
1783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */
2883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
299f1d05eb44d85183651753d9b83ae3115a8ea256Ben Gruverpackage org.jf.util;
3083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
3183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/**
3283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Utilities for formatting numbers as hexadecimal.
3383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */
3483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compublic final class Hex {
3583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
3683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * This class is uninstantiable.
3783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
3883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private Hex() {
3983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        // This space intentionally left blank.
4083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
4183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
4283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
4383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats a <code>long</code> as an 8-byte unsigned hex value.
4483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
4583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
4683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
4783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
4883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String u8(long v) {
4983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[16];
5083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 16; i++) {
5183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[15 - i] = Character.forDigit((int) v & 0x0f, 16);
5283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
5383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
5483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
5583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
5683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
5783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
5883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
5983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 4-byte unsigned hex value.
6083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
6183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
6283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
6383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
6483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String u4(int v) {
6583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[8];
6683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 8; i++) {
6783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[7 - i] = Character.forDigit(v & 0x0f, 16);
6883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
6983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
7083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
7183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
7283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
7383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
7483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
7583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 3-byte unsigned hex value.
7683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
7783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
7883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
7983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
8083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String u3(int v) {
8183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[6];
8283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 6; i++) {
8383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[5 - i] = Character.forDigit(v & 0x0f, 16);
8483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
8583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
8683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
8783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
8883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
8983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
9083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
9183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 2-byte unsigned hex value.
9283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
9383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
9483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
9583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
9683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String u2(int v) {
9783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[4];
9883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 4; i++) {
9983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[3 - i] = Character.forDigit(v & 0x0f, 16);
10083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
10183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
10283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
10383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
10483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
10583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
10683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
10783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as either a 2-byte unsigned hex value
10883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * (if the value is small enough) or a 4-byte unsigned hex value (if
10983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * not).
11083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
11183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
11283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
11383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
11483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String u2or4(int v) {
11583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (v == (char) v) {
11683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            return u2(v);
11783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
11883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            return u4(v);
11983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
12083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
12183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
12283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
12383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 1-byte unsigned hex value.
12483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
12583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
12683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
12783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
12883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String u1(int v) {
12983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[2];
13083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 2; i++) {
13183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[1 - i] = Character.forDigit(v & 0x0f, 16);
13283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
13383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
13483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
13583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
13683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
13783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
13883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
13983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 4-bit unsigned hex nibble.
14083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
14183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
14283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
14383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
14483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String uNibble(int v) {
14583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[1];
14683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
14783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        result[0] = Character.forDigit(v & 0x0f, 16);
14883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
14983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
15083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
15183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
15283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats a <code>long</code> as an 8-byte signed hex value.
15383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
15483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
15583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
15683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
15783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String s8(long v) {
15883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[17];
15983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
16083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (v < 0) {
16183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '-';
16283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v = -v;
16383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
16483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '+';
16583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
16683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
16783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 16; i++) {
16883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[16 - i] = Character.forDigit((int) v & 0x0f, 16);
16983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
17083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
17183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
17283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
17383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
17483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
17583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
17683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 4-byte signed hex value.
17783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
17883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
17983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
18083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
18183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String s4(int v) {
18283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[9];
18383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
18483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (v < 0) {
18583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '-';
18683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v = -v;
18783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
18883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '+';
18983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
19083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
19183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 8; i++) {
19283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[8 - i] = Character.forDigit(v & 0x0f, 16);
19383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
19483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
19583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
19683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
19783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
19883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
19983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
20083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 2-byte signed hex value.
20183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
20283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
20383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
20483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
20583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String s2(int v) {
20683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[5];
20783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
20883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (v < 0) {
20983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '-';
21083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v = -v;
21183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
21283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '+';
21383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
21483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
21583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 4; i++) {
21683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[4 - i] = Character.forDigit(v & 0x0f, 16);
21783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
21883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
21983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
22083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
22183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
22283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
22383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
22483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats an <code>int</code> as a 1-byte signed hex value.
22583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
22683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param v value to format
22783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; formatted form
22883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
22983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String s1(int v) {
23083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        char[] result = new char[3];
23183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
23283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (v < 0) {
23383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '-';
23483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v = -v;
23583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
23683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[0] = '+';
23783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
23883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
23983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i = 0; i < 2; i++) {
24083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            result[2 - i] = Character.forDigit(v & 0x0f, 16);
24183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            v >>= 4;
24283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
24383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
24483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return new String(result);
24583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
24683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
24783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
24883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Formats a hex dump of a portion of a <code>byte[]</code>. The result
24983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * is always newline-terminated, unless the passed-in length was zero,
25083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * in which case the result is always the empty string (<code>""</code>).
25183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
25283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param arr non-null; array to format
25383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param offset &gt;= 0; offset to the part to dump
25483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param length &gt;= 0; number of bytes to dump
25583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param outOffset &gt;= 0; first output offset to print
25683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param bpl &gt;= 0; number of bytes of output per line
25783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param addressLength {2,4,6,8}; number of characters for each address
25883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * header
25983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; a string of the dump
26083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
26183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static String dump(byte[] arr, int offset, int length,
26283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                              int outOffset, int bpl, int addressLength) {
26383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        int end = offset + length;
26483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
26583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
26683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (((offset | length | end) < 0) || (end > arr.length)) {
26783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            throw new IndexOutOfBoundsException("arr.length " +
26883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                                                arr.length + "; " +
26983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                                                offset + "..!" + end);
27083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
27183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
27283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (outOffset < 0) {
27383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            throw new IllegalArgumentException("outOffset < 0");
27483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
27583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
27683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (length == 0) {
27783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            return "";
27883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
27983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
28083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        StringBuffer sb = new StringBuffer(length * 4 + 6);
28183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        boolean bol = true;
28283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        int col = 0;
28383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
28483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        while (length > 0) {
28583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            if (col == 0) {
28683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                String astr;
28783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                switch (addressLength) {
28883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                    case 2:  astr = Hex.u1(outOffset); break;
28983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                    case 4:  astr = Hex.u2(outOffset); break;
29083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                    case 6:  astr = Hex.u3(outOffset); break;
29183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                    default: astr = Hex.u4(outOffset); break;
29283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                }
29383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                sb.append(astr);
29483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                sb.append(": ");
29583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            } else if ((col & 1) == 0) {
29683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                sb.append(' ');
29783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            }
29883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sb.append(Hex.u1(arr[offset]));
29983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            outOffset++;
30083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            offset++;
30183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            col++;
30283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            if (col == bpl) {
30383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                sb.append('\n');
30483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                col = 0;
30583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            }
30683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            length--;
30783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
30883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
30983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (col != 0) {
31083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sb.append('\n');
31183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
31283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
31383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return sb.toString();
31483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
31583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com}