| /* |
| * 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 |
| */ |
| 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. |
| * @param s 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 */ |
| 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. |
| */ |
| 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. |