/* Vio.java -- Value type IO operations.
   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.Minor;
import gnu.CORBA.ObjectCreator;

import gnu.java.lang.CPStringBuilder;

import org.omg.CORBA.CustomMarshal;
import org.omg.CORBA.DataInputStream;
import org.omg.CORBA.DataOutputStream;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.StringSeqHelper;
import org.omg.CORBA.StringValueHelper;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.WStringValueHelper;
import org.omg.CORBA.portable.BoxedValueHelper;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.Streamable;
import org.omg.CORBA.portable.ValueFactory;

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.StringTokenizer;

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

/**
 * A specialised class for reading and writing the value types.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 */
public abstract class Vio
{
  /**
   * If true, wrap value type data into chunks. This decrease the performance,
   * and is not required for interoperability with jdk 1.5, but is left in the
   * implementation as the optional mode for solving possible interoperability
   * problems with non-Sun CORBA implementations.
   *
   * The current implementation would accept both single chunk or multiple
   * chunks, but will always send a single chunk (if true) or unchunked data (if
   * false).
   */
  public static boolean USE_CHUNKING = false;

  /**
   * The first field in the value record. The last octet may contain additional
   * flags (vf_CODEBASE, vf_ID and vf_MULTIPLE_IDS). The tag value is different
   * for the indirections (vt_INDIRECTION) and nulls (vt_NULL).
   */
  public static final int vt_VALUE_TAG = 0x7fffff00;

  /**
   * The value tag flag, indicating that the codebase URL is present in the
   * value tag record.
   */
  public static final int vf_CODEBASE = 0x1;

  /**
   * The value tag flag, indicating that a single repository id is present in
   * the value tag record.
   */
  public static final int vf_ID = 0x2;

  /**
   * The value tag flag, indicating, that there are multiple repository ids
   * present in the record. If this flag is set, the flag vf_ID must also be
   * set, resulting the value of the least significant byte 0x6.
   */
  public static final int vf_MULTIPLE_IDS = 0x4;

  /**
   * The value tag flag, indicating the presence of chunking. Each chunk is
   * preceeded by a positive int, indicating the number of bytes in the chunk. A
   * sequence of chunks is terminated by a non positive int.
   */
  public static final int vf_CHUNKING = 0x8;

  /**
   * The indirection tag value. Such tag must be followed by the CORBA long,
   * indicating the offset in the CORBA message, where the indirected
   * information is present. This offset is assumed zero at the position where
   * the mentioned CORBA long starts and can refer both forward (positive
   * values) and backward (negative values).
   */
  public static final int vt_INDIRECTION = 0xffffffff;

  /**
   * This tag value means that the value object being transferred is equal to
   * null.
   */
  public static final int vt_NULL = 0x0;

  /**
   * The size of CORBA long (java int).
   */
  static final int INT_SIZE = 4;

  /**
   * The String value helper (one instance is sufficient).
   */
  public static final WStringValueHelper m_StringValueHelper = new WStringValueHelper();

  /**
   * An instance of the value handler.
   */
  static ValueHandler handler = Util.createValueHandler();

  /**
   * Read the value base from the given input stream. Determines the required
   * class from the repository id. This includes operations that are not
   * required when an unitialised instance or at least class of the value type
   * is known. Hence it may be faster to use the alternative methods,
   * read(InputStream, Class) or read(InputStream, Serializable).
   *
   * @param input a stream to read from.
   *
   * @return the loaded value.
   *
   * @throws MARSHAL if the reading has failed due any reason.
   */
  public static Serializable read(InputStream input)
  {
    return read(input, (String) null);
  }

  /**
   * Read the value base from the given input stream. Determines the required
   * class from the repository id. This includes operations that are not
   * required when an unitialised instance or at least class of the value type
   * is known. Hence it may be faster to use the alternative methods,
   * read(InputStream, Class) or read(InputStream, Serializable).
   *
   * @param input a stream to read from.
   * @param repository_id a repository id of the object being read, may be null.
   *
   * @return the loaded value.
   *
   * @throws MARSHAL if the reading has failed due any reason.
   */
  public static Serializable read(InputStream input, String repository_id)
  {
    try
      {
        final int position = getCurrentPosition(input);
        // We may need to jump back if the value is read via value factory.
        input.mark(512);

        int value_tag = input.read_long();
        checkTag(value_tag);

        String codebase = null;
        String[] ids = null;
        String id = repository_id;

        // Check for the agreed null value.
        if (value_tag == vt_NULL)
          return null;
        else if (value_tag == vt_INDIRECTION)
          return readIndirection(input);
        else
          {
            // Read the value.
            if ((value_tag & vf_CODEBASE) != 0)
              {
                // The codebase is present. The codebase is a space
                // separated list of URLs from where the implementing
                // code can be downloaded.
                codebase = read_string(input);
              }

            if ((value_tag & vf_MULTIPLE_IDS) != 0)
              {
                // Multiple supported repository ids are present.
                ids = read_string_array(input);
              }
            else if ((value_tag & vf_ID) != 0)
              {
                // Single supported repository id is present.
                id = read_string(input);
              }
          }

        BoxedValueHelper helper = getHelper(null, id);
        // The existing implementing object.
        java.lang.Object ox = null;

        if (helper != null)
          ox = null; // Helper will care about the instantiating.
        else if (id.equals(WStringValueHelper.id()))
          helper = m_StringValueHelper;
        else
          ox = createInstance(id, ids, codebase);
        return (Serializable) read_instance(input, position, ox, value_tag,
          helper, id, ids, codebase);
      }
    catch (Exception ex)
      {
        MARSHAL m = new MARSHAL();
        m.minor = Minor.Value;
        m.initCause(ex);
        throw m;
      }
  }

  /**
   * Read the value base from the given input stream when the value base class
   * is available. Hence there is no need to guess it from the repository id.
   *
   * @param input a stream to read from.
   * @param value_class the class of the value being read.
   *
   * @return the loaded value.
   *
   * @throws MARSHAL if the reading has failed due any reason.
   */
  public static Serializable read(InputStream input, Class value_class)
  {
    final int position = getCurrentPosition(input);

    String id = null;
    String[] ids = null;
    String codebase = null;

    try
      {
        int value_tag = input.read_long();
        checkTag(value_tag);

        // Check for the agreed null value.
        if (value_tag == vt_NULL)
          return null;
        else if (value_tag == vt_INDIRECTION)
          return readIndirection(input);
        else
          {
            // Read the value.
            if ((value_tag & vf_CODEBASE) != 0)
              {
                // The codebase is present.
                codebase = read_string(input);
              }

            if ((value_tag & vf_MULTIPLE_IDS) != 0)
              {
                // Multiple supported repository ids are present.
                ids = read_string_array(input);
              }
            else if ((value_tag & vf_ID) != 0)
              {
                // Single supported repository id is present.
                id = read_string(input);
              }
          }

        BoxedValueHelper vHelper = id != null ? getHelper(value_class, id)
          : getHelper(value_class, ids);

        java.lang.Object ox;

        if (vHelper == null)
          {
            try
              {
                ox = createInstance(id, ids, codebase);
              }
            catch (Exception e)
              {
                ox = null;
              }

            if (ox != null)
              {
                if (value_class != null
                  && !value_class.isAssignableFrom(ox.getClass()))
                  {
                    MARSHAL m = new MARSHAL(ox.getClass() + " is not a "
                    + value_class.getName());
                    m.minor = Minor.ClassCast;
                    throw m;
                  }
              }
          }
        else
          ox = null;

        ox = read_instance(input, position, ox, value_tag, vHelper, id, ids,
          codebase);
        return (Serializable) ox;
      }
    catch (MARSHAL m)
      {
        throw m;
      }
    catch (SystemException sysEx)
      {
        // OK.
        throw sysEx;
      }
    catch (Exception ex)
      {
        MARSHAL m = new MARSHAL("Cant read " + value_class);
        m.minor = Minor.Value;
        m.initCause(ex);
        throw m;
      }
  }

  /**
   * Read the value base from the given input stream when the unitialised
   * instance is available. Hence there is no need to guess the class from the
   * repository id and then to instantiate an instance.
   *
   * @param input a stream to read from.
   *
   * @param value_instance an pre-created instance of the value. If the helper
   * is not null, this parameter is ignored an should be null.
   *
   * @param helper a helper to create an instance and read the object- specific
   * part of the record. If the value_instance is used instead, this parameter
   * should be null.
   *
   * @return the loaded value.
   *
   * @throws MARSHAL if the reading has failed due any reason.
   */
  public static Object read(InputStream input, Object value_instance,
    BoxedValueHelper helper)
  {
    final int position = getCurrentPosition(input);

    String id = null;
    String[] ids = null;
    String codebase = null;

    try
      {
        int value_tag = input.read_long();
        checkTag(value_tag);

        // Check for the agreed null value.
        if (value_tag == vt_NULL)
          return null;
        else if (value_tag == vt_INDIRECTION)
          return readIndirection(input);
        else
          {
            // Read the value.
            if ((value_tag & vf_CODEBASE) != 0)
              {
                // The codebase is present.
                codebase = read_string(input);
              }

            if ((value_tag & vf_MULTIPLE_IDS) != 0)
              {
                // Multiple supported repository ids are present.
                ids = read_string_array(input);
              }
            else if ((value_tag & vf_ID) != 0)
              {
                // Single supported repository id is present.
                id = read_string(input);
              }
          }

        Class value_class = value_instance == null ? null
          : value_instance.getClass();

        if (helper == null)
          helper = id != null ? getHelper(value_class, id) : getHelper(
            value_class, ids);

        value_instance = read_instance(input, position, value_instance,
          value_tag, helper, id, ids, codebase);
        return value_instance;
      }
    catch (Exception ex)
      {
        MARSHAL m = new MARSHAL();
        m.minor = Minor.Value;
        m.initCause(ex);
        throw m;
      }
  }

  /**
   * Read using provided boxed value helper. This method expects the full value
   * type header, followed by contents, that are delegated to the provided
   * helper. It handles null.
   *
   * @param input the stream to read from.
   * @param helper the helper that reads the type-specific part of the content.
   *
   * @return the value, created by the helper, or null if the header indicates
   * that null was previously written.
   */
  public static Serializable read(InputStream input, BoxedValueHelper helper)
  {
    return (Serializable) read(input, null, helper);
  }

  /**
   * Fill in the instance fields by the data from the input stream. The method
   * assumes that the value header, if any, is already behind. The information
   * from the stream is stored into the passed ox parameter.
   *
   * @param input an input stream to read from.
   *
   * @param value a pre-instantiated value type object, must be either
   * Streamable or CustomMarshal. If the helper is used, this parameter is
   * ignored and should be null.
   *
   * @param value_tag the tag that must be read previously.
   * @param helper the helper for read object specific part; may be null to read
   * in using other methods.
   *
   * @return the value that was read.
   */
  static Object read_instance(InputStream input, final int position,
    Object value, int value_tag, BoxedValueHelper helper, String id,
    String[] ids, String codebase)
  {
    if (helper != m_StringValueHelper && id != null)
      if (id.equals(StringValueHelper.id()))
        {
          value = null;
          helper = m_StringValueHelper;
        }

    try
      {
        if ((value_tag & vf_CHUNKING) != 0)
          {
            BufferedCdrOutput output = createBuffer(input, 1024);
            // Read the current (not a nested one) value in this spec case.
            readNestedValue(value_tag, input, output, -1);
            BufferredCdrInput ci = new BufferredCdrInput(output.buffer.getBuffer());
            ci.setRunTime(output.getRunTime());

            input = new HeadlessInput(ci, input);
          }
        else
          {
            if (input instanceof BufferredCdrInput)
              {
                // Highly probable case.
                input = new HeadlessInput((BufferredCdrInput) input, null);
              }
            else if (input instanceof HeadlessInput)
              {
                // There is no need to instantiate one more HeadlessInput
                // as we can just reset.
                ((HeadlessInput) input).subsequentCalls = false;
              }
            else
              {
                BufferedCdrOutput bout = new BufferedCdrOutput();
                int c;
                while ((c = input.read()) >= 0)
                  bout.write((byte) c);
                input = new HeadlessInput(
                  (BufferredCdrInput) bout.create_input_stream(), input);
              }
          }
      }
    catch (IOException ex)
      {
        MARSHAL m = new MARSHAL("Unable to read chunks");
        m.minor = Minor.Value;
        m.initCause(ex);
        throw m;
      }

    return readValue(input, position, value, helper, id, ids, codebase);
  }

  /**
   * Create a buffer, inheriting critical settings from the passed input stream.
   */
  private static BufferedCdrOutput createBuffer(InputStream input, int proposed_size)
  {
    BufferedCdrOutput bout;
    bout = new BufferedCdrOutput(2 * proposed_size + 256);

    if (input instanceof BufferredCdrInput)
      {
        BufferredCdrInput in = (BufferredCdrInput) input;
        bout.setBigEndian(in.isBigEndian());
      }

    if (input instanceof gnuValueStream)
      bout.setRunTime(((gnuValueStream) input).getRunTime());
    else
      bout.setRunTime(new gnuRuntime(null, null));
    return bout;
  }

  /**
   * Read the chunked nested value from the given input stream, transferring the
   * contents to the given output stream.
   *
   * @param value_tag the value tag of the value being read.
   * @param input the input stream from where the remainder of the nested value
   * must be read.
   * @param output the output stream where the unchunked nested value must be
   * copied.
   *
   * @return the tag that ended the nested value.
   */
  public static int readNestedValue(int value_tag, InputStream input,
    BufferedCdrOutput output, int level)
    throws IOException
  {
    String id = null;
    if (level < -1)
      {
        // For the first level, this information is already behind.
        output.write_long(value_tag - vf_CHUNKING);

        // The nested value should be aways chunked.
        if ((value_tag & vf_CHUNKING) == 0)
          {
            MARSHAL m = new MARSHAL("readNestedValue: must be chunked");
            m.minor = Minor.Chunks;
            throw m;
          }
        else if (value_tag == vt_NULL)
          {
            MARSHAL m = new MARSHAL("readNestedValue: nul");
            m.minor = Minor.Chunks;
            throw m;
          }
        else if (value_tag == vt_INDIRECTION)
          {
            MARSHAL m = new MARSHAL("readNestedValue: indirection");
            m.minor = Minor.Chunks;
            throw m;
          }
        else
          {
            // Read the value.
            if ((value_tag & vf_CODEBASE) != 0)
              {
                String codebase = read_string(input);
                write_string(output, codebase);
              }

            if ((value_tag & vf_MULTIPLE_IDS) != 0)
              {
                // Multiple supported repository ids are present.
                String[] ids = read_string_array(input);
                id = ids[0];
                write_string_array(output, ids);
              }
            else if ((value_tag & vf_ID) != 0)
              {
                id = read_string(input);
                write_string(output, id);
              }
          }
      }

    int n = -1;

    // Read all chunks.
    int chunk_size;

    byte[] r = null;

    while (true)
      {
        // Read the size of the next chunk or it may also be the
        // header of the nested value.
        chunk_size = input.read_long();

        // End of chunk terminator.
        if (chunk_size < 0 && chunk_size >= level)
          return chunk_size;
        else if (chunk_size >= 0x7FFFFF00)
          {
            int onInput = getCurrentPosition(input) - 4;
            int onOutput = output.getPosition();
            output.getRunTime().redirect(onInput, onOutput);
            // Value over 0x7FFFFF00 indicates that the nested value
            // starts here. Read the nested value, storing it into the output.
            // First parameter is actually the value tag.
            chunk_size = readNestedValue(chunk_size, input, output, level - 1);
            if (chunk_size < 0 && chunk_size >= level)
              return chunk_size;
          }
        else
          {
            // The chunk follows.
            if (r == null || r.length < chunk_size)
              r = new byte[chunk_size + 256];

            n = 0;
            while (n < chunk_size)
              n += input.read(r, n, chunk_size - n);
            output.write(r, 0, n);
          }
      }
  }

  /**
   * Read the value (the header must be behind).
   */
  public static Serializable readValue(InputStream input, final int position,
    Object value, BoxedValueHelper helper, String id, String[] ids,
    String codebase)
  {
    gnuRuntime g;
    gnuValueStream c = ((gnuValueStream) input);
    if (c.getRunTime() == null)
      {
        g = new gnuRuntime(codebase, value);
        c.setRunTime(g);
      }
    else
      {
        g = c.getRunTime();
        g.addCodeBase(codebase);
        g.target = (Serializable) value;
      }
    if (value != null)
      g.objectWritten(value, position);

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

    boolean ok = true;

    // The user-defined io operations are implemented.
    if (value instanceof CustomMarshal)
      {
        CustomMarshal marsh = (CustomMarshal) value;
        marsh.unmarshal((DataInputStream) input);
      }
    else
    // The IDL-generated io operations are implemented.
    if (value instanceof Streamable)
      {
        ((Streamable) value)._read(input);
      }
    else if (helper != null)
      {
        // If helper is non-null the value should normally be null.
        value = helper.read_value(input);
        g.objectWritten(value, position);
      }
    else
      {
        ok = false;
        ValueFactory factory = null;
        org.omg.CORBA_2_3.ORB orb = (org.omg.CORBA_2_3.ORB) input.orb();

        if (id != null)
          factory = orb.lookup_value_factory(id);

        if (factory == null && ids != null)
          {
            for (int i = 0; i < ids.length && factory == null; i++)
              {
                factory = orb.lookup_value_factory(ids[i]);
              }
          }

        if (factory != null)
          {
            value = factory.read_value((org.omg.CORBA_2_3.portable.InputStream) input);
            ok = true;
          }
      }

    if (!ok && value instanceof Serializable)
    // Delegate to ValueHandler
      {
        if (ids != null && ids.length > 0)
          id = ids[0];

        value = handler.readValue(input, position, value.getClass(), id, g);
        ok = true;
      }

    if (!ok)
      {
        if (value != null)
          {
            MARSHAL m = new MARSHAL(value.getClass().getName()
            + " must be Streamable, CustomMarshal or Serializable");
            m.minor = Minor.UnsupportedValue;
            throw m;
          }
        else
          {
            MARSHAL m = new MARSHAL("Unable to instantiate " + id + ":" + list(ids)
            + " helper " + helper);
            m.minor = Minor.UnsupportedValue;
            throw m;
          }
      }
    else
      return (Serializable) value;
  }

  /**
   * Conveniency method to list ids in exception reports.
   */
  static String list(String[] s)
  {
    if (s == null)
      return "null";
    else
      {
        CPStringBuilder b = new CPStringBuilder("{");
        for (int i = 0; i < s.length; i++)
          {
            b.append(s[i]);
            b.append(" ");
          }
        b.append("}");
        return b.toString();
      }
  }

