CDRInputObject.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.corba.se.impl.encoding;
27
28import java.nio.ByteBuffer;
29
30import com.sun.org.omg.SendingContext.CodeBase;
31
32import com.sun.corba.se.pept.encoding.InputObject;
33
34import com.sun.corba.se.spi.logging.CORBALogDomains;
35
36import com.sun.corba.se.spi.orb.ORB;
37
38import com.sun.corba.se.spi.transport.CorbaConnection;
39
40import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
41
42import com.sun.corba.se.impl.encoding.BufferManagerFactory;
43import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
44import com.sun.corba.se.impl.encoding.CodeSetConversion;
45import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
46import com.sun.corba.se.impl.encoding.CDRInputStream;
47
48import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
49
50import com.sun.corba.se.impl.logging.ORBUtilSystemException;
51import com.sun.corba.se.impl.logging.OMGSystemException;
52
53import com.sun.corba.se.impl.orbutil.ORBUtility;
54
55/**
56 * @author Harold Carr
57 */
58public class CDRInputObject extends CDRInputStream
59    implements
60        InputObject
61{
62    private CorbaConnection corbaConnection;
63    private Message header;
64    private boolean unmarshaledHeader;
65    private ORB orb ;
66    private ORBUtilSystemException wrapper ;
67    private OMGSystemException omgWrapper ;
68
69    public CDRInputObject(ORB orb,
70                          CorbaConnection corbaConnection,
71                          ByteBuffer byteBuffer,
72                          Message header)
73    {
74        super(orb, byteBuffer, header.getSize(), header.isLittleEndian(),
75              header.getGIOPVersion(), header.getEncodingVersion(),
76              BufferManagerFactory.newBufferManagerRead(
77                                          header.getGIOPVersion(),
78                                          header.getEncodingVersion(),
79                                          orb));
80
81        this.corbaConnection = corbaConnection;
82        this.orb = orb ;
83        this.wrapper = ORBUtilSystemException.get( orb,
84            CORBALogDomains.RPC_ENCODING ) ;
85        this.omgWrapper = OMGSystemException.get( orb,
86            CORBALogDomains.RPC_ENCODING ) ;
87
88        if (orb.transportDebugFlag) {
89            dprint(".CDRInputObject constructor:");
90        }
91
92        getBufferManager().init(header);
93
94        this.header = header;
95
96        unmarshaledHeader = false;
97
98        setIndex(Message.GIOPMessageHeaderLength);
99
100        setBufferLength(header.getSize());
101    }
102
103    // REVISIT - think about this some more.
104    // This connection normally is accessed from the message mediator.
105    // However, giop input needs to get code set info from the connetion
106    // *before* the message mediator is available.
107    public final CorbaConnection getConnection()
108    {
109        return corbaConnection;
110    }
111
112    // XREVISIT - Should the header be kept in the stream or the
113    // message mediator?  Or should we not have a header and
114    // have the information stored in the message mediator
115    // directly?
116    public Message getMessageHeader()
117    {
118        return header;
119    }
120
121    /**
122     * Unmarshal the extended GIOP header
123     * NOTE: May be fragmented, so should not be called by the ReaderThread.
124     * See CorbaResponseWaitingRoomImpl.waitForResponse.  It is done
125     * there in the client thread.
126     */
127    public void unmarshalHeader()
128    {
129        // Unmarshal the extended GIOP message from the buffer.
130
131        if (!unmarshaledHeader) {
132            try {
133                if (((ORB)orb()).transportDebugFlag) {
134                    dprint(".unmarshalHeader->: " + getMessageHeader());
135                }
136                getMessageHeader().read(this);
137                unmarshaledHeader= true;
138            } catch (RuntimeException e) {
139                if (((ORB)orb()).transportDebugFlag) {
140                    dprint(".unmarshalHeader: !!ERROR!!: "
141                           + getMessageHeader()
142                           + ": " + e);
143                }
144                throw e;
145            } finally {
146                if (((ORB)orb()).transportDebugFlag) {
147                    dprint(".unmarshalHeader<-: " + getMessageHeader());
148                }
149            }
150        }
151    }
152
153    public final boolean unmarshaledHeader()
154    {
155        return unmarshaledHeader;
156    }
157
158    /**
159     * Override the default CDR factory behavior to get the
160     * negotiated code sets from the connection.
161     *
162     * These are only called once per message, the first time needed.
163     *
164     * In the local case, there is no Connection, so use the
165     * local code sets.
166     */
167    protected CodeSetConversion.BTCConverter createCharBTCConverter() {
168        CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
169
170        // If the connection doesn't have its negotiated
171        // code sets by now, fall back on the defaults defined
172        // in CDRInputStream.
173        if (codesets == null)
174            return super.createCharBTCConverter();
175
176        OSFCodeSetRegistry.Entry charSet
177            = OSFCodeSetRegistry.lookupEntry(codesets.getCharCodeSet());
178
179        if (charSet == null)
180            throw wrapper.unknownCodeset( charSet ) ;
181
182        return CodeSetConversion.impl().getBTCConverter(charSet, isLittleEndian());
183    }
184
185    protected CodeSetConversion.BTCConverter createWCharBTCConverter() {
186
187        CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
188
189        // If the connection doesn't have its negotiated
190        // code sets by now, we have to throw an exception.
191        // See CORBA formal 00-11-03 13.9.2.6.
192        if (codesets == null) {
193            if (getConnection().isServer())
194                throw omgWrapper.noClientWcharCodesetCtx() ;
195            else
196                throw omgWrapper.noServerWcharCodesetCmp() ;
197        }
198
199        OSFCodeSetRegistry.Entry wcharSet
200            = OSFCodeSetRegistry.lookupEntry(codesets.getWCharCodeSet());
201
202        if (wcharSet == null)
203            throw wrapper.unknownCodeset( wcharSet ) ;
204
205        // For GIOP 1.2 and UTF-16, use big endian if there is no byte
206        // order marker.  (See issue 3405b)
207        //
208        // For GIOP 1.1 and UTF-16, use the byte order the stream if
209        // there isn't (and there shouldn't be) a byte order marker.
210        //
211        // GIOP 1.0 doesn't have wchars.  If we're talking to a legacy ORB,
212        // we do what our old ORBs did.
213        if (wcharSet == OSFCodeSetRegistry.UTF_16) {
214            if (getGIOPVersion().equals(GIOPVersion.V1_2))
215                return CodeSetConversion.impl().getBTCConverter(wcharSet, false);
216        }
217
218        return CodeSetConversion.impl().getBTCConverter(wcharSet, isLittleEndian());
219    }
220
221    // If we're local and don't have a Connection, use the
222    // local code sets, otherwise get them from the connection.
223    // If the connection doesn't have negotiated code sets
224    // yet, then we use ISO8859-1 for char/string and wchar/wstring
225    // are illegal.
226    private CodeSetComponentInfo.CodeSetContext getCodeSets() {
227        if (getConnection() == null)
228            return CodeSetComponentInfo.LOCAL_CODE_SETS;
229        else
230            return getConnection().getCodeSetContext();
231    }
232
233    public final CodeBase getCodeBase() {
234        if (getConnection() == null)
235            return null;
236        else
237            return getConnection().getCodeBase();
238    }
239
240    // -----------------------------------------------------------
241    // Below this point are commented out methods with features
242    // from the old stream.  We must find ways to address
243    // these issues in the future.
244    // -----------------------------------------------------------
245
246    // XREVISIT
247//     private XIIOPInputStream(XIIOPInputStream stream) {
248//         super(stream);
249
250//         this.conn = stream.conn;
251//         this.msg = stream.msg;
252//         this.unmarshaledHeader = stream.unmarshaledHeader;
253//     }
254
255    public CDRInputStream dup() {
256        // XREVISIT
257        return null;
258        // return new XIIOPInputStream(this);
259    }
260
261    protected void dprint(String msg)
262    {
263        ORBUtility.dprint("CDRInputObject", msg);
264    }
265}
266
267// End of file.
268