/* CdrEncapsCodecImpl.java --
   Copyright (C) 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.CORBA;

import gnu.CORBA.CDR.BufferredCdrInput;
import gnu.CORBA.CDR.BufferedCdrOutput;
import gnu.CORBA.CDR.AbstractCdrOutput;

import org.omg.CORBA.Any;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.UserException;
import org.omg.IOP.Codec;
import org.omg.IOP.CodecPackage.FormatMismatch;
import org.omg.IOP.CodecPackage.InvalidTypeForEncoding;
import org.omg.IOP.CodecPackage.TypeMismatch;

/**
 * The local {@link Codec} implementation for ENCODING_CDR_ENCAPS
 * encoding. This is a local implementation; the remote side should
 * have its own Codec of this kind. 
 *
 *
 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
 */
public class CdrEncapsCodecImpl
  extends LocalObject
  implements Codec
{
  /** 
   * Use serialVersionUID for interoperability. 
   */
  private static final long serialVersionUID = 1;

  /**
   * If set to true, no wide string or wide character is allowed (GIOP 1.0).
   */
  private final boolean noWide;

  /**
   * The version of this encoding.
   */
  private final Version version;

  /**
   * The associated ORB.
   */
  protected final ORB orb;

  /**
   * If true, this Codec writes the record length (as int) in the beginning
   * of the record. This indicator is part of the formal OMG standard, but it is
   * missing in Sun's implementation. Both Suns's and this Codec detects
   * the indicator, if present, but can also decode data where this information
   * is missing. If the length indicator is missing, the first four bytes in
   * Suns encoding are equal to 0 (Big Endian marker).
   */
  private boolean lengthIndicator = true;

  /**
   * Create an instance of this Codec, encoding following the given version.
   */
  public CdrEncapsCodecImpl(ORB _orb, Version _version)
  {
    orb = _orb;
    version = _version;
    noWide = version.until_inclusive(1, 0);
  }

  /**
   * Return the array of repository ids for this object.
   *
   * @return { "IDL:gnu/CORBA/cdrEnapsCodec:1.0" }, always.
   */
  public String[] _ids()
  {
    return new String[] { "IDL:gnu/CORBA/cdrEnapsCodec:1.0" };
  }

  /**
   * Decode the contents of the byte array into Any.
   * The byte array may have the optional four byte length indicator
   * in the beginning. If these four bytes are zero, it is assumed,
   * that no length indicator is present.
   */
  public Any decode(byte[] them)
             throws FormatMismatch
  {
    BufferredCdrInput input = createInput(them);
    BufferredCdrInput encapsulation = createEncapsulation(them, input);

    TypeCode type = encapsulation.read_TypeCode();

    try
      {
        checkTypePossibility("", type);
      }
    catch (InvalidTypeForEncoding ex)
      {
        throw new FormatMismatch(ex.getMessage());
      }

    return readAny(type, encapsulation);
  }

  private BufferredCdrInput createEncapsulation(byte[] them, BufferredCdrInput input)
  {
    BufferredCdrInput encapsulation;

    if ((them [ 0 ] | them [ 1 ] | them [ 2 ] | them [ 3 ]) == 0)
      {
        // Skip that appears to be the always present Big Endian marker.
        encapsulation = input;
        input.read_short();
      }
    else
      encapsulation = input.read_encapsulation();
    return encapsulation;
  }

  /** {@inheritDoc} */
  public byte[] encode(Any that)
                throws InvalidTypeForEncoding
  {
    checkTypePossibility("", that.type());

    BufferedCdrOutput output = createOutput(that);

    // BufferedCdrOutput has internal support for this encoding.
    AbstractCdrOutput encapsulation = output.createEncapsulation();

    try
      {
        TypeCodeHelper.write(encapsulation, that.type());
        that.write_value(encapsulation);

        encapsulation.close();
        output.close();
      }
    catch (Exception ex)
      {
        MARSHAL m = new MARSHAL();
        m.minor = Minor.Encapsulation;
        m.initCause(ex);
        throw m;
      }
    return output.buffer.toByteArray();
  }

  /**
   * Decode the value, stored in the byte array, into Any, assuming,
   * that the byte array holds the data structure, defined by the
   * given typecode.
   *
   * The byte array may have the optional four byte length indicator
   * in the beginning. If these four bytes are zero, it is assumed,
   * that no length indicator is present.
   */
  public Any decode_value(byte[] them, TypeCode type)
                   throws FormatMismatch, TypeMismatch
  {
    try
      {
        checkTypePossibility("", type);
      }
    catch (InvalidTypeForEncoding ex)
      {
        throw new TypeMismatch(ex.getMessage());
      }

    BufferredCdrInput input = createInput(them);
    BufferredCdrInput encapsulation = createEncapsulation(them, input);
    return readAny(type, encapsulation);
  }

  /**
   * Read an Any from the given stream.
   *
   * @param type a type of the Any to read.
   * @param input the encapsulation stream.
   */
  private Any readAny(TypeCode type, BufferredCdrInput encapsulation)
               throws MARSHAL
  {
    gnuAny a = new gnuAny();
    a.setOrb(orb);

    // BufferredCdrInput has internal support for this encoding.
    a.read_value(encapsulation, type);
    return a;
  }

  /** {@inheritDoc} */
  public byte[] encode_value(Any that)
                      throws InvalidTypeForEncoding
  {
    checkTypePossibility("", that.type());

    BufferedCdrOutput output = createOutput(that);

    AbstractCdrOutput encapsulation = output.createEncapsulation();

    try
      {
        that.write_value(encapsulation);

        encapsulation.close();
        output.close();
      }
    catch (Exception ex)
      {
        MARSHAL m = new MARSHAL();
        m.minor = Minor.Encapsulation;
        m.initCause(ex);
        throw m;
      }
    return output.buffer.toByteArray();
  }

  /**
   * Create the CDR output stream for writing the given Any.
   * The BufferedCdrOutput has internal support for encapsulation encodings.
   *
   * @param that the Any that will be written.
   *
   * @return the stream.
   *
   * @throws InvalidTypeForEncoding if that Any cannot be written under the
   * given version.
   */
  private BufferedCdrOutput createOutput(Any that)
                             throws InvalidTypeForEncoding
  {
    BufferedCdrOutput output = new BufferedCdrOutput();
    output.setOrb(orb);
    output.setVersion(version);
    return output;
  }

  /**
   * Checks if the given type can be encoded. Currently only checks for wide
   * strings and wide chars for GIOP 1.0.
   *
   * @param t a typecode to chek.
   *
   * @throws InvalidTypeForEncoding if the typecode is not valid for the given
   * version.
   */
  private void checkTypePossibility(String name, TypeCode t)
                             throws InvalidTypeForEncoding
  {
    if (noWide)
      {
        try
          {
            int kind = t.kind().value();

            if (kind == TCKind._tk_wchar || kind == TCKind._tk_wstring)
              throw new InvalidTypeForEncoding(name + " wide char in " +
                                               version
                                              );
            else if (kind == TCKind._tk_alias || kind == TCKind._tk_array ||
                     kind == TCKind._tk_sequence
                    )
              checkTypePossibility("Array member", t.content_type());

            else if (kind == TCKind._tk_struct || kind == TCKind._tk_union)
              {
                for (int i = 0; i < t.member_count(); i++)
                  {
                    checkTypePossibility(t.member_name(i), t.member_type(i));
                  }
              }
          }
        catch (UserException ex)
          {
            InternalError ierr = new InternalError();
            ierr.initCause(ex);
            throw ierr;
          }
      }
  }

  /**
   * Create the CDR input stream for reading the given byte array.
   *
   * @param them a byte array to read.
   *
   * @return the stream.
   */
  private BufferredCdrInput createInput(byte[] them)
  {
    BufferredCdrInput input = new BufferredCdrInput(them);
    input.setOrb(orb);
    input.setVersion(version);
    return input;
  }

  /**
   * Check if the Codec writes the length indicator.
   */
  public boolean hasLengthIndicator()
  {
    return lengthIndicator;
  }

  /**
   * Sets if the Codec must write the record length in the beginning of the
   * array. Encodings both with and without that indicator are understood
   * both by Suns and this codec, but the OMG specification seems requiring
   * it. The default behavior is to use the length indicator.
   *
   * @param use_lengthIndicator
   */
  public void setUseLengthIndicator(boolean use_lengthIndicator)
  {
    lengthIndicator = use_lengthIndicator;
  }
}