/*
* Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.corba.se.impl.encoding;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.omg.CORBA.Any;
import org.omg.CORBA.Principal;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.portable.InputStream;
import com.sun.corba.se.pept.encoding.OutputObject;
import com.sun.corba.se.pept.protocol.MessageMediator;
import com.sun.corba.se.spi.encoding.CorbaOutputObject ;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
import com.sun.corba.se.pept.transport.ByteBufferPool;
import com.sun.corba.se.spi.transport.CorbaConnection;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.spi.servicecontext.ServiceContexts;
import com.sun.corba.se.impl.encoding.BufferManagerFactory;
import com.sun.corba.se.impl.encoding.ByteBufferWithInfo;
import com.sun.corba.se.impl.encoding.CDROutputStream;
import com.sun.corba.se.impl.encoding.CDROutputStream_1_0;
import com.sun.corba.se.impl.encoding.CodeSetConversion;
import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
Author: Harold Carr
/**
* @author Harold Carr
*/
public class CDROutputObject extends CorbaOutputObject
{
private Message header;
private ORB orb;
private ORBUtilSystemException wrapper;
private OMGSystemException omgWrapper;
// REVISIT - only used on sendCancelRequest.
private CorbaConnection connection;
private CDROutputObject(
ORB orb, GIOPVersion giopVersion, Message header,
BufferManagerWrite manager, byte streamFormatVersion,
CorbaMessageMediator mediator)
{
super(orb, giopVersion, header.getEncodingVersion(),
false, manager, streamFormatVersion,
((mediator != null && mediator.getConnection() != null) ?
((CorbaConnection)mediator.getConnection()).
shouldUseDirectByteBuffers() : false));
this.header = header;
this.orb = orb;
this.wrapper = ORBUtilSystemException.get( orb, CORBALogDomains.RPC_ENCODING ) ;
this.omgWrapper = OMGSystemException.get( orb, CORBALogDomains.RPC_ENCODING ) ;
getBufferManager().setOutputObject(this);
this.corbaMessageMediator = mediator;
}
public CDROutputObject(ORB orb,
MessageMediator messageMediator,
Message header,
byte streamFormatVersion)
{
this(
orb,
((CorbaMessageMediator)messageMediator).getGIOPVersion(),
header,
BufferManagerFactory.newBufferManagerWrite(
((CorbaMessageMediator)messageMediator).getGIOPVersion(),
header.getEncodingVersion(),
orb),
streamFormatVersion,
(CorbaMessageMediator)messageMediator);
}
// NOTE:
// Used in SharedCDR (i.e., must be grow).
// Used in msgtypes test.
public CDROutputObject(ORB orb,
MessageMediator messageMediator,
Message header,
byte streamFormatVersion,
int strategy)
{
this(
orb,
((CorbaMessageMediator)messageMediator).getGIOPVersion(),
header,
BufferManagerFactory.
newBufferManagerWrite(strategy,
header.getEncodingVersion(),
orb),
streamFormatVersion,
(CorbaMessageMediator)messageMediator);
}
// REVISIT
// Used on sendCancelRequest.
// Used for needs addressing mode.
public CDROutputObject(ORB orb, CorbaMessageMediator mediator,
GIOPVersion giopVersion,
CorbaConnection connection, Message header,
byte streamFormatVersion)
{
this(
orb,
giopVersion,
header,
BufferManagerFactory.
newBufferManagerWrite(giopVersion,
header.getEncodingVersion(),
orb),
streamFormatVersion,
mediator);
this.connection = connection ;
}
// XREVISIT
// Header should only be in message mediator.
// Another possibility: merge header and message mediator.
// REVISIT - make protected once all encoding together
public Message getMessageHeader() {
return header;
}
public final void finishSendingMessage() {
getBufferManager().sendMessage();
}
Write the contents of the CDROutputStream to the specified
output stream. Has the side-effect of pushing any current
Message onto the Message list.
Params: - connection – The output stream to write to.
/**
* Write the contents of the CDROutputStream to the specified
* output stream. Has the side-effect of pushing any current
* Message onto the Message list.
* @param connection The output stream to write to.
*/
public void writeTo(CorbaConnection connection)
throws java.io.IOException
{
//
// Update the GIOP MessageHeader size field.
//
ByteBufferWithInfo bbwi = getByteBufferWithInfo();
getMessageHeader().setSize(bbwi.byteBuffer, bbwi.getSize());
if (orb() != null) {
if (((ORB)orb()).transportDebugFlag) {
dprint(".writeTo: " + connection);
}
if (((ORB)orb()).giopDebugFlag) {
CDROutputStream_1_0.printBuffer(bbwi);
}
}
bbwi.byteBuffer.position(0).limit(bbwi.getSize());
connection.write(bbwi.byteBuffer);
}
overrides create_input_stream from CDROutputStream /** overrides create_input_stream from CDROutputStream */
public org.omg.CORBA.portable.InputStream create_input_stream()
{
// XREVISIT
return null;
//return new XIIOPInputStream(orb(), getByteBuffer(), getIndex(),
//isLittleEndian(), getMessageHeader(), conn);
}
public CorbaConnection getConnection()
{
// REVISIT - only set when doing sendCancelRequest.
if (connection != null) {
return connection;
}
return (CorbaConnection) corbaMessageMediator.getConnection();
}
// XREVISIT - If CDROutputObject doesn't live in the iiop
// package, it will need this, here, to give package access
// to xgiop.
// REVISIT - make protected once all encoding together
public final ByteBufferWithInfo getByteBufferWithInfo() {
return super.getByteBufferWithInfo();
}
// REVISIT - make protected once all encoding together
public final void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
super.setByteBufferWithInfo(bbwi);
}
Override the default CDR factory behavior to get the
negotiated code sets from the connection.
These are only called once per message, the first time needed.
In the local case, there is no Connection, so use the
local code sets.
/**
* Override the default CDR factory behavior to get the
* negotiated code sets from the connection.
*
* These are only called once per message, the first time needed.
*
* In the local case, there is no Connection, so use the
* local code sets.
*/
protected CodeSetConversion.CTBConverter createCharCTBConverter() {
CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
// If the connection doesn't have its negotiated
// code sets by now, fall back on the defaults defined
// in CDRInputStream.
if (codesets == null)
return super.createCharCTBConverter();
OSFCodeSetRegistry.Entry charSet
= OSFCodeSetRegistry.lookupEntry(codesets.getCharCodeSet());
if (charSet == null)
throw wrapper.unknownCodeset( charSet ) ;
return CodeSetConversion.impl().getCTBConverter(charSet,
isLittleEndian(),
false);
}
protected CodeSetConversion.CTBConverter createWCharCTBConverter() {
CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
// If the connection doesn't have its negotiated
// code sets by now, we have to throw an exception.
// See CORBA formal 00-11-03 13.9.2.6.
if (codesets == null) {
if (getConnection().isServer())
throw omgWrapper.noClientWcharCodesetCtx() ;
else
throw omgWrapper.noServerWcharCodesetCmp() ;
}
OSFCodeSetRegistry.Entry wcharSet
= OSFCodeSetRegistry.lookupEntry(codesets.getWCharCodeSet());
if (wcharSet == null)
throw wrapper.unknownCodeset( wcharSet ) ;
boolean useByteOrderMarkers
= ((ORB)orb()).getORBData().useByteOrderMarkers();
// With UTF-16:
//
// For GIOP 1.2, we can put byte order markers if we want to, and
// use the default of big endian otherwise. (See issue 3405b)
//
// For GIOP 1.1, we don't use BOMs and use the endianness of
// the stream.
if (wcharSet == OSFCodeSetRegistry.UTF_16) {
if (getGIOPVersion().equals(GIOPVersion.V1_2)) {
return CodeSetConversion.impl().getCTBConverter(wcharSet,
false,
useByteOrderMarkers);
}
if (getGIOPVersion().equals(GIOPVersion.V1_1)) {
return CodeSetConversion.impl().getCTBConverter(wcharSet,
isLittleEndian(),
false);
}
}
// In the normal case, let the converter system handle it
return CodeSetConversion.impl().getCTBConverter(wcharSet,
isLittleEndian(),
useByteOrderMarkers);
}
// If we're local and don't have a Connection, use the
// local code sets, otherwise get them from the connection.
// If the connection doesn't have negotiated code sets
// yet, then we use ISO8859-1 for char/string and wchar/wstring
// are illegal.
private CodeSetComponentInfo.CodeSetContext getCodeSets() {
if (getConnection() == null)
return CodeSetComponentInfo.LOCAL_CODE_SETS;
else
return getConnection().getCodeSetContext();
}
protected void dprint(String msg)
{
ORBUtility.dprint("CDROutputObject", msg);
}
}
// End of file.