Thu, 31 Aug 2017 18:10:36 +0800
merge
1 /*
2 * Copyright (c) 2000, 2013, 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 */
26 package com.sun.corba.se.impl.interceptors;
28 import org.omg.CORBA.Any;
29 import org.omg.CORBA.ORB;
30 import org.omg.CORBA.TypeCode;
31 import org.omg.CORBA.LocalObject;
33 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
34 import com.sun.corba.se.spi.logging.CORBALogDomains;
36 import sun.corba.EncapsInputStreamFactory;
38 import com.sun.corba.se.impl.corba.AnyImpl;
39 import com.sun.corba.se.impl.encoding.EncapsInputStream;
40 import com.sun.corba.se.impl.encoding.EncapsOutputStream;
41 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
43 import org.omg.IOP.Codec;
44 import org.omg.IOP.CodecPackage.FormatMismatch;
45 import org.omg.IOP.CodecPackage.InvalidTypeForEncoding;
46 import org.omg.IOP.CodecPackage.TypeMismatch;
48 /**
49 * CDREncapsCodec is an implementation of Codec, as described
50 * in orbos/99-12-02, that supports CDR encapsulation version 1.0, 1.1, and
51 * 1.2.
52 */
53 public final class CDREncapsCodec
54 extends org.omg.CORBA.LocalObject
55 implements Codec
56 {
57 // The ORB that created the factory this codec was created from
58 private ORB orb;
59 ORBUtilSystemException wrapper;
61 // The GIOP version we are encoding for
62 private GIOPVersion giopVersion;
64 /*
65 *******************************************************************
66 * NOTE: CDREncapsCodec must remain immutable! This is so that we
67 * can pre-create CDREncapsCodecs for each version of GIOP in
68 * CodecFactoryImpl.
69 *******************************************************************/
71 /**
72 * Creates a new codec implementation. Uses the given ORB to create
73 * CDRInputStreams when necessary.
74 *
75 * @param orb The ORB to use to create a CDRInputStream or CDROutputStream
76 * @param major The major version of GIOP we are encoding for
77 * @param minor The minor version of GIOP we are encoding for
78 */
79 public CDREncapsCodec( ORB orb, int major, int minor ) {
80 this.orb = orb;
81 wrapper = ORBUtilSystemException.get(
82 (com.sun.corba.se.spi.orb.ORB)orb, CORBALogDomains.RPC_PROTOCOL ) ;
84 giopVersion = GIOPVersion.getInstance( (byte)major, (byte)minor );
85 }
87 /**
88 * Convert the given any into a CDR encapsulated octet sequence
89 */
90 public byte[] encode( Any data )
91 throws InvalidTypeForEncoding
92 {
93 if ( data == null )
94 throw wrapper.nullParam() ;
95 return encodeImpl( data, true );
96 }
98 /**
99 * Decode the given octet sequence into an any based on a CDR
100 * encapsulated octet sequence.
101 */
102 public Any decode ( byte[] data )
103 throws FormatMismatch
104 {
105 if( data == null )
106 throw wrapper.nullParam() ;
107 return decodeImpl( data, null );
108 }
110 /**
111 * Convert the given any into a CDR encapsulated octet sequence. Only
112 * the data is stored. The type code is not.
113 */
114 public byte[] encode_value( Any data )
115 throws InvalidTypeForEncoding
116 {
117 if( data == null )
118 throw wrapper.nullParam() ;
119 return encodeImpl( data, false );
120 }
122 /**
123 * Decode the given octet sequence into an any based on a CDR
124 * encapsulated octet sequence. The type code is expected not to appear
125 * in the octet sequence, and the given type code is used instead.
126 */
127 public Any decode_value( byte[] data, TypeCode tc )
128 throws FormatMismatch, TypeMismatch
129 {
130 if( data == null )
131 throw wrapper.nullParam() ;
132 if( tc == null )
133 throw wrapper.nullParam() ;
134 return decodeImpl( data, tc );
135 }
137 /**
138 * Convert the given any into a CDR encapsulated octet sequence.
139 * If sendTypeCode is true, the type code is sent with the message, as in
140 * a standard encapsulation. If it is false, only the data is sent.
141 * Either way, the endian type is sent as the first part of the message.
142 */
143 private byte[] encodeImpl( Any data, boolean sendTypeCode )
144 throws InvalidTypeForEncoding
145 {
146 if( data == null )
147 throw wrapper.nullParam() ;
149 // _REVISIT_ Note that InvalidTypeForEncoding is never thrown in
150 // the body of this method. This is due to the fact that CDR*Stream
151 // will never throw an exception if the encoding is invalid. To
152 // fix this, the CDROutputStream must know the version of GIOP it
153 // is encoding for and it must check to ensure that, for example,
154 // wstring cannot be encoded in GIOP 1.0.
155 //
156 // As part of the GIOP 1.2 work, the CDRInput and OutputStream will
157 // be versioned. This can be handled once this work is complete.
159 // Create output stream with default endianness.
160 EncapsOutputStream cdrOut =
161 sun.corba.OutputStreamFactory.newEncapsOutputStream(
162 (com.sun.corba.se.spi.orb.ORB)orb, giopVersion );
164 // This is an encapsulation, so put out the endian:
165 cdrOut.putEndian();
167 // Sometimes encode type code:
168 if( sendTypeCode ) {
169 cdrOut.write_TypeCode( data.type() );
170 }
172 // Encode value and return.
173 data.write_value( cdrOut );
175 return cdrOut.toByteArray();
176 }
178 /**
179 * Decode the given octet sequence into an any based on a CDR
180 * encapsulated octet sequence. If the type code is null, it is
181 * expected to appear in the octet sequence. Otherwise, the given
182 * type code is used.
183 */
184 private Any decodeImpl( byte[] data, TypeCode tc )
185 throws FormatMismatch
186 {
187 if( data == null )
188 throw wrapper.nullParam() ;
190 AnyImpl any = null; // return value
192 // _REVISIT_ Currently there is no way for us to distinguish between
193 // a FormatMismatch and a TypeMismatch because we cannot get this
194 // information from the CDRInputStream. If a RuntimeException occurs,
195 // it is turned into a FormatMismatch exception.
197 try {
198 EncapsInputStream cdrIn = EncapsInputStreamFactory.newEncapsInputStream( orb, data,
199 data.length, giopVersion );
202 cdrIn.consumeEndian();
204 // If type code not specified, read it from octet stream:
205 if( tc == null ) {
206 tc = cdrIn.read_TypeCode();
207 }
209 // Create a new Any object:
210 any = new AnyImpl( (com.sun.corba.se.spi.orb.ORB)orb );
211 any.read_value( cdrIn, tc );
212 }
213 catch( RuntimeException e ) {
214 // See above note.
215 throw new FormatMismatch();
216 }
218 return any;
219 }
220 }