blob: 7fb977cb114948841c34b25f95e37fcece9ffe93 [file] [log] [blame]
/*
* Copyright (c) 2000, 2003, 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 org.omg.CORBA.CompletionStatus;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.impl.encoding.CodeSetConversion;
public class CDROutputStream_1_1 extends CDROutputStream_1_0
{
// This is used to keep indirections working across fragments. When added
// to the current bbwi.position(), the result is the current position
// in the byte stream without any fragment headers.
//
// It is equal to the following:
//
// n = number of buffers (0 is original buffer, 1 is first fragment, etc)
//
// n == 0, fragmentOffset = 0
//
// n > 0, fragmentOffset
// = sum i=[1,n] { bbwi_i-1_.size - buffer i header length }
//
protected int fragmentOffset = 0;
protected void alignAndReserve(int align, int n) {
// Notice that in 1.1, we won't end a fragment with
// alignment padding. We also won't guarantee that
// our fragments end on evenly divisible 8 byte
// boundaries. There may be alignment
// necessary with the header of the next fragment
// since the header isn't aligned on an 8 byte
// boundary, so we have to calculate it twice.
int alignment = computeAlignment(align);
if (bbwi.position() + n + alignment > bbwi.buflen) {
grow(align, n);
// Must recompute the alignment after a grow.
// In the case of fragmentation, the alignment
// calculation may no longer be correct.
// People shouldn't be able to set their fragment
// sizes so small that the fragment header plus
// this alignment fills the entire buffer.
alignment = computeAlignment(align);
}
bbwi.position(bbwi.position() + alignment);
}
protected void grow(int align, int n) {
// Save the current size for possible post-fragmentation calculation
int oldSize = bbwi.position();
super.grow(align, n);
// At this point, if we fragmented, we should have a ByteBufferWithInfo
// with the fragment header already marshalled. The size and length fields
// should be updated accordingly, and the fragmented flag should be set.
if (bbwi.fragmented) {
// Clear the flag
bbwi.fragmented = false;
// Update fragmentOffset so indirections work properly.
// At this point, oldSize is the entire length of the
// previous buffer. bbwi.position() is the length of the
// fragment header of this buffer.
fragmentOffset += (oldSize - bbwi.position());
}
}
public int get_offset() {
return bbwi.position() + fragmentOffset;
}
public GIOPVersion getGIOPVersion() {
return GIOPVersion.V1_1;
}
public void write_wchar(char x)
{
// In GIOP 1.1, interoperability with wchar is limited
// to 2 byte fixed width encodings. CORBA formal 99-10-07 15.3.1.6.
// Note that the following code prohibits UTF-16 with a byte
// order marker (which would result in 4 bytes).
CodeSetConversion.CTBConverter converter = getWCharConverter();
converter.convert(x);
if (converter.getNumBytes() != 2)
throw wrapper.badGiop11Ctb(CompletionStatus.COMPLETED_MAYBE);
alignAndReserve(converter.getAlignment(),
converter.getNumBytes());
parent.write_octet_array(converter.getBytes(),
0,
converter.getNumBytes());
}
public void write_wstring(String value)
{
if (value == null) {
throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
}
// The length is the number of code points (which are 2 bytes each)
// including the 2 byte null. See CORBA formal 99-10-07 15.3.2.7.
int len = value.length() + 1;
write_long(len);
CodeSetConversion.CTBConverter converter = getWCharConverter();
converter.convert(value);
internalWriteOctetArray(converter.getBytes(), 0, converter.getNumBytes());
// Write the 2 byte null ending
write_short((short)0);
}
}