/* DERWriter.java -- write Java types in DER format.
   Copyright (C) 2003, 2004, 2005 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., 51 Franklin Street, 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.der;

import gnu.java.security.OID;

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

import java.math.BigInteger;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;

/**
 * Methods that allow various Java types to be written as a DER
 * (Distinguished Encoding Rules) stream to the specified output stream.
 * DER is used to encode ASN.1 constructions, but this class provides no
 * methods for interacting with ASN.1. Rather, callers should construct
 * their output objects properly for whatever ASN.1 construct is being
 * output.
 *
 * <p>This class only defines static methods; there are no instance
 * variables needed.
 *
 * @author Casey Marshall (csm@gnu.org)
 */
public class DERWriter implements DER
{

  // Constructors.
  // ------------------------------------------------------------------------

  /** This class only has static methods. */
  private DERWriter()
  {
  }

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

  public static int write(OutputStream out, DERValue object)
    throws IOException
  {
    if (DER.CONSTRUCTED_VALUE.equals (object.getValue ()))
      {
        out.write (object.getEncoded ());
        return object.getLength ();
      }

    out.write(object.getExternalTag());
    Object value = object.getValue();
    if (value == null)
      {
        writeLength(out, 0);
        return 0;
      }
    if (value instanceof Boolean)
      return writeBoolean(out, (Boolean) value);
    else if (value instanceof BigInteger)
      return writeInteger(out, (BigInteger) value);
    else if (value instanceof Date)
      return writeDate(out, object.getExternalTag(), (Date) value);
    else if (value instanceof String)
      return writeString(out, object.getExternalTag(), (String) value);
    else if (value instanceof List)
      return writeSequence(out, (List) value);
    else if (value instanceof Set)
      return writeSet(out, (Set) value);
    else if (value instanceof BitString)
      return writeBitString(out, (BitString) value);
    else if (value instanceof OID)
      return writeOID(out, (OID) value);
    else if (value instanceof byte[])
      {
        writeLength(out, ((byte[]) value).length);
        out.write((byte[]) value);
        return ((byte[]) value).length;
      }
    else if (value instanceof DERValue)
      {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        write(bout, (DERValue) value);
        byte[] buf = bout.toByteArray();
        writeLength(out, buf.length);
        out.write(buf);
        return buf.length;
      }
    else
      throw new DEREncodingException("cannot encode " + value.getClass().getName());
  }

  public static int definiteEncodingSize(int length)
  {
    if (length < 128)
      return 1;
    else if (length < 256)
      return 2;
    else if (length < 65536)
      return 3;
    else if (length < 16777216)
      return 4;
    else
      return 5;
  }

  // Own methods.
  // ------------------------------------------------------------------------

  /**
   * Write a BOOLEAN type to the given output stream.
   *
   * @param out The sink output stream.
   * @param b   The boolean value to write.
   */
  private static int writeBoolean(OutputStream out, Boolean b)
    throws IOException
  {
    writeLength(out, 1);
    if (b.booleanValue())
      out.write(0xFF);
    else
      out.write(0);
    return 1;
  }

  /**
   * Write an INTEGER type to the given output stream.
   *
   * @param out The sink output stream.
   * @param integer The integer to write.
   */
  private static int writeInteger(OutputStream out, BigInteger integer)
    throws IOException
  {
    byte[] bytes = integer.toByteArray();
    writeLength(out, bytes.length);
    out.write(bytes);
    return bytes.length;
  }

  private static int writeSequence(OutputStream out, List sequence)
    throws IOException
  {
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    for (Iterator i = sequence.iterator(); i.hasNext(); )
      {
        write(bout, (DERValue) i.next());
      }
    byte[] buf = bout.toByteArray();
    writeLength(out, buf.length);
    out.write(buf);
    return buf.length;
  }

  private static int writeSet(OutputStream out, Set set)
    throws IOException
  {
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    for (Iterator i = set.iterator(); i.hasNext(); )
      {
        write(bout, (DERValue) i.next());
      }
    byte[] buf = bout.toByteArray();
    writeLength(out, buf.length);
    out.write(buf);
    return buf.length;
  }

  private static int writeOID(OutputStream out, OID oid)
    throws IOException
  {
    byte[] der = oid.getDER();
    writeLength(out, der.length);
    out.write(der);
    return der.length;
  }

  private static int writeBitString(OutputStream out, BitString bs)
    throws IOException
  {
    byte[] buf = bs.getShiftedByteArray();
    writeLength(out, buf.length + 1);
    out.write(bs.getIgnoredBits());
    out.write(buf);
    return buf.length + 1;
  }

  private static int writeString(OutputStream out, int tag, String str)
    throws IOException
  {
    byte[] b = null;
    switch (tag & 0x1F)
      {
        case NUMERIC_STRING:
        case PRINTABLE_STRING:
        case T61_STRING:
        case VIDEOTEX_STRING:
        case IA5_STRING:
        case GRAPHIC_STRING:
        case ISO646_STRING:
        case GENERAL_STRING:
          b = toIso88591(str);
          break;

        case UNIVERSAL_STRING:
        case BMP_STRING:
          b = toUtf16Be(str);
          break;

        case UTF8_STRING:
        default:
          b = toUtf8(str);
          break;
      }
    writeLength(out, b.length);
    out.write(b);
    return b.length;
  }

  private static byte[] toIso88591(String string)
  {
    byte[] result = new byte[string.length()];
    for (int i = 0; i < string.length(); i++)
      result[i] = (byte) string.charAt(i);
    return result;
  }

  private static byte[] toUtf16Be(String string)
  {
    byte[] result = new byte[string.length() * 2];
    for (int i = 0; i < string.length(); i++)
      {
        result[i*2  ] = (byte) ((string.charAt(i) >>> 8) & 0xFF);
        result[i*2+1] = (byte)  (string.charAt(i) & 0xFF);
      }
    return result;
  }

  private static byte[] toUtf8(String string)
  {
    ByteArrayOutputStream buf =
      new ByteArrayOutputStream((int)(string.length() * 1.5));
    for (int i = 0; i < string.length(); i++)
      {
        char c = string.charAt(i);
        if (c < 0x0080)
          buf.write(c & 0xFF);
        else if (c < 0x0800)
          {
            buf.write(0xC0 | ((c >>> 6) & 0x3F));
            buf.write(0x80 |  (c & 0x3F));
          }
        else
          {
            buf.write(0xE0 | ((c >>> 12) & 0x0F));
            buf.write(0x80 | ((c >>>  6) & 0x3F));
            buf.write(0x80 |  (c & 0x3F));
          }
      }
    return buf.toByteArray();
  }

  private static int writeDate(OutputStream out, int tag, Date date)
    throws IOException
  {
    SimpleDateFormat sdf = null;
    if ((tag & 0x1F) == UTC_TIME)
      sdf = new SimpleDateFormat("yyMMddHHmmss'Z'");
    else
      sdf = new SimpleDateFormat("yyyyMMddHHmmss'.'SSS'Z'");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    byte[] b = sdf.format(date).getBytes("ISO-8859-1");
    writeLength(out, b.length);
    out.write(b);
    return b.length;
  }

  // Package method.
  // ------------------------------------------------------------------------

  static void writeLength(OutputStream out, int len) throws IOException
  {
    if (len < 128)
      out.write(len);
    else if (len < 256)
      {
        out.write(0x81);
        out.write(len);
      }
    else if (len < 65536)
      {
        out.write(0x82);
        out.write(len >> 8);
        out.write(len);
      }
    else if (len < 16777216)
      {
        out.write(0x83);
        out.write(len >> 16);
        out.write(len >>  8);
        out.write(len);
      }
    else
      {
        out.write(0x84);
        out.write(len >> 24);
        out.write(len >> 16);
        out.write(len >>  8);
        out.write(len);
      }
  }
}
