/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.server;

/**
 * A utility to decode and encode byte arrays as Strings, using only "safe"
 * characters.
 */
public class Base64Utils {

  /**
   * An array mapping size but values to the characters that will be used to
   * represent them. Note that this is not identical to the set of characters
   * used by MIME-Base64.
   */
  private static final char[] base64Chars = new char[] {
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
      'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
      'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
      '4', '5', '6', '7', '8', '9', '$', '_'};

  /**
   * An array mapping legal base 64 characters [a-zA-Z0-9$_] to their associated
   * 6-bit values. The source indices will be given by 7-bit ASCII characters,
   * thus the array size needs to be 128 (actually 123 would suffice for the
   * given set of characters in use).
   */
  private static final byte[] base64Values = new byte[128];

  /**
   * Initialize the base 64 encoder values.
   */
  static {
    // Invert the mapping (i -> base64Chars[i])
    for (int i = 0; i < base64Chars.length; i++) {
      base64Values[base64Chars[i]] = (byte) i;
    }
  }

  /**
   * Decode a base64 string into a byte array.
   * 
   * @param data the encoded data.
   * @return a byte array.
   * @see #fromBase64(String)
   */
  public static byte[] fromBase64(String data) {
    if (data == null) {
      return null;
    }

    int len = data.length();
    assert (len % 4) == 0;

    if (len == 0) {
      return new byte[0];
    }

    char[] chars = new char[len];
    data.getChars(0, len, chars, 0);

    int olen = 3 * (len / 4);
    if (chars[len - 2] == '=') {
      --olen;
    }
    if (chars[len - 1] == '=') {
      --olen;
    }

    byte[] bytes = new byte[olen];

    int iidx = 0;
    int oidx = 0;
    while (iidx < len) {
      int c0 = base64Values[chars[iidx++] & 0xff];
      int c1 = base64Values[chars[iidx++] & 0xff];
      int c2 = base64Values[chars[iidx++] & 0xff];
      int c3 = base64Values[chars[iidx++] & 0xff];
      int c24 = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3;

      bytes[oidx++] = (byte) (c24 >> 16);
      if (oidx == olen) {
        break;
      }
      bytes[oidx++] = (byte) (c24 >> 8);
      if (oidx == olen) {
        break;
      }
      bytes[oidx++] = (byte) c24;
    }

    return bytes;
  }

  /**
   * Decode a base64 string into a long value.
   */
  public static long longFromBase64(String value) {
    int pos = 0;
    long longVal = base64Values[value.charAt(pos++)];
    int len = value.length();
    while (pos < len) {
      longVal <<= 6;
      longVal |= base64Values[value.charAt(pos++)];
    }
    return longVal;
  }

  /**
   * Converts a byte array into a base 64 encoded string. Null is encoded as
   * null, and an empty array is encoded as an empty string. Otherwise, the byte
   * data is read 3 bytes at a time, with bytes off the end of the array padded
   * with zeros. Each 24-bit chunk is encoded as 4 characters from the sequence
   * [A-Za-z0-9$_]. If one of the source positions consists entirely of padding
   * zeros, an '=' character is used instead.
   * 
   * @param data a byte array, which may be null or empty
   * @return a String
   */
  public static String toBase64(byte[] data) {
    if (data == null) {
      return null;
    }

    int len = data.length;
    if (len == 0) {
      return "";
    }

    int olen = 4 * ((len + 2) / 3);
    char[] chars = new char[olen];

    int iidx = 0;
    int oidx = 0;
    int charsLeft = len;
    while (charsLeft > 0) {
      int b0 = data[iidx++] & 0xff;
      int b1 = (charsLeft > 1) ? data[iidx++] & 0xff : 0;
      int b2 = (charsLeft > 2) ? data[iidx++] & 0xff : 0;
      int b24 = (b0 << 16) | (b1 << 8) | b2;

      int c0 = (b24 >> 18) & 0x3f;
      int c1 = (b24 >> 12) & 0x3f;
      int c2 = (b24 >> 6) & 0x3f;
      int c3 = b24 & 0x3f;

      chars[oidx++] = base64Chars[c0];
      chars[oidx++] = base64Chars[c1];
      chars[oidx++] = (charsLeft > 1) ? base64Chars[c2] : '=';
      chars[oidx++] = (charsLeft > 2) ? base64Chars[c3] : '=';

      charsLeft -= 3;
    }

    return new String(chars);
  }

  /**
   * Return a string containing a base-64 encoded version of the given long
   * value.  Leading groups of all zero bits are omitted.
   */
  public static String toBase64(long value) {
    // Convert to ints early to avoid need for long ops
    int low = (int) (value & 0xffffffff);
    int high = (int) (value >> 32);

    StringBuilder sb = new StringBuilder();
    boolean haveNonZero = base64Append(sb, (high >> 28) & 0xf, false);
    haveNonZero = base64Append(sb, (high >> 22) & 0x3f, haveNonZero);
    haveNonZero = base64Append(sb, (high >> 16) & 0x3f, haveNonZero);
    haveNonZero = base64Append(sb, (high >> 10) & 0x3f, haveNonZero);
    haveNonZero = base64Append(sb, (high >> 4) & 0x3f, haveNonZero);
    int v = ((high & 0xf) << 2) | ((low >> 30) & 0x3);
    haveNonZero = base64Append(sb, v, haveNonZero);
    haveNonZero = base64Append(sb, (low >> 24) & 0x3f, haveNonZero);
    haveNonZero = base64Append(sb, (low >> 18) & 0x3f, haveNonZero);
    haveNonZero = base64Append(sb, (low >> 12) & 0x3f, haveNonZero);
    base64Append(sb, (low >> 6) & 0x3f, haveNonZero);
    base64Append(sb, low & 0x3f, true);

    return sb.toString();
  }

  private static boolean base64Append(StringBuilder sb, int digit,
      boolean haveNonZero) {
    if (digit > 0) {
      haveNonZero = true;
    }
    if (haveNonZero) {
      sb.append(base64Chars[digit]);
    }
    return haveNonZero;
  }
}
