/* Util.java -- Miscellaneous utility methods.
   Copyright (C) 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.security.x509;

/**
 * A collection of useful class methods.
 *
 * @author Casey Marshall (rsdio@metastatic.org)
 */
public final class Util
{

  // Constants.
  // -------------------------------------------------------------------------

  public static final String HEX = "0123456789abcdef";

  // Class methods.
  // -------------------------------------------------------------------------

  /**
   * Convert a byte array to a hexadecimal string, as though it were a
   * big-endian arbitrarily-sized integer.
   *
   * @param buf The bytes to format.
   * @param off The offset to start at.
   * @param len The number of bytes to format.
   * @return A hexadecimal representation of the specified bytes.
   */
  public static String toHexString(byte[] buf, int off, int len)
  {
    StringBuffer str = new StringBuffer();
    for (int i = 0; i < len; i++)
      {
        str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
        str.append(HEX.charAt(buf[i+off] & 0x0F));
      }
    return str.toString();
  }

  /**
   * See {@link #toHexString(byte[],int,int)}.
   */
  public static String toHexString(byte[] buf)
  {
    return Util.toHexString(buf, 0, buf.length);
  }

  /**
   * Convert a byte array to a hexadecimal string, separating octets
   * with the given character.
   *
   * @param buf The bytes to format.
   * @param off The offset to start at.
   * @param len The number of bytes to format.
   * @param sep The character to insert between octets.
   * @return A hexadecimal representation of the specified bytes.
   */
  public static String toHexString(byte[] buf, int off, int len, char sep)
  {
    StringBuffer str = new StringBuffer();
    for (int i = 0; i < len; i++)
      {
        str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F));
        str.append(HEX.charAt(buf[i+off] & 0x0F));
        if (i < len - 1)
          str.append(sep);
      }
    return str.toString();
  }

  /**
   * See {@link #toHexString(byte[],int,int,char)}.
   */
  public static String toHexString(byte[] buf, char sep)
  {
    return Util.toHexString(buf, 0, buf.length, sep);
  }

  /**
   * Create a representation of the given byte array similar to the
   * output of `hexdump -C', which is
   *
   * <p><pre>OFFSET  SIXTEEN-BYTES-IN-HEX  PRINTABLE-BYTES</pre>
   *
   * <p>The printable bytes show up as-is if they are printable and
   * not a newline character, otherwise showing as '.'.
   *
   * @param buf The bytes to format.
   * @param off The offset to start at.
   * @param len The number of bytes to encode.
   * @return The formatted string.
   */
  public static String hexDump(byte[] buf, int off, int len, String prefix)
  {
    String nl = System.getProperty("line.separator");
    StringBuffer str = new StringBuffer();
    int i = 0;
    while (i < len)
      {
        str.append(prefix);
        str.append(Util.formatInt(i+off, 16, 8));
        str.append("  ");
        String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' ');
        str.append(s);
        for (int j = 56 - (56 - s.length()); j < 56; j++)
          str.append(" ");
        for (int j = 0; j < Math.min(16, len - i); j++)
          {
            if ((buf[i+off+j] & 0xFF) < 0x20 || (buf[i+off+j] & 0xFF) > 0x7E)
              str.append('.');
            else
              str.append((char) (buf[i+off+j] & 0xFF));
          }
        str.append(nl);
        i += 16;
      }
    return str.toString();
  }

  /**
   * See {@link #hexDump(byte[],int,int)}.
   */
  public static String hexDump(byte[] buf, String prefix)
  {
    return hexDump(buf, 0, buf.length, prefix);
  }

  /**
   * Format an integer into the specified radix, zero-filled.
   *
   * @param i The integer to format.
   * @param radix The radix to encode to.
   * @param len The target length of the string. The string is
   *   zero-padded to this length, but may be longer.
   * @return The formatted integer.
   */
  public static String formatInt(int i, int radix, int len)
  {
    String s = Integer.toString(i, radix);
    StringBuffer buf = new StringBuffer();
    for (int j = 0; j < len - s.length(); j++)
      buf.append("0");
    buf.append(s);
    return buf.toString();
  }

  /**
   * Convert a hexadecimal string into its byte representation.
   *
   * @param hex The hexadecimal string.
   * @return The converted bytes.
   */
  public static byte[] toByteArray(String hex)
  {
    hex = hex.toLowerCase();
    byte[] buf = new byte[hex.length() / 2];
    int j = 0;
    for (int i = 0; i < buf.length; i++)
      {
        buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) |
                          Character.digit(hex.charAt(j++), 16));
      }
    return buf;
  }
}
