package anastore.util;

import java.io.IOException;
import java.io.OutputStream;

/**
 * A utility class to pretty-print hex dumps of binary data.
 */
public class HexDump
{
    /**
     * HexDump is pure static.
     */
    private HexDump()
    {
    }

    public static void dump(OutputStream os, byte[] data)
    {
        StringBuilder out = new StringBuilder();

        for (int start = 0; start < data.length; start += 16) {
            out.append(String.format(data.length < 0x10000 ? "%04x  " : "%08x  ",
                                     start));

            for (int pos = start; pos < start+16; ++pos) {
                if (pos < data.length)
                    out.append(String.format("%02x", data[pos]));
                else
                    out.append("  ");

                if (pos%8 == 3 && pos < data.length)
                    out.append('-');
                else if (pos%8 == 7)
                    out.append("  ");
                else
                    out.append(' ');
            }

            for (int pos = start; pos < start+16 && pos < data.length; ++pos) {
                byte b = data[pos];
                if (b >= 32 && b < 127)
                    out.append((char)b);
                else
                    out.append('.');
            }

            out.append('\n');
        }

        try {
            os.write(out.toString().getBytes());
        } catch (IOException e) {
            // Ignore
        }
    }

    public static void dump(byte[] data)
    {
        dump(System.err, data);
    }

    public static void dump(OutputStream os, java.nio.ByteBuffer buf)
    {
        byte[] data;
        if (buf.hasArray()) {
            data = buf.array();
        } else {
            data = new byte[buf.limit()];
            buf.get(data);
        }
        dump(os, data);
    }

    public static void dump(java.nio.ByteBuffer buf)
    {
        dump(System.err, buf);
    }

    public static void dump(OutputStream os, java.io.ByteArrayOutputStream buf)
    {
        dump(os, buf.toByteArray());
    }

    public static void dump(java.io.ByteArrayOutputStream buf)
    {
        dump(System.err, buf);
    }

    public static String summarize(byte[] data, int length)
    {
        StringBuilder res = new StringBuilder();

        int i;
        for (i = 0; i < data.length && i < length; ++i) {
            if (i != 0)
                res.append(' ');
            res.append(String.format("%02x", data[i]));
        }

        if (i < data.length)
            res.append(" ...");

        return res.toString();
    }
}
