/* Util.java -- various utility routines.
   Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.

This file is a 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 of the License, 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; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
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.util;

import gnu.java.lang.CPStringBuilder;

import java.math.BigInteger;

/**
 * A collection of utility methods used throughout this project.
 */
public class Util
{
  // Hex charset
  private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

  // Base-64 charset
  private static final String BASE64_CHARS =
      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";

  private static final char[] BASE64_CHARSET = BASE64_CHARS.toCharArray();

  /** Trivial constructor to enforce Singleton pattern. */
  private Util()
  {
    super();
  }

  /**
   * Returns a string of hexadecimal digits from a byte array. Each byte is
   * converted to 2 hex symbols; zero(es) included.
   * <p>
   * This method calls the method with same name and three arguments as:
   * <pre>
   * toString(ba, 0, ba.length);
   * </pre>
   *
   * @param ba the byte array to convert.
   * @return a string of hexadecimal characters (two for each byte) representing
   *         the designated input byte array.
   */
  public static String toString(byte[] ba)
  {
    return toString(ba, 0, ba.length);
  }

  /**
   * Returns a string of hexadecimal digits from a byte array, starting at
   * <code>offset</code> and consisting of <code>length</code> bytes. Each
   * byte is converted to 2 hex symbols; zero(es) included.
   *
   * @param ba the byte array to convert.
   * @param offset the index from which to start considering the bytes to
   *          convert.
   * @param length the count of bytes, starting from the designated offset to
   *          convert.
   * @return a string of hexadecimal characters (two for each byte) representing
   *         the designated input byte sub-array.
   */
  public static final String toString(byte[] ba, int offset, int length)
  {
    char[] buf = new char[length * 2];
    for (int i = 0, j = 0, k; i < length;)
      {
        k = ba[offset + i++];
        buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
        buf[j++] = HEX_DIGITS[ k        & 0x0F];
      }
    return new String(buf);
  }

  /**
   * Returns a string of hexadecimal digits from a byte array. Each byte is
   * converted to 2 hex symbols; zero(es) included. The argument is treated as a
   * large little-endian integer and is returned as a large big-endian integer.
   * <p>
   * This method calls the method with same name and three arguments as:
   * <pre>
   * toReversedString(ba, 0, ba.length);
   * </pre>
   *
   * @param ba the byte array to convert.
   * @return a string of hexadecimal characters (two for each byte) representing
   *         the designated input byte array.
   */
  public static String toReversedString(byte[] ba)
  {
    return toReversedString(ba, 0, ba.length);
  }

  /**
   * Returns a string of hexadecimal digits from a byte array, starting at
   * <code>offset</code> and consisting of <code>length</code> bytes. Each
   * byte is converted to 2 hex symbols; zero(es) included.
   * <p>
   * The byte array is treated as a large little-endian integer, and is returned
   * as a large big-endian integer.
   *
   * @param ba the byte array to convert.
   * @param offset the index from which to start considering the bytes to
   *          convert.
   * @param length the count of bytes, starting from the designated offset to
   *          convert.
   * @return a string of hexadecimal characters (two for each byte) representing
   *         the designated input byte sub-array.
   */
  public static final String toReversedString(byte[] ba, int offset, int length)
  {
    char[] buf = new char[length * 2];
    for (int i = offset + length - 1, j = 0, k; i >= offset;)
      {
        k = ba[offset + i--];
        buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
        buf[j++] = HEX_DIGITS[ k        & 0x0F];
      }
    return new String(buf);
  }

  /**
   * <p>
   * Returns a byte array from a string of hexadecimal digits.
   * </p>
   *
   * @param s a string of hexadecimal ASCII characters
   * @return the decoded byte array from the input hexadecimal string.
   */
  public static byte[] toBytesFromString(String s)
  {
    int limit = s.length();
    byte[] result = new byte[((limit + 1) / 2)];
    int i = 0, j = 0;
    if ((limit % 2) == 1)
      result[j++] = (byte) fromDigit(s.charAt(i++));
    while (i < limit)
      {
        result[j  ] = (byte) (fromDigit(s.charAt(i++)) << 4);
        result[j++] |= (byte) fromDigit(s.charAt(i++));
      }
    return result;
  }

  /**
   * Returns a byte array from a string of hexadecimal digits, interpreting them
   * as a large big-endian integer and returning it as a large little-endian
   * integer.
   *
   * @param s a string of hexadecimal ASCII characters
   * @return the decoded byte array from the input hexadecimal string.
   */
  public static byte[] toReversedBytesFromString(String s)
  {
    int limit = s.length();
    byte[] result = new byte[((limit + 1) / 2)];
    int i = 0;
    if ((limit % 2) == 1)
      result[i++] = (byte) fromDigit(s.charAt(--limit));
    while (limit > 0)
      {
        result[i  ] = (byte) fromDigit(s.charAt(--limit));
        result[i++] |= (byte) (fromDigit(s.charAt(--limit)) << 4);
      }
    return result;
  }

  /**
   * Returns a number from <code>0</code> to <code>15</code> corresponding
   * to the designated hexadecimal digit.
   *
   * @param c a hexadecimal ASCII symbol.
   */
  public static int fromDigit(char c)
  {
    if (c >= '0' && c <= '9')
      return c - '0';
    else if (c >= 'A' && c <= 'F')
      return c - 'A' + 10;
    else if (c >= 'a' && c <= 'f')
      return c - 'a' + 10;
    else
      throw new IllegalArgumentException("Invalid hexadecimal digit: " + c);
  }

  /**
   * Returns a string of 8 hexadecimal digits (most significant digit first)
   * corresponding to the unsigned integer <code>n</code>.
   *
   * @param n the unsigned integer to convert.
   * @return a hexadecimal string 8-character long.
   */
  public static String toString(int n)
  {
    char[] buf = new char[8];
    for (int i = 7; i >= 0; i--)
      {
        buf[i] = HEX_DIGITS[n & 0x0F];
        n >>>= 4;
      }
    return new String(buf);
  }

  /**
   * Returns a string of hexadecimal digits from an integer array. Each int is
   * converted to 4 hex symbols.
   */
  public static String toString(int[] ia)
  {
    int length = ia.length;
    char[] buf = new char[length * 8];
    for (int i = 0, j = 0, k; i < length; i++)
      {
        k = ia[i];
        buf[j++] = HEX_DIGITS[(k >>> 28) & 0x0F];
        buf[j++] = HEX_DIGITS[(k >>> 24) & 0x0F];
        buf[j++] = HEX_DIGITS[(k >>> 20) & 0x0F];
        buf[j++] = HEX_DIGITS[(k >>> 16) & 0x0F];
        buf[j++] = HEX_DIGITS[(k >>> 12) & 0x0F];
        buf[j++] = HEX_DIGITS[(k >>>  8) & 0x0F];
        buf[j++] = HEX_DIGITS[(k >>>  4) & 0x0F];
        buf[j++] = HEX_DIGITS[ k         & 0x0F];
      }
    return new String(buf);
  }

  /**
   * Returns a string of 16 hexadecimal digits (most significant digit first)
   * corresponding to the unsigned long <code>n</code>.
   *
   * @param n the unsigned long to convert.
   * @return a hexadecimal string 16-character long.
   */
  public static String toString(long n)
  {
    char[] b = new char[16];
    for (int i = 15; i >= 0; i--)
      {
        b[i] = HEX_DIGITS[(int)(n & 0x0FL)];
        n >>>= 4;
      }
    return new String(b);
  }

  /**
   * Similar to the <code>toString()</code> method except that the Unicode
   * escape character is inserted before every pair of bytes. Useful to
   * externalise byte arrays that will be constructed later from such strings;
   * eg. s-box values.
   *
   * @throws ArrayIndexOutOfBoundsException if the length is odd.
   */
  public static String toUnicodeString(byte[] ba)
  {
    return toUnicodeString(ba, 0, ba.length);
  }

  /**
   * Similar to the <code>toString()</code> method except that the Unicode
   * escape character is inserted before every pair of bytes. Useful to
   * externalise byte arrays that will be constructed later from such strings;
   * eg. s-box values.
   *
   * @throws ArrayIndexOutOfBoundsException if the length is odd.
   */
  public static final String toUnicodeString(byte[] ba, int offset, int length)
  {
    CPStringBuilder sb = new CPStringBuilder();
    int i = 0;
    int j = 0;
    int k;
    sb.append('\n').append("\"");
    while (i < length)
      {
        sb.append("\\u");
        k = ba[offset + i++];
        sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
        sb.append(HEX_DIGITS[ k        & 0x0F]);
        k = ba[offset + i++];
        sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
        sb.append(HEX_DIGITS[ k        & 0x0F]);
        if ((++j % 8) == 0)
          sb.append("\"+").append('\n').append("\"");
      }
    sb.append("\"").append('\n');
    return sb.toString();
  }

