blob: 039484b04643188304c37a6389c8b243be36cfb8 [file] [log] [blame]
/*
* 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.nio.ByteBuffer;
import com.sun.org.omg.SendingContext.CodeBase;
import com.sun.corba.se.pept.encoding.InputObject;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.transport.CorbaConnection;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.impl.encoding.BufferManagerFactory;
import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
import com.sun.corba.se.impl.encoding.CodeSetConversion;
import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
import com.sun.corba.se.impl.encoding.CDRInputStream;
import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
import com.sun.corba.se.impl.orbutil.ORBUtility;
/**
* @author Harold Carr
*/
public class CDRInputObject extends CDRInputStream
implements
InputObject
{
private CorbaConnection corbaConnection;
private Message header;
private boolean unmarshaledHeader;
private ORB orb ;
private ORBUtilSystemException wrapper ;
private OMGSystemException omgWrapper ;
public CDRInputObject(ORB orb,
CorbaConnection corbaConnection,
ByteBuffer byteBuffer,
Message header)
{
super(orb, byteBuffer, header.getSize(), header.isLittleEndian(),
header.getGIOPVersion(), header.getEncodingVersion(),
BufferManagerFactory.newBufferManagerRead(
header.getGIOPVersion(),
header.getEncodingVersion(),
orb));
this.corbaConnection = corbaConnection;
this.orb = orb ;
this.wrapper = ORBUtilSystemException.get( orb,
CORBALogDomains.RPC_ENCODING ) ;
this.omgWrapper = OMGSystemException.get( orb,
CORBALogDomains.RPC_ENCODING ) ;
if (orb.transportDebugFlag) {
dprint(".CDRInputObject constructor:");
}
getBufferManager().init(header);
this.header = header;
unmarshaledHeader = false;
setIndex(Message.GIOPMessageHeaderLength);
setBufferLength(header.getSize());
}
// REVISIT - think about this some more.
// This connection normally is accessed from the message mediator.
// However, giop input needs to get code set info from the connetion
// *before* the message mediator is available.
public final CorbaConnection getConnection()
{
return corbaConnection;
}
// XREVISIT - Should the header be kept in the stream or the
// message mediator? Or should we not have a header and
// have the information stored in the message mediator
// directly?
public Message getMessageHeader()
{
return header;
}
/**
* Unmarshal the extended GIOP header
* NOTE: May be fragmented, so should not be called by the ReaderThread.
* See CorbaResponseWaitingRoomImpl.waitForResponse. It is done
* there in the client thread.
*/
public void unmarshalHeader()
{
// Unmarshal the extended GIOP message from the buffer.
if (!unmarshaledHeader) {
try {
if (((ORB)orb()).transportDebugFlag) {
dprint(".unmarshalHeader->: " + getMessageHeader());
}
getMessageHeader().read(this);
unmarshaledHeader= true;
} catch (RuntimeException e) {
if (((ORB)orb()).transportDebugFlag) {
dprint(".unmarshalHeader: !!ERROR!!: "
+ getMessageHeader()
+ ": " + e);
}
throw e;
} finally {
if (((ORB)orb()).transportDebugFlag) {
dprint(".unmarshalHeader<-: " + getMessageHeader());
}
}
}
}
public final boolean unmarshaledHeader()
{
return unmarshaledHeader;
}
/**
* 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.BTCConverter createCharBTCConverter() {
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.createCharBTCConverter();
OSFCodeSetRegistry.Entry charSet
= OSFCodeSetRegistry.lookupEntry(codesets.getCharCodeSet());
if (charSet == null)
throw wrapper.unknownCodeset( charSet ) ;
return CodeSetConversion.impl().getBTCConverter(charSet, isLittleEndian());
}
protected CodeSetConversion.BTCConverter createWCharBTCConverter() {
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 ) ;
// For GIOP 1.2 and UTF-16, use big endian if there is no byte
// order marker. (See issue 3405b)
//
// For GIOP 1.1 and UTF-16, use the byte order the stream if
// there isn't (and there shouldn't be) a byte order marker.
//
// GIOP 1.0 doesn't have wchars. If we're talking to a legacy ORB,
// we do what our old ORBs did.
if (wcharSet == OSFCodeSetRegistry.UTF_16) {
if (getGIOPVersion().equals(GIOPVersion.V1_2))
return CodeSetConversion.impl().getBTCConverter(wcharSet, false);
}
return CodeSetConversion.impl().getBTCConverter(wcharSet, isLittleEndian());
}
// 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();
}
public final CodeBase getCodeBase() {
if (getConnection() == null)
return null;
else
return getConnection().getCodeBase();
}
// -----------------------------------------------------------
// Below this point are commented out methods with features
// from the old stream. We must find ways to address
// these issues in the future.
// -----------------------------------------------------------
// XREVISIT
// private XIIOPInputStream(XIIOPInputStream stream) {
// super(stream);
// this.conn = stream.conn;
// this.msg = stream.msg;
// this.unmarshaledHeader = stream.unmarshaledHeader;
// }
public CDRInputStream dup() {
// XREVISIT
return null;
// return new XIIOPInputStream(this);
}
protected void dprint(String msg)
{
ORBUtility.dprint("CDRInputObject", msg);
}
}
// End of file.