/* * Copyright 2001-2004 Sun Microsystems, Inc. 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. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.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.