/* ResponseHandlerImpl.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.BufferedCdrOutput;
import gnu.CORBA.GIOP.MessageHeader;
import gnu.CORBA.GIOP.ReplyHeader;
import gnu.CORBA.GIOP.RequestHeader;
import gnu.CORBA.GIOP.CodeSetServiceContext;

import org.omg.CORBA.ORB;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;

/**
 * Provides the CDR output streams for writing the response to the given buffer.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 */
public class ResponseHandlerImpl
  implements ResponseHandler
{
  /**
   * The message header. This field is used to compute the size and alignments.
   * It is, however, never directly written to the buffer stream.
   */
  public final MessageHeader message_header;

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

  /**
   * The reply header.
   */
  public final ReplyHeader reply_header;

  /**
   * The request header.
   */
  public final RequestHeader request_header;

  /**
   * True if the stream was obtained by invoking {@link #createExceptionReply()},
   * false otherwise.
   */
  private boolean exceptionReply;

  /**
   * The buffer to write into.
   */
  private BufferedCdrOutput buffer;

  /**
   * Create a new buffered response handler that uses the given message headers.
   * The headers are used to compute sizes and check the versions. They are not
   * written into a stream inside this class.
   *
   * @param m_header a message header.
   * @param r_header a reply header.
   */
  ResponseHandlerImpl(ORB an_orb, MessageHeader m_header,
                          ReplyHeader r_header, RequestHeader rq_header)
  {
    message_header = m_header;
    reply_header = r_header;
    request_header = rq_header;
    orb = an_orb;
    prepareStream();
  }

  /**
   * Get an output stream for providing details about the exception. Before
   * returning the stream, the handler automatically writes the message header
   * and the reply about exception header, but not the message header.
   *
   * @return the stream to write exception details into.
   */
  public OutputStream createExceptionReply()
  {
    exceptionReply = true;
    prepareStream();
    return buffer;
  }

  /**
   * Get an output stream for writing a regular reply (not an exception).
   *
   * Before returning the stream, the handler automatically writes the regular
   * reply header, but not the message header.
   *
   * @return the output stream for writing a regular reply.
   */
  public OutputStream createReply()
  {
    exceptionReply = false;
    prepareStream();
    reply_header.reply_status = ReplyHeader.NO_EXCEPTION;
    return buffer;
  }

  /**
   * Get the buffer, normally containing the written reply. The reply includes
   * the reply header (or the exception header) but does not include the message
   * header.
   *
   * The stream buffer can also be empty if no data have been written into
   * streams, returned by {@link #createReply()} or
   * {@link #createExceptionReply()}.
   *
   * @return the CDR output stream, containing the written output.
   */
  public BufferedCdrOutput getBuffer()
  {
    return buffer;
  }

  /**
   * True if the stream was obtained by invoking {@link #createExceptionReply()},
   * false otherwise (usually no-exception reply).
   */
  public boolean isExceptionReply()
  {
    return exceptionReply;
  }

  /**
   * Compute the header offset, set the correct version number and codeset.
   */
  private void prepareStream()
  {
    buffer = new BufferedCdrOutput();
    buffer.setOrb(orb);
    buffer.setVersion(message_header.version);
    buffer.setCodeSet(CodeSetServiceContext.find(reply_header.service_context));

    // Since 1.2, the data section is always aligned on the 8 byte boundary.
    // In older versions, it is necessary to set the offset correctly.
    if (message_header.version.until_inclusive(1, 1))
      {
        buffer.setOffset(message_header.getHeaderSize());

        // Get the position after the reply header would be written.
        reply_header.write(buffer);

        int new_offset = message_header.getHeaderSize() + buffer.buffer.size();

        buffer.buffer.reset();
        buffer.setOffset(new_offset);
      }
  }
}
