1 /*
   2  * Copyright (c) 2000, 2011, 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 package com.sun.corba.se.impl.encoding;
  26 
  27 import java.io.IOException;
  28 import java.io.Serializable;
  29 import java.math.BigDecimal;
  30 import java.nio.ByteBuffer;
  31 
  32 import org.omg.CORBA.TypeCode;
  33 import org.omg.CORBA.Principal;
  34 import org.omg.CORBA.Any;
  35 
  36 import com.sun.corba.se.pept.protocol.MessageMediator;
  37 
  38 import com.sun.corba.se.spi.orb.ORB;
  39 import com.sun.corba.se.spi.logging.CORBALogDomains;
  40 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  41 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
  42 
  43 import com.sun.corba.se.impl.encoding.CodeSetConversion;
  44 import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
  45 import com.sun.corba.se.impl.orbutil.ORBConstants;
  46 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  47 import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  48 
  49 /**
  50  * This is delegates to the real implementation.
  51  */
  52 public abstract class CDROutputStream
  53     extends org.omg.CORBA_2_3.portable.OutputStream
  54     implements com.sun.corba.se.impl.encoding.MarshalOutputStream,
  55                org.omg.CORBA.DataOutputStream, org.omg.CORBA.portable.ValueOutputStream
  56 {
  57     private CDROutputStreamBase impl;
  58     protected ORB orb ;
  59     protected ORBUtilSystemException wrapper ;
  60     protected CorbaMessageMediator corbaMessageMediator;
  61 
  62 
  63     // We can move this out somewhere later.  For now, it serves its purpose
  64     // to create a concrete CDR delegate based on the GIOP version.
  65     private static class OutputStreamFactory {
  66 
  67         public static CDROutputStreamBase newOutputStream(
  68                 ORB orb, GIOPVersion version, byte encodingVersion) {
  69             switch(version.intValue()) {
  70                 case GIOPVersion.VERSION_1_0:
  71                     return new CDROutputStream_1_0();
  72                 case GIOPVersion.VERSION_1_1:
  73                     return new CDROutputStream_1_1();
  74             case GIOPVersion.VERSION_1_2:
  75                 if (encodingVersion != Message.CDR_ENC_VERSION) {
  76                     return
  77                         new IDLJavaSerializationOutputStream(encodingVersion);
  78                 }
  79                 return new CDROutputStream_1_2();
  80             default:
  81                     ORBUtilSystemException wrapper = ORBUtilSystemException.get( orb,
  82                         CORBALogDomains.RPC_ENCODING ) ;
  83                     // REVISIT - what is appropriate?  INTERNAL exceptions
  84                     // are really hard to track later.
  85                     throw wrapper.unsupportedGiopVersion( version ) ;
  86             }
  87         }
  88     }
  89 
  90     // REVISIT - These two constructors should be re-factored to better hide
  91     // the fact that someone extending this class 'can' construct a CDROutputStream
  92     // that does not use pooled ByteBuffers. Right now, only EncapsOutputStream
  93     // does _not_ use pooled ByteBuffers, see EncapsOutputStream.
  94 
  95     // NOTE: When a stream is constructed for non-channel-backed sockets
  96     // it notifies the constructor not to use pooled (i.e, direct)
  97     // ByteBuffers.
  98 
  99     public CDROutputStream(ORB orb,
 100                            GIOPVersion version,
 101                            byte encodingVersion,
 102                            boolean littleEndian,
 103                            BufferManagerWrite bufferManager,
 104                            byte streamFormatVersion,
 105                            boolean usePooledByteBuffers)
 106     {
 107         impl = OutputStreamFactory.newOutputStream(orb, version,
 108                                                    encodingVersion);
 109         impl.init(orb, littleEndian, bufferManager,
 110                   streamFormatVersion, usePooledByteBuffers);
 111 
 112         impl.setParent(this);
 113         this.orb = orb ;
 114         this.wrapper = ORBUtilSystemException.get( orb,
 115             CORBALogDomains.RPC_ENCODING ) ;
 116     }
 117 
 118     public CDROutputStream(ORB orb,
 119                            GIOPVersion version,
 120                            byte encodingVersion,
 121                            boolean littleEndian,
 122                            BufferManagerWrite bufferManager,
 123                            byte streamFormatVersion)
 124     {
 125         this(orb, version, encodingVersion, littleEndian,
 126              bufferManager, streamFormatVersion, true);
 127     }
 128 
 129     // org.omg.CORBA.portable.OutputStream
 130 
 131     // Provided by IIOPOutputStream and EncapsOutputStream
 132     public abstract org.omg.CORBA.portable.InputStream create_input_stream();
 133 
 134     public final void write_boolean(boolean value) {
 135         impl.write_boolean(value);
 136     }
 137     public final void write_char(char value) {
 138         impl.write_char(value);
 139     }
 140     public final void write_wchar(char value) {
 141         impl.write_wchar(value);
 142     }
 143     public final void write_octet(byte value) {
 144         impl.write_octet(value);
 145     }
 146     public final void write_short(short value) {
 147         impl.write_short(value);
 148     }
 149     public final void write_ushort(short value) {
 150         impl.write_ushort(value);
 151     }
 152     public final void write_long(int value) {
 153         impl.write_long(value);
 154     }
 155     public final void write_ulong(int value) {
 156         impl.write_ulong(value);
 157     }
 158     public final void write_longlong(long value) {
 159         impl.write_longlong(value);
 160     }
 161     public final void write_ulonglong(long value) {
 162         impl.write_ulonglong(value);
 163     }
 164     public final void write_float(float value) {
 165         impl.write_float(value);
 166     }
 167     public final void write_double(double value) {
 168         impl.write_double(value);
 169     }
 170     public final void write_string(String value) {
 171         impl.write_string(value);
 172     }
 173     public final void write_wstring(String value) {
 174         impl.write_wstring(value);
 175     }
 176 
 177     public final void write_boolean_array(boolean[] value, int offset, int length) {
 178         impl.write_boolean_array(value, offset, length);
 179     }
 180     public final void write_char_array(char[] value, int offset, int length) {
 181         impl.write_char_array(value, offset, length);
 182     }
 183     public final void write_wchar_array(char[] value, int offset, int length) {
 184         impl.write_wchar_array(value, offset, length);
 185     }
 186     public final void write_octet_array(byte[] value, int offset, int length) {
 187         impl.write_octet_array(value, offset, length);
 188     }
 189     public final void write_short_array(short[] value, int offset, int length) {
 190         impl.write_short_array(value, offset, length);
 191     }
 192     public final void write_ushort_array(short[] value, int offset, int length){
 193         impl.write_ushort_array(value, offset, length);
 194     }
 195     public final void write_long_array(int[] value, int offset, int length) {
 196         impl.write_long_array(value, offset, length);
 197     }
 198     public final void write_ulong_array(int[] value, int offset, int length) {
 199         impl.write_ulong_array(value, offset, length);
 200     }
 201     public final void write_longlong_array(long[] value, int offset, int length) {
 202         impl.write_longlong_array(value, offset, length);
 203     }
 204     public final void write_ulonglong_array(long[] value, int offset,int length) {
 205         impl.write_ulonglong_array(value, offset, length);
 206     }
 207     public final void write_float_array(float[] value, int offset, int length) {
 208         impl.write_float_array(value, offset, length);
 209     }
 210     public final void write_double_array(double[] value, int offset, int length) {
 211         impl.write_double_array(value, offset, length);
 212     }
 213     public final void write_Object(org.omg.CORBA.Object value) {
 214         impl.write_Object(value);
 215     }
 216     public final void write_TypeCode(TypeCode value) {
 217         impl.write_TypeCode(value);
 218     }
 219     public final void write_any(Any value) {
 220         impl.write_any(value);
 221     }
 222 
 223     public final void write_Principal(Principal value) {
 224         impl.write_Principal(value);
 225     }
 226 
 227     public final void write(int b) throws java.io.IOException {
 228         impl.write(b);
 229     }
 230 
 231     public final void write_fixed(java.math.BigDecimal value) {
 232         impl.write_fixed(value);
 233     }
 234 
 235     public final void write_Context(org.omg.CORBA.Context ctx,
 236                               org.omg.CORBA.ContextList contexts) {
 237         impl.write_Context(ctx, contexts);
 238     }
 239 
 240     public final org.omg.CORBA.ORB orb() {
 241         return impl.orb();
 242     }
 243 
 244     // org.omg.CORBA_2_3.portable.OutputStream
 245     public final void write_value(java.io.Serializable value) {
 246         impl.write_value(value);
 247     }
 248 
 249     public final void write_value(java.io.Serializable value, java.lang.Class clz) {
 250         impl.write_value(value, clz);
 251     }
 252 
 253     public final void write_value(java.io.Serializable value, String repository_id) {
 254         impl.write_value(value, repository_id);
 255     }
 256 
 257     public final void write_value(java.io.Serializable value,
 258                             org.omg.CORBA.portable.BoxedValueHelper factory) {
 259         impl.write_value(value, factory);
 260     }
 261 
 262     public final void write_abstract_interface(java.lang.Object obj) {
 263         impl.write_abstract_interface(obj);
 264     }
 265 
 266     // java.io.OutputStream
 267     public final void write(byte b[]) throws IOException {
 268         impl.write(b);
 269     }
 270 
 271     public final void write(byte b[], int off, int len) throws IOException {
 272         impl.write(b, off, len);
 273     }
 274 
 275     public final void flush() throws IOException {
 276         impl.flush();
 277     }
 278 
 279     public final void close() throws IOException {
 280         impl.close();
 281     }
 282 
 283     // com.sun.corba.se.impl.encoding.MarshalOutputStream
 284     public final void start_block() {
 285         impl.start_block();
 286     }
 287 
 288     public final void end_block() {
 289         impl.end_block();
 290     }
 291 
 292     public final void putEndian() {
 293         impl.putEndian();
 294     }
 295 
 296     public void writeTo(java.io.OutputStream s)
 297         throws IOException
 298     {
 299         impl.writeTo(s);
 300     }
 301 
 302     public final byte[] toByteArray() {
 303         return impl.toByteArray();
 304     }
 305 
 306     // org.omg.CORBA.DataOutputStream
 307     public final void write_Abstract (java.lang.Object value) {
 308         impl.write_Abstract(value);
 309     }
 310 
 311     public final void write_Value (java.io.Serializable value) {
 312         impl.write_Value(value);
 313     }
 314 
 315     public final void write_any_array(org.omg.CORBA.Any[] seq, int offset, int length) {
 316         impl.write_any_array(seq, offset, length);
 317     }
 318 
 319     public void setMessageMediator(MessageMediator messageMediator)
 320     {
 321         this.corbaMessageMediator = (CorbaMessageMediator) messageMediator;
 322     }
 323 
 324     public MessageMediator getMessageMediator()
 325     {
 326         return corbaMessageMediator;
 327     }
 328 
 329     // org.omg.CORBA.portable.ValueBase
 330     public final String[] _truncatable_ids() {
 331         return impl._truncatable_ids();
 332     }
 333 
 334     // Other
 335     protected final int getSize() {
 336         return impl.getSize();
 337     }
 338 
 339     protected final int getIndex() {
 340         return impl.getIndex();
 341     }
 342 
 343     protected int getRealIndex(int index) {
 344         // Used in indirections. Overridden by TypeCodeOutputStream.
 345         return index;
 346     }
 347 
 348     protected final void setIndex(int value) {
 349         impl.setIndex(value);
 350     }
 351 
 352     protected final ByteBuffer getByteBuffer() {
 353         return impl.getByteBuffer();
 354     }
 355 
 356     protected final void setByteBuffer(ByteBuffer byteBuffer) {
 357         impl.setByteBuffer(byteBuffer);
 358     }
 359 
 360     /**
 361      * return true if our ByteBuffer is sharing/equal to bb
 362      */
 363     protected final boolean isSharing(ByteBuffer bb) {
 364         return (getByteBuffer() ==  bb);
 365     }
 366 
 367     public final boolean isLittleEndian() {
 368         return impl.isLittleEndian();
 369     }
 370 
 371     // XREVISIT - return to final if possible
 372     // REVISIT - was protected - need access from msgtypes test.
 373     public ByteBufferWithInfo getByteBufferWithInfo() {
 374         return impl.getByteBufferWithInfo();
 375     }
 376 
 377     protected void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
 378         impl.setByteBufferWithInfo(bbwi);
 379     }
 380 
 381     // REVISIT: was protected - but need to access from xgiop.
 382     public final BufferManagerWrite getBufferManager() {
 383         return impl.getBufferManager();
 384     }
 385 
 386     public final void write_fixed(java.math.BigDecimal bigDecimal, short digits, short scale) {
 387         impl.write_fixed(bigDecimal, digits, scale);
 388     }
 389 
 390     public final void writeOctetSequenceTo(org.omg.CORBA.portable.OutputStream s) {
 391         impl.writeOctetSequenceTo(s);
 392     }
 393 
 394     public final GIOPVersion getGIOPVersion() {
 395         return impl.getGIOPVersion();
 396     }
 397 
 398     public final void writeIndirection(int tag, int posIndirectedTo) {
 399         impl.writeIndirection(tag, posIndirectedTo);
 400     }
 401 
 402     // Use Latin-1 for GIOP 1.0 or when code set negotiation was not
 403     // performed.
 404     protected CodeSetConversion.CTBConverter createCharCTBConverter() {
 405         return CodeSetConversion.impl().getCTBConverter(OSFCodeSetRegistry.ISO_8859_1);
 406     }
 407 
 408     // Subclasses must decide what to do here.  It's inconvenient to
 409     // make the class and this method abstract because of dup().
 410     protected abstract CodeSetConversion.CTBConverter createWCharCTBConverter();
 411 
 412     protected final void freeInternalCaches() {
 413         impl.freeInternalCaches();
 414     }
 415 
 416     void printBuffer() {
 417         impl.printBuffer();
 418     }
 419 
 420     public void alignOnBoundary(int octetBoundary) {
 421         impl.alignOnBoundary(octetBoundary);
 422     }
 423 
 424     // Needed by request and reply messages for GIOP versions >= 1.2 only.
 425     public void setHeaderPadding(boolean headerPadding) {
 426         impl.setHeaderPadding(headerPadding);
 427     }
 428 
 429     // ValueOutputStream -----------------------------
 430 
 431     public void start_value(String rep_id) {
 432         impl.start_value(rep_id);
 433     }
 434 
 435     public void end_value() {
 436         impl.end_value();
 437     }
 438 }