1 /*
   2  * Copyright (c) 2001, 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  */
  25 
  26 package com.sun.corba.se.impl.encoding;
  27 
  28 import org.omg.CORBA.CompletionStatus;
  29 
  30 import com.sun.corba.se.spi.orb.ORB;
  31 
  32 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  33 
  34 import com.sun.corba.se.impl.encoding.CodeSetConversion;
  35 import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
  36 import com.sun.corba.se.impl.encoding.CDROutputStream;
  37 import com.sun.corba.se.impl.encoding.BufferManagerWrite;
  38 import com.sun.corba.se.impl.encoding.BufferManagerFactory;
  39 import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  40 import com.sun.corba.se.impl.orbutil.ORBConstants;
  41 
  42 import sun.corba.EncapsInputStreamFactory;
  43 
  44 /**
  45  * Encapsulations are supposed to explicitly define their
  46  * code sets and GIOP version.  The original resolution to issue 2784
  47  * said that the defaults were UTF-8 and UTF-16, but that was not
  48  * agreed upon.
  49  *
  50  * These streams currently use CDR 1.2 with ISO8859-1 for char/string and
  51  * UTF16 for wchar/wstring.  If no byte order marker is available,
  52  * the endianness of the encapsulation is used.
  53  *
  54  * When more encapsulations arise that have their own special code
  55  * sets defined, we can make all constructors take such parameters.
  56  */
  57 public class EncapsOutputStream extends CDROutputStream
  58 {
  59 
  60     // REVISIT - Right now, EncapsOutputStream's do not use
  61     // pooled byte buffers. This is controlled by the following
  62     // static constant. This should be re-factored such that
  63     // the EncapsOutputStream doesn't know it's using pooled
  64     // byte buffers.
  65     final static boolean usePooledByteBuffers = false;
  66 
  67     // REVISIT - Right now, valuetypes in encapsulations will
  68     // only use stream format version 1, which may create problems
  69     // for service contexts or codecs (?).
  70 
  71     // corba/ORB
  72     // corba/ORBSingleton
  73     // iiop/ORB
  74     // iiop/GIOPImpl
  75     // corba/AnyImpl
  76     public EncapsOutputStream(ORB orb) {
  77         // GIOP version 1.2 with no fragmentation, big endian,
  78         // UTF8 for char data and UTF-16 for wide char data;
  79         this(orb, GIOPVersion.V1_2);
  80     }
  81 
  82     // CDREncapsCodec
  83     //
  84     // REVISIT.  A UTF-16 encoding with GIOP 1.1 will not work
  85     // with byte order markers.
  86     public EncapsOutputStream(ORB orb, GIOPVersion version) {
  87         this(orb, version, false);
  88     }
  89 
  90     // Used by IIOPProfileTemplate
  91     //
  92     public EncapsOutputStream(ORB orb, boolean isLittleEndian) {
  93         this(orb, GIOPVersion.V1_2, isLittleEndian);
  94     }
  95 
  96     public EncapsOutputStream(ORB orb,
  97                               GIOPVersion version,
  98                               boolean isLittleEndian)
  99     {
 100         super(orb, version, Message.CDR_ENC_VERSION, isLittleEndian,
 101               BufferManagerFactory.newBufferManagerWrite(
 102                                         BufferManagerFactory.GROW,
 103                                         Message.CDR_ENC_VERSION,
 104                                         orb),
 105               ORBConstants.STREAM_FORMAT_VERSION_1,
 106               usePooledByteBuffers);
 107     }
 108 
 109     public org.omg.CORBA.portable.InputStream create_input_stream() {
 110         freeInternalCaches();
 111 
 112         return  EncapsInputStreamFactory.newEncapsInputStream(orb(),
 113                 getByteBuffer(),
 114                 getSize(),
 115                 isLittleEndian(),
 116                 getGIOPVersion());
 117     }
 118 
 119     protected CodeSetConversion.CTBConverter createCharCTBConverter() {
 120         return CodeSetConversion.impl().getCTBConverter(OSFCodeSetRegistry.ISO_8859_1);
 121     }
 122 
 123     protected CodeSetConversion.CTBConverter createWCharCTBConverter() {
 124         if (getGIOPVersion().equals(GIOPVersion.V1_0))
 125             throw wrapper.wcharDataInGiop10(CompletionStatus.COMPLETED_MAYBE);
 126 
 127         // In the case of GIOP 1.1, we take the byte order of the stream and don't
 128         // use byte order markers since we're limited to a 2 byte fixed width encoding.
 129         if (getGIOPVersion().equals(GIOPVersion.V1_1))
 130             return CodeSetConversion.impl().getCTBConverter(OSFCodeSetRegistry.UTF_16,
 131                                                             isLittleEndian(),
 132                                                             false);
 133 
 134         // Assume anything else meets GIOP 1.2 requirements
 135         //
 136         // Use byte order markers?  If not, use big endian in GIOP 1.2.
 137         // (formal 00-11-03 15.3.16)
 138 
 139         boolean useBOM = ((ORB)orb()).getORBData().useByteOrderMarkersInEncapsulations();
 140 
 141         return CodeSetConversion.impl().getCTBConverter(OSFCodeSetRegistry.UTF_16,
 142                                                         false,
 143                                                         useBOM);
 144     }
 145 }