/* ArrayValueHelper.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.CDR;

import gnu.CORBA.ObjectCreator;

import org.omg.CORBA.BooleanSeqHelper;
import org.omg.CORBA.CharSeqHelper;
import org.omg.CORBA.DoubleSeqHelper;
import org.omg.CORBA.FloatSeqHelper;
import org.omg.CORBA.LongLongSeqHelper;
import org.omg.CORBA.LongSeqHelper;
import org.omg.CORBA.OctetSeqHelper;
import org.omg.CORBA.ShortSeqHelper;
import org.omg.CORBA.portable.BoxedValueHelper;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.rmi.Remote;

import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;

/**
 * Writes arrays as a boxed value types. A single instance is used to write a
 * single array. This class is only used with RMI/IIOP, to handle array boxed
 * values.
 *
 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
 */
class ArrayValueHelper
  implements BoxedValueHelper
{
  /**
   * The value handler (one for all instances).
   */
  static ValueHandler handler = Util.createValueHandler();

  /**
   * A class of the array being written.
   */
  Class arrayClass;

  /**
   * The array component class.
   */
  Class component;

  /**
   * The array component repository Id.
   */
  String componentId;

  /**
   * If true, the array members are written as objects rather than as values.
   * True for Remotes and CORBA objects.
   */
  boolean written_as_object()
  {
    return org.omg.CORBA.Object.class.isAssignableFrom(component)
      || Remote.class.isAssignableFrom(component);
  }

  /**
   * Creates the instance of the helper to write this specific array class.
   */
  ArrayValueHelper(Class an_arrayClass)
  {
    arrayClass = an_arrayClass;
  }

  /**
   * Get the array repository Id that will be the RMI repository id.
   */
  public String get_id()
  {
    return ObjectCreator.getRepositoryId(arrayClass);
  }

  /**
   * Read the array from the input stream.
   */
  public Serializable read_value(InputStream input)
  {
    if (input instanceof HeadlessInput)
      {
        ((HeadlessInput) input).subsequentCalls = true;
      }

    component = arrayClass.getComponentType();

    if (component.equals(byte.class))
      return OctetSeqHelper.read(input);
    else if (component.equals(String.class))
      {
        // String array is optimized because this may be frequent.
        String[] s = new String[input.read_long()];

        for (int i = 0; i < s.length; i++)
          s[i] = (String) Vio.read(input, Vio.m_StringValueHelper);
        return s;
      }
    else if (component.equals(int.class))
      return LongSeqHelper.read(input);
    else if (component.equals(long.class))
      return LongLongSeqHelper.read(input);
    else if (component.equals(double.class))
      return DoubleSeqHelper.read(input);
    else if (component.equals(float.class))
      return FloatSeqHelper.read(input);
    else if (component.equals(boolean.class))
      return BooleanSeqHelper.read(input);
    else if (component.equals(short.class))
      return ShortSeqHelper.read(input);
    else if (component.equals(char.class))
      return CharSeqHelper.read(input);
    else
      {
        // Read others, use reflection.
        int n = input.read_long();

        gnuValueStream s = null;

        Serializable array = (Serializable) Array.newInstance(component, n);
        if (written_as_object())
          for (int i = 0; i < n; i++)
            {
              gnuRuntime g;
              int position;
              if (input instanceof gnuValueStream)
                {
                  s = (gnuValueStream) input;
                  g = s.getRunTime();
                  position = s.getPosition();
                }
              else
                {
                  g = null;
                  position = -1;
                }

              if (input instanceof HeadlessInput)
                ((HeadlessInput) input).subsequentCalls = true;

              Object o = handler.readValue(input, position, component, null, g);
              Array.set(array, i, o);
            }
        else
          for (int i = 0; i < n; i++)
            Array.set(array, i, Vio.read(input, component));
        return array;
      }
  }

  /**
   * Write the array to the input stream.
   */
  public void write_value(OutputStream output, Serializable value)
  {
    if (output instanceof gnuValueStream)
      {
        gnuRuntime r = ((gnuValueStream) output).getRunTime();
        if (r != null)
          r.target = null;
      }

    if (value instanceof byte[])
      OctetSeqHelper.write(output, (byte[]) value);
    else if (value instanceof String[])
      {
        String[] s = (String[]) value;
        output.write_long(s.length);
        for (int i = 0; i < s.length; i++)
          Vio.write(output, s[i], Vio.m_StringValueHelper);
      }
    else if (value instanceof int[])
      LongSeqHelper.write(output, (int[]) value);
    else if (value instanceof long[])
      LongLongSeqHelper.write(output, (long[]) value);
    else if (value instanceof double[])
      DoubleSeqHelper.write(output, (double[]) value);
    else if (value instanceof float[])
      FloatSeqHelper.write(output, (float[]) value);
    else if (value instanceof boolean[])
      BooleanSeqHelper.write(output, (boolean[]) value);
    else if (value instanceof short[])
      ShortSeqHelper.write(output, (short[]) value);
    else if (value instanceof char[])
      CharSeqHelper.write(output, (char[]) value);
    else
      {
        // Write others, use reflection.
        component = arrayClass.getComponentType();

        int n = Array.getLength(value);
        output.write_long(n);
        if (written_as_object())
          for (int i = 0; i < n; i++)
            {
              Object o = Array.get(value, i);
              if (o == null)
                output.write_Object(null);
              else
                // CORBA objects have another notation.
                handler.writeValue(output, (Serializable) o);
            }
        else
          {
            for (int i = 0; i < n; i++)
              Vio.write(output, (Serializable) Array.get(value, i),
                component);
          }

      }
  }
}