  /**
   * Similar to the <code>toString()</code> method except that the Unicode
   * escape character is inserted before every pair of bytes. Useful to
   * externalise integer arrays that will be constructed later from such
   * strings; eg. s-box values.
   *
   * @throws ArrayIndexOutOfBoundsException if the length is not a multiple of
   *           4.
   */
  public static String toUnicodeString(int[] ia)
  {
    CPStringBuilder sb = new CPStringBuilder();
    int i = 0;
    int j = 0;
    int k;
    sb.append('\n').append("\"");
    while (i < ia.length)
      {
        k = ia[i++];
        sb.append("\\u");
        sb.append(HEX_DIGITS[(k >>> 28) & 0x0F]);
        sb.append(HEX_DIGITS[(k >>> 24) & 0x0F]);
        sb.append(HEX_DIGITS[(k >>> 20) & 0x0F]);
        sb.append(HEX_DIGITS[(k >>> 16) & 0x0F]);
        sb.append("\\u");
        sb.append(HEX_DIGITS[(k >>> 12) & 0x0F]);
        sb.append(HEX_DIGITS[(k >>>  8) & 0x0F]);
        sb.append(HEX_DIGITS[(k >>>  4) & 0x0F]);
        sb.append(HEX_DIGITS[ k         & 0x0F]);
        if ((++j % 4) == 0)
          sb.append("\"+").append('\n').append("\"");
      }
    sb.append("\"").append('\n');
    return sb.toString();
  }

  public static byte[] toBytesFromUnicode(String s)
  {
    int limit = s.length() * 2;
    byte[] result = new byte[limit];
    char c;
    for (int i = 0; i < limit; i++)
      {
        c = s.charAt(i >>> 1);
        result[i] = (byte)(((i & 1) == 0) ? c >>> 8 : c);
      }
    return result;
  }

  /**
   * Dumps a byte array as a string, in a format that is easy to read for
   * debugging. The string <code>m</code> is prepended to the start of each
   * line.
   * <p>
   * If <code>offset</code> and <code>length</code> are omitted, the whole
   * array is used. If <code>m</code> is omitted, nothing is prepended to each
   * line.
   *
   * @param data the byte array to be dumped.
   * @param offset the offset within <i>data</i> to start from.
   * @param length the number of bytes to dump.
   * @param m a string to be prepended to each line.
   * @return a string containing the result.
   */
  public static String dumpString(byte[] data, int offset, int length, String m)
  {
    if (data == null)
      return m + "null\n";
    CPStringBuilder sb = new CPStringBuilder(length * 3);
    if (length > 32)
      sb.append(m).append("Hexadecimal dump of ")
          .append(length).append(" bytes...\n");
    // each line will list 32 bytes in 4 groups of 8 each
    int end = offset + length;
    String s;
    int l = Integer.toString(length).length();
    if (l < 4)
      l = 4;
    for (; offset < end; offset += 32)
      {
        if (length > 32)
          {
            s = "         " + offset;
            sb.append(m).append(s.substring(s.length() - l)).append(": ");
          }
        int i = 0;
        for (; i < 32 && offset + i + 7 < end; i += 8)
          sb.append(toString(data, offset + i, 8)).append(' ');
        if (i < 32)
          for (; i < 32 && offset + i < end; i++)
            sb.append(byteToString(data[offset + i]));
        sb.append('\n');
      }
    return sb.toString();
  }

  public static String dumpString(byte[] data)
  {
    return (data == null) ? "null\n" : dumpString(data, 0, data.length, "");
  }

  public static String dumpString(byte[] data, String m)
  {
    return (data == null) ? "null\n" : dumpString(data, 0, data.length, m);
  }

  public static String dumpString(byte[] data, int offset, int length)
  {
    return dumpString(data, offset, length, "");
  }

  /**
   * Returns a string of 2 hexadecimal digits (most significant digit first)
   * corresponding to the lowest 8 bits of <code>n</code>.
   *
   * @param n the byte value to convert.
   * @return a string of 2 hex characters representing the input.
   */
  public static String byteToString(int n)
  {
    char[] buf = { HEX_DIGITS[(n >>> 4) & 0x0F], HEX_DIGITS[n & 0x0F] };
    return new String(buf);
  }

  /**
   * Converts a designated byte array to a Base-64 representation, with the
   * exceptions that (a) leading 0-byte(s) are ignored, and (b) the character
   * '.' (dot) shall be used instead of "+' (plus).
   * <p>
   * Used by SASL password file manipulation primitives.
   *
   * @param buffer an arbitrary sequence of bytes to represent in Base-64.
   * @return unpadded (without the '=' character(s)) Base-64 representation of
   *         the input.
   */
  public static final String toBase64(byte[] buffer)
  {
    int len = buffer.length, pos = len % 3;
    byte b0 = 0, b1 = 0, b2 = 0;
    switch (pos)
      {
      case 1:
        b2 = buffer[0];
        break;
      case 2:
        b1 = buffer[0];
        b2 = buffer[1];
        break;
      }
    CPStringBuilder sb = new CPStringBuilder();
    int c;
    boolean notleading = false;
    do
      {
        c = (b0 & 0xFC) >>> 2;
        if (notleading || c != 0)
          {
            sb.append(BASE64_CHARSET[c]);
            notleading = true;
          }
        c = ((b0 & 0x03) << 4) | ((b1 & 0xF0) >>> 4);
        if (notleading || c != 0)
          {
            sb.append(BASE64_CHARSET[c]);
            notleading = true;
          }
        c = ((b1 & 0x0F) << 2) | ((b2 & 0xC0) >>> 6);
        if (notleading || c != 0)
          {
            sb.append(BASE64_CHARSET[c]);
            notleading = true;
          }
        c = b2 & 0x3F;
        if (notleading || c != 0)
          {
            sb.append(BASE64_CHARSET[c]);
            notleading = true;
          }
        if (pos >= len)
          break;
        else
          {
            try
              {
                b0 = buffer[pos++];
                b1 = buffer[pos++];
                b2 = buffer[pos++];
              }
            catch (ArrayIndexOutOfBoundsException x)
              {
                break;
              }
          }
      }
    while (true);

    if (notleading)
      return sb.toString();
    return "0";
  }

  /**
   * The inverse function of the above.
   * <p>
   * Converts a string representing the encoding of some bytes in Base-64 to
   * their original form.
   *
   * @param str the Base-64 encoded representation of some byte(s).
   * @return the bytes represented by the <code>str</code>.
   * @throws NumberFormatException if <code>str</code> is <code>null</code>,
   *           or <code>str</code> contains an illegal Base-64 character.
   * @see #toBase64(byte[])
   */
  public static final byte[] fromBase64(String str)
  {
    int len = str.length();
    if (len == 0)
      throw new NumberFormatException("Empty string");
    byte[] a = new byte[len + 1];
    int i, j;
    for (i = 0; i < len; i++)
      try
        {
          a[i] = (byte) BASE64_CHARS.indexOf(str.charAt(i));
        }
      catch (ArrayIndexOutOfBoundsException x)
        {
          throw new NumberFormatException("Illegal character at #" + i);
        }
    i = len - 1;
    j = len;
    try
      {
        while (true)
          {
            a[j] = a[i];
            if (--i < 0)
              break;
            a[j] |= (a[i] & 0x03) << 6;
            j--;
            a[j] = (byte)((a[i] & 0x3C) >>> 2);
            if (--i < 0)
              break;
            a[j] |= (a[i] & 0x0F) << 4;
            j--;
            a[j] = (byte)((a[i] & 0x30) >>> 4);
            if (--i < 0)
              break;
            a[j] |= (a[i] << 2);
            j--;
            a[j] = 0;
            if (--i < 0)
              break;
          }
      }
    catch (Exception ignored)
      {
      }
    try
      { // ignore leading 0-bytes
        while (a[j] == 0)
          j++;
      }
    catch (Exception x)
      {
        return new byte[1]; // one 0-byte
      }
    byte[] result = new byte[len - j + 1];
    System.arraycopy(a, j, result, 0, len - j + 1);
    return result;
  }

  // BigInteger utilities ----------------------------------------------------

  /**
   * Treats the input as the MSB representation of a number, and discards
   * leading zero elements. For efficiency, the input is simply returned if no
   * leading zeroes are found.
   *
   * @param n the {@link BigInteger} to trim.
   * @return the byte array representation of the designated {@link BigInteger}
   *         with no leading 0-bytes.
   */
  public static final byte[] trim(BigInteger n)
  {
    byte[] in = n.toByteArray();
    if (in.length == 0 || in[0] != 0)
      return in;
    int len = in.length;
    int i = 1;
    while (in[i] == 0 && i < len)
      ++i;
    byte[] result = new byte[len - i];
    System.arraycopy(in, i, result, 0, len - i);
    return result;
  }

  /**
   * Returns a hexadecimal dump of the trimmed bytes of a {@link BigInteger}.
   *
   * @param x the {@link BigInteger} to display.
   * @return the string representation of the designated {@link BigInteger}.
   */
  public static final String dump(BigInteger x)
  {
    return dumpString(trim(x));
  }
}