  /**
   * Write the value base into the given stream.
   *
   * @param output a stream to write to.
   *
   * @param value a value type object, must be either Streamable or
   * CustomMarshal.
   *
   * @throws MARSHAL if the writing failed due any reason.
   */
  public static void write(OutputStream output, Serializable value)
  {
    // Write null if this is a null value.
    if (value == null)
      output.write_long(vt_NULL);
    else if (value instanceof String)
      write(output, value, m_StringValueHelper);
    else
      write(output, value, value.getClass());
  }

  /**
   * Write the value base into the given stream, stating that it is an instance
   * of the given class.
   *
   * @param output a stream to write to.
   *
   * @param value a value to write.
   *
   * @throws MARSHAL if the writing failed due any reason.
   */
  public static void write(OutputStream output, Serializable value,
    Class substitute)
  {
    // Write null if this is a null value.
    if (value == null)
      output.write_long(vt_NULL);
    else if (value instanceof String || substitute == String.class)
      writeString(output, value);
    else
      {
        String vId = ObjectCreator.getRepositoryId(value.getClass());
        if (substitute == null || value.getClass().equals(substitute))
          write_instance(output, value, vId, getHelper(value.getClass(), vId));
        else
          {
            String vC = ObjectCreator.getRepositoryId(substitute);
            String[] ids = new String[] { vId, vC };
            BoxedValueHelper h = getHelper(substitute.getClass(), ids);
            // If the helper is available, it is also responsible for
            // providing the repository Id. Otherwise, write both
            // ids.
            if (h == null)
              write_instance(output, value, ids, null);
            else
              write_instance(output, value, h.get_id(), null);
          }
      }
  }

  /**
   * Write the value base into the given stream, supplementing it with an array
   * of the provided repository ids plus the repository id, derived from the
   * passed value.
   *
   * @param output a stream to write to.
   *
   * @param value a value to write.
   *
   * @throws MARSHAL if the writing failed due any reason.
   */
  public static void write(OutputStream output, Serializable value,
    String[] multiple_ids)
  {
    // Write null if this is a null value.
    if (value == null)
      output.write_long(vt_NULL);
    else
      {
        String[] ids = new String[multiple_ids.length + 1];
        ids[0] = ObjectCreator.getRepositoryId(value.getClass());
        System.arraycopy(multiple_ids, 0, ids, 1, multiple_ids.length);
        BoxedValueHelper h = getHelper(value.getClass(), ids);
        write_instance(output, value, ids, h);
      }
  }

  /**
   * Write value when its repository Id is explicitly given. Only this Id is
   * written, the type of value is not taken into consideration.
   *
   * @param output an output stream to write into.
   * @param value a value to write.
   * @param id a value repository id.
   */
  public static void write(OutputStream output, Serializable value, String id)
  {
    if (value == null)
      output.write_long(vt_NULL);
    else
      write_instance(output, value, id, getHelper(value.getClass(), id));
  }

  /**
   * Write standard value type header, followed by contents, produced by the
   * boxed value helper.
   *
   * @param output the stream to write to.
   * @param value the value to write, can be null.
   * @param helper the helper that writes the value content if it is not null
   * (must be provided for this method).
   */
  public static void write(OutputStream output, Serializable value,
    BoxedValueHelper helper)
  {
    if (helper == null)
      throw new AssertionError("Helper must be provided");
    if (value == null)
      output.write_long(vt_NULL);
    else
      write_instance(output, value, helper.get_id(), helper);
  }

  /**
   * Write the parameter that is surely a string and not null.
   */
  private static void writeString(OutputStream output, Serializable string)
  {
    write_instance(output, string, m_StringValueHelper.get_id(),
      m_StringValueHelper);
  }

  /**
   * Write value when its repository Id is explicitly given. Does not handle
   * null.
   *
   * @param output an output stream to write into.
   * @param value a value to write.
   * @param ids a value repository id (can be either single string or string
   * array).
   * @param helper a helper, writing object - specifical part. Can be null if
   * the value should be written using other methods.
   */
  static void write_instance(OutputStream output, Serializable value,
    Object ids, BoxedValueHelper helper)
  {
    gnuValueStream rout = null;
    gnuRuntime runtime = null;

    try
      {
        if (output instanceof gnuValueStream)
          {
            int position;
            rout = (gnuValueStream) output;
            runtime = rout.getRunTime();

            if (runtime == null)
              {
                runtime = new gnuRuntime(null, value);
                rout.setRunTime(runtime);
                rout.getRunTime().objectWritten(value,
                  position = rout.getPosition());
              }
            else if (runtime.target == value)
              {
                if (!writeSelf(output, value))
                  throw new InternalError("Recursive helper call for "
                    + value.getClass().getName());
                return;
              }
            else
              {
                position = runtime.isWrittenAt(value);
                if (position >= 0)
                  {
                    // The object was already written.
                    output.write_long(vt_INDIRECTION);
                    output.write_long(position - rout.getPosition());
                    // Replacing object write data by indirection reference.
                    return;
                  }
                else
                  {
                    runtime.objectWritten(value, position = rout.getPosition());
                  }
              }
          }

        int value_tag = vt_VALUE_TAG;

        if (ids instanceof String)
          value_tag |= vf_ID;
        else if (ids instanceof String[])
          // OMG standard requires to set both flags.
          value_tag |= vf_MULTIPLE_IDS | vf_ID;

        int chunkSizeLocation;

        OutputStream outObj;

        if (USE_CHUNKING)
          {
            // Wrap the value being written into one chunk (makes sense only for
            // compatibility reasons).
            outObj = output;
            value_tag |= vf_CHUNKING;
          }
        else
          outObj = output;

        output.write_long(value_tag);

        if ((value_tag & vf_MULTIPLE_IDS) != 0)
          write_string_array(output, (String[]) ids);
        else if ((value_tag & vf_ID) != 0)
          write_string(output, (String) ids);

        if (USE_CHUNKING)
          {
            // So far, write 0x55555555 instead of the chunk size (alignment may
            // take place).
            output.write_long(0x55555555);
            // If the chunking is involved, the chunk size must be written here.
            chunkSizeLocation = rout.getPosition() - INT_SIZE;
          }
        else
          // Not in use for this case.
          chunkSizeLocation = -1;

        writeValue(outObj, value, helper);

        if (USE_CHUNKING)
          {
            // Write the chunk size where the place for it was reserved.
            int chunkSize = rout.getPosition() - chunkSizeLocation - INT_SIZE;
            int current = rout.getPosition();
            rout.seek(chunkSizeLocation);
            output.write_long(chunkSize);
            rout.seek(current);

            // The end of record marker.
            output.write_long(-1);
          }
      }
    finally
      {
        if (runtime != null)
          runtime.target = null;
      }
  }

  /**
   * Write value (after header).
   */
  static void writeValue(OutputStream output, Serializable value,
    BoxedValueHelper helper)
  {
    ((gnuValueStream) output).getRunTime().target = value;
    if (helper != null)
      helper.write_value(output, value);
    else if (!writeSelf(output, value))
      {
        // Try to find helper via class loader.
        boolean ok = false;

        if (!ok)
          {
            if (output instanceof BufferedCdrOutput)
              {
                BufferedCdrOutput b = (BufferedCdrOutput) output;
                if (b.runtime == null)
                  b.runtime = new gnuRuntime(null, value);
              }

            handler.writeValue(output, value);
          }
      }
  }

  /**
   * Try to write value supposing that it implements self-streamable interfaces.
   * Return false if it does not or true on success.
   */
  static boolean writeSelf(OutputStream output, Serializable value)
  {
    // User defined write method is present.
    if (value instanceof CustomMarshal)
      {
        ((CustomMarshal) value).marshal((DataOutputStream) output);
        return true;
      }
    else if (value instanceof Streamable)
      {
        ((Streamable) value)._write(output);
        return true;
      }
    return false;
  }

  /**
   * Read the indirection data and return the object that was already written to
   * this stream.
   *
   * @param an_input the input stream, must be BufferredCdrInput.
   */
  static Serializable readIndirection(InputStream an_input)
  {
    if (!(an_input instanceof gnuValueStream))
      throw new NO_IMPLEMENT(gnuValueStream.class.getName()
        + " expected as parameter");

    gnuValueStream in = (gnuValueStream) an_input;

    int current_pos = in.getPosition();

    int offset = an_input.read_long();
    if (offset > -INT_SIZE)
      {
        MARSHAL m = new MARSHAL("Indirection tag refers to " + offset
        + " (must be less than -" + INT_SIZE + ")");
        m.minor = Minor.Offset;
        throw m;
      }

    int stored_at = current_pos + offset;

    if (in.getRunTime() == null)
      {
        MARSHAL m = new MARSHAL(stored_at + " offset " + offset + ": not written");
        m.minor = Minor.Value;
        throw m;
      }

    return (Serializable) in.getRunTime().isObjectWrittenAt(stored_at, offset);
  }

  /**
   * Check the passed value tag for correctness.
   *
   * @param value_tag a tag to check, must be between 0x7fffff00 and 0x7fffffff
   *
   * @throws MARSHAL if the tag is outside this interval.
   */
  static void checkTag(int value_tag)
  {
    if ((value_tag < 0x7fffff00 || value_tag > 0x7fffffff)
      && value_tag != vt_NULL && value_tag != vt_INDIRECTION)
      {
        MARSHAL m = new MARSHAL("Invalid value record, unsupported header tag: "
        + value_tag + " (0x" + Integer.toHexString(value_tag) + ")");
        m.minor = Minor.ValueHeaderTag;
        throw m;
      }

    if ((value_tag & vf_MULTIPLE_IDS) != 0 && (value_tag & vf_ID) == 0)
      {
        MARSHAL m = new MARSHAL("Invalid value record header flag combination (0x"
        + Integer.toHexString(value_tag) + ")");
        m.minor = Minor.ValueHeaderFlags;
        throw m;
      }
  }

  /**
   * Throw MARSHAL.
   */
  static void throwIt(String msg, String id1, String id2, Throwable e)
    throws MARSHAL
  {
    MARSHAL m = new MARSHAL(msg + ":'" + id1 + "' versus '" + id2 + "'");
    if (e != null)
      m.initCause(e);
    m.minor = Minor.Value;
    throw m;
  }

  /**
   * Load class by name and create the instance.
   */
  static Object createInstance(String id, String[] ids, String codebase)
  {
    Object o = null;

    if (id != null)
      o = _createInstance(id, codebase);

    if (ids != null)
      for (int i = 0; i < ids.length && o == null; i++)
        o = _createInstance(ids[i], codebase);
    return o;
  }

  static Object _createInstance(String id, String codebase)
  {
    if (id == null)
      return null;
    if (id.equals(StringValueHelper.id()))
      return "";
    StringTokenizer st = new StringTokenizer(id, ":");

    String prefix = st.nextToken();
    if (prefix.equalsIgnoreCase("IDL"))
      return ObjectCreator.Idl2Object(id);
    else if (prefix.equalsIgnoreCase("RMI"))
      {
        String className = st.nextToken();
        String hashCode = st.nextToken();
        String sid = null;
        if (st.hasMoreElements())
          sid = st.nextToken();

        try
          {
            Class objectClass = Util.loadClass(className, codebase,
              Vio.class.getClassLoader());

            String rid = ObjectCreator.getRepositoryId(objectClass);

            if (!rid.equals(id))
              {
                // If direct string comparison fails, compare by meaning.
                StringTokenizer st2 = new StringTokenizer(rid, ":");
                if (!st2.nextToken().equals("RMI"))
                  throw new InternalError("RMI format expected: '" + rid + "'");
                if (!st2.nextToken().equals(className))
                  throwIt("Class name mismatch", id, rid, null);

                try
                  {
                    long h1 = Long.parseLong(hashCode, 16);
                    long h2 = Long.parseLong(st2.nextToken(), 16);
                    if (h1 != h2)
                      throwIt("Hashcode mismatch", id, rid, null);

                    if (sid != null && st2.hasMoreTokens())
                      {
                        long s1 = Long.parseLong(hashCode, 16);
                        long s2 = Long.parseLong(st2.nextToken(), 16);
                        if (s1 != s2)
                          throwIt("serialVersionUID mismatch", id, rid, null);
                      }
                  }
                catch (NumberFormatException e)
                  {
                    throwIt("Invalid hashcode or svuid format: ", id, rid, e);
                  }
              }

            // Low - level instantiation required here.
            return instantiateAnyWay(objectClass);
          }
        catch (Exception ex)
          {
            MARSHAL m = new MARSHAL("Unable to instantiate " + id);
            m.minor = Minor.Instantiation;
            m.initCause(ex);
            throw m;
          }
      }
    else
      throw new NO_IMPLEMENT("Unsupported prefix " + prefix + ":");
  }

  /**
   * Read string, expecting the probable indirection.
   */
  static String read_string(InputStream input)
  {
    gnuValueStream g = (gnuValueStream) input;
    int previous = g.getPosition();
    int l = input.read_long();
    if (l != vt_INDIRECTION)
      {
        g.seek(previous);
        String s = input.read_string();
        if (g.getRunTime() == null)
          g.setRunTime(new gnuRuntime(null, null));
        g.getRunTime().singleIdWritten(s, previous);
        return s;
      }
    else
      {
        gnuRuntime r = g.getRunTime();
        int base = g.getPosition();
        int delta = input.read_long();
        if (r == null)
          {
            previous = g.getPosition();
            g.seek(base + delta);
            String indir = input.read_string();
            g.seek(previous);
            return indir;
          }
        else
          {
            return (String) r.isObjectWrittenAt(base + delta, delta);
          }
      }
  }

  /**
   * Read string array, expecting the probable indirection.
   */
  static String[] read_string_array(InputStream input)
  {
    gnuValueStream g = (gnuValueStream) input;
    int previous = g.getPosition();
    int l = input.read_long();
    if (l != vt_INDIRECTION)
      {
        g.seek(previous);
        String[] s = StringSeqHelper.read(input);
        if (g.getRunTime() == null)
          g.setRunTime(new gnuRuntime(null, null));
        g.getRunTime().objectWritten(s, previous);
        return s;
      }
    else
      {
        gnuRuntime r = g.getRunTime();
        int base = g.getPosition();
        int delta = input.read_long();
        if (r == null)
          {
            previous = g.getPosition();
            g.seek(base + delta);
            String[] indir = StringSeqHelper.read(input);
            g.seek(previous);
            return indir;
          }
        else
          {
            return (String[]) r.isObjectWrittenAt(base + delta, delta);
          }
      }
  }

  /**
   * Write repository Id, probably shared.
   */
  static void write_string(OutputStream output, String id)
  {
    if (output instanceof gnuValueStream)
      {
        gnuValueStream b = (gnuValueStream) output;
        if (b != null)
          {
            int written = b.getRunTime().idWrittenAt(id);
            if (written >= 0)
              {
                // Reuse existing id record.
                output.write_long(vt_INDIRECTION);
                int p = b.getPosition();
                output.write_long(written - p);
              }
            else
              {
                b.getRunTime().singleIdWritten(id, b.getPosition());
                output.write_string(id);
              }
          }
      }
    else
      output.write_string(id);
  }

  /**
   * Write repository Id, probably shared.
   */
  static void write_string_array(OutputStream output, String[] ids)
  {
    if (output instanceof gnuValueStream)
      {
        gnuValueStream b = (gnuValueStream) output;
        if (b != null)
          {
            int written = b.getRunTime().idWrittenAt(ids);
            if (written >= 0)
              {
                // Reuse existing id record.
                output.write_long(vt_INDIRECTION);
                int p = b.getPosition();
                output.write_long(written - p);
              }
            else
              {
                b.getRunTime().multipleIdsWritten(ids, b.getPosition());
                StringSeqHelper.write(output, ids);
              }
          }
      }
    else
      StringSeqHelper.write(output, ids);
  }

  /**
   * Get the helper that could write the given object, or null if no pre-defined
   * helper available for this object.
   */
  public static BoxedValueHelper getHelper(Class x, Object ids)
  {
    if (x != null && x.equals(String.class))
      return m_StringValueHelper;
    else if (x != null && x.isArray())
      return new ArrayValueHelper(x);
    else if (ids instanceof String)
      return locateHelper((String) ids);
    else if (ids instanceof String[])
      {
        String[] ia = (String[]) ids;
        BoxedValueHelper h;
        for (int i = 0; i < ia.length; i++)
          {
            h = locateHelper(ia[i]);
            if (h != null)
              return h;
          }
        return null;
      }
    else
      return null;
  }

  /**
   * Get the helper that could write the given object, or null if no pre-defined
   * helper available for this object.
   */
  public static BoxedValueHelper getHelper(Class x, String id)
  {
    if (x != null && x.equals(String.class))
      return m_StringValueHelper;
    else if (x != null && x.isArray())
      return new ArrayValueHelper(x);
    else
      return locateHelper(id);
  }

  /**
   * Try to locate helper from the repository id.
   */
  static BoxedValueHelper locateHelper(String id)
  {
    if (id != null)
      {
        if (id.equals(m_StringValueHelper.get_id()))
          return m_StringValueHelper;
        else
        // Try to locate helper for IDL type.
        if (id.startsWith("IDL:"))
          {
            try
              {
                Class helperClass = ObjectCreator.findHelper(id);
                if (BoxedValueHelper.class.isAssignableFrom(helperClass))
                  return (BoxedValueHelper) helperClass.newInstance();
                else if (helperClass != null)
                  return new IDLTypeHelper(helperClass);
                else
                  return null;
              }
            catch (Exception ex)
              {
                return null;
              }
          }
      }
    return null;
  }

  /**
   * Get the current position.
   */
  static int getCurrentPosition(InputStream x)
  {
    if (x instanceof gnuValueStream)
      return ((gnuValueStream) x).getPosition();
    else
      return 0;
  }

  /**
   * Instantiate an instance of this class anyway; also in the case when it has
   * no parameterless or any other constructor. The fields will be assigned
   * while reading the class from the stream.
   *
   * @param clazz a class for that the instance should be instantiated.
   */
  public static Object instantiateAnyWay(Class clazz)
    throws Exception
  {
    Class first_nonserial = clazz;

    while (Serializable.class.isAssignableFrom(first_nonserial)
      || Modifier.isAbstract(first_nonserial.getModifiers()))
      first_nonserial = first_nonserial.getSuperclass();

    final Class local_constructor_class = first_nonserial;

    Constructor constructor = local_constructor_class.getDeclaredConstructor(new Class[0]);

    return VMVio.allocateObject(clazz, constructor.getDeclaringClass(),
      constructor);
  }
}
