/* DERWriter.java -- write Java types in DER format.
   Copyright (C) 2003, 2004, 2005, 2010  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)
  {
    int len = string.length();
    ByteArrayOutputStream buf = new ByteArrayOutputStream(len + (len >> 1));
    for (int i = 0; i < len; 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);
      }
  }
}
