alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (CDROutputStream_1_0.java)

This example Java source code file (CDROutputStream_1_0.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

buffermanagerwrite, bytebuffer, bytebufferpool, bytebufferwithinfo, cachetable, cdroutputstream_1_0, class, corba, custommarshal, ior, nio, reflection, rmi, security, string, stringbuffer, typecodeimpl, util, valuehandlermultiformat, valuehelper

The CDROutputStream_1_0.java Java example source code

/*
 * Copyright (c) 1997, 2012, 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.
 */
/*
 * Licensed Materials - Property of IBM
 * RMI-IIOP v1.0
 * Copyright IBM Corp. 1998 1999  All Rights Reserved
 *
 */

package com.sun.corba.se.impl.encoding;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.rmi.Remote;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.util.Hashtable;
import java.util.Stack;

import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;
import javax.rmi.CORBA.ValueHandlerMultiFormat;

import org.omg.CORBA.CustomMarshal;
import org.omg.CORBA.DataOutputStream;
import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.Object;
import org.omg.CORBA.Principal;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.Any;
import org.omg.CORBA.VM_CUSTOM;
import org.omg.CORBA.VM_TRUNCATABLE;
import org.omg.CORBA.VM_NONE;
import org.omg.CORBA.portable.IDLEntity;
import org.omg.CORBA.portable.CustomValue;
import org.omg.CORBA.portable.StreamableValue;
import org.omg.CORBA.portable.BoxedValueHelper;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ValueBase;

import com.sun.org.omg.CORBA.portable.ValueHelper;

import com.sun.corba.se.pept.protocol.MessageMediator;
import com.sun.corba.se.pept.transport.ByteBufferPool;

import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.spi.ior.IORFactories;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.orb.ORBVersionFactory;
import com.sun.corba.se.spi.orb.ORBVersion;
import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
import com.sun.corba.se.spi.logging.CORBALogDomains;

import com.sun.corba.se.impl.encoding.ByteBufferWithInfo;
import com.sun.corba.se.impl.encoding.MarshalOutputStream;
import com.sun.corba.se.impl.encoding.CodeSetConversion;
import com.sun.corba.se.impl.corba.TypeCodeImpl;
import com.sun.corba.se.impl.orbutil.CacheTable;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.RepositoryIdStrings;
import com.sun.corba.se.impl.orbutil.RepositoryIdUtility;
import com.sun.corba.se.impl.orbutil.RepositoryIdFactory;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;

public class CDROutputStream_1_0 extends CDROutputStreamBase
{
    private static final int INDIRECTION_TAG = 0xffffffff;

    protected boolean littleEndian;
    protected BufferManagerWrite bufferManagerWrite;
    ByteBufferWithInfo bbwi;

    protected ORB orb;
    protected ORBUtilSystemException wrapper ;

    protected boolean debug = false;

    protected int blockSizeIndex = -1;
    protected int blockSizePosition = 0;

    protected byte streamFormatVersion;

    private static final int DEFAULT_BUFFER_SIZE = 1024;
    private static final String kWriteMethod = "write";

    // Codebase cache
    private CacheTable codebaseCache = null;

    // Value cache
    private CacheTable valueCache = null;

    // Repository ID cache
    private CacheTable repositoryIdCache = null;

    // Write end flag
    private int end_flag = 0;

    // Beginning with the resolution to interop issue 3526,
    // only enclosing chunked valuetypes are taken into account
    // when computing the nesting level.  However, we still need
    // the old computation around for interoperability with our
    // older ORBs.
    private int chunkedValueNestingLevel = 0;

    private boolean mustChunk = false;

    // In block marker
    protected boolean inBlock = false;

    // Last end tag position
    private int end_flag_position = 0;
    private int end_flag_index = 0;

    // ValueHandler
    private ValueHandler valueHandler = null;

    // Repository ID handlers
    private RepositoryIdUtility repIdUtil;
    private RepositoryIdStrings repIdStrs;

    // Code set converters (created when first needed)
    private CodeSetConversion.CTBConverter charConverter;
    private CodeSetConversion.CTBConverter wcharConverter;

    // REVISIT - This should be re-factored so that including whether
    // to use pool byte buffers or not doesn't need to be known.
    public void init(org.omg.CORBA.ORB orb,
                        boolean littleEndian,
                        BufferManagerWrite bufferManager,
                        byte streamFormatVersion,
                        boolean usePooledByteBuffers)
    {
        // ORB must not be null.  See CDROutputStream constructor.
        this.orb = (ORB)orb;
        this.wrapper = ORBUtilSystemException.get( this.orb,
            CORBALogDomains.RPC_ENCODING ) ;
        debug = this.orb.transportDebugFlag;

        this.littleEndian = littleEndian;
        this.bufferManagerWrite = bufferManager;
        this.bbwi = new ByteBufferWithInfo(orb, bufferManager, usePooledByteBuffers);
        this.streamFormatVersion = streamFormatVersion;

        createRepositoryIdHandlers();
    }

    public void init(org.omg.CORBA.ORB orb,
                        boolean littleEndian,
                        BufferManagerWrite bufferManager,
                        byte streamFormatVersion)
   {
       init(orb, littleEndian, bufferManager, streamFormatVersion, true);
   }

    private final void createRepositoryIdHandlers()
    {
        repIdUtil = RepositoryIdFactory.getRepIdUtility();
        repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
    }

    public BufferManagerWrite getBufferManager()
    {
        return bufferManagerWrite;
    }

    public byte[] toByteArray() {
        byte[] it;

        it = new byte[bbwi.position()];

        // Micro-benchmarks show ByteBuffer.get(int) out perform the bulk
        // ByteBuffer.get(byte[], offset, length).
        for (int i = 0; i < bbwi.position(); i++)
            it[i] = bbwi.byteBuffer.get(i);

        return it;
    }

    public GIOPVersion getGIOPVersion() {
        return GIOPVersion.V1_0;
    }

    // Called by Request and Reply message. Valid for GIOP versions >= 1.2 only.
    // Illegal for GIOP versions < 1.2.
    void setHeaderPadding(boolean headerPadding) {
        throw wrapper.giopVersionError();
    }

    protected void handleSpecialChunkBegin(int requiredSize)
    {
        // No-op for GIOP 1.0
    }

    protected void handleSpecialChunkEnd()
    {
        // No-op for GIOP 1.0
    }

    protected final int computeAlignment(int align) {
        if (align > 1) {
            int incr = bbwi.position() & (align - 1);
            if (incr != 0)
                return align - incr;
        }

        return 0;
    }

    protected void alignAndReserve(int align, int n) {

        bbwi.position(bbwi.position() + computeAlignment(align));

        if (bbwi.position() + n  > bbwi.buflen)
            grow(align, n);
    }

    //
    // Default implementation of grow.  Subclassers may override this.
    // Always grow the single buffer. This needs to delegate
    // fragmentation policy for IIOP 1.1.
    //
    protected void grow(int align, int n)
    {
        bbwi.needed = n;

        bufferManagerWrite.overflow(bbwi);
    }

    public final void putEndian() throws SystemException {
        write_boolean(littleEndian);
    }

    public final boolean littleEndian() {
        return littleEndian;
    }

    void freeInternalCaches() {
        if (codebaseCache != null)
            codebaseCache.done();

        if (valueCache != null)
            valueCache.done();

        if (repositoryIdCache != null)
            repositoryIdCache.done();
    }

    // No such type in java
    public final void write_longdouble(double x)
    {
        throw wrapper.longDoubleNotImplemented(
            CompletionStatus.COMPLETED_MAYBE ) ;
    }

    public void write_octet(byte x)
    {
        // The 'if' stmt is commented out since we need the alignAndReserve to
        // be called, particularly when the first body byte is written,
        // to induce header padding to align the body on a 8-octet boundary,
        // for GIOP versions 1.2 and above. Refer to internalWriteOctetArray()
        // method that also has a similar change.
        //if (bbwi.position() + 1 > bbwi.buflen)
            alignAndReserve(1, 1);

//      REVISIT - Should just use ByteBuffer.put(byte) and let it
//                increment the ByteBuffer position. This is true
//                for all write operations in this file.

        bbwi.byteBuffer.put(bbwi.position(), x);
        bbwi.position(bbwi.position() + 1);

    }

    public final void write_boolean(boolean x)
    {
        write_octet(x? (byte)1:(byte)0);
    }

    public void write_char(char x)
    {
        CodeSetConversion.CTBConverter converter = getCharConverter();

        converter.convert(x);

        // CORBA formal 99-10-07 15.3.1.6: "In the case of multi-byte encodings
        // of characters, a single instance of the char type may only
        // hold one octet of any multi-byte character encoding."
        if (converter.getNumBytes() > 1)
            throw wrapper.invalidSingleCharCtb(CompletionStatus.COMPLETED_MAYBE);

        write_octet(converter.getBytes()[0]);
    }

    // These wchar methods are only used when talking to
    // legacy ORBs, now.
    private final void writeLittleEndianWchar(char x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)(x & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)((x >>> 8) & 0xFF));
        bbwi.position(bbwi.position() + 2);
    }

    private final void writeBigEndianWchar(char x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)((x >>> 8) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)(x & 0xFF));
        bbwi.position(bbwi.position() + 2);
    }

    private final void writeLittleEndianShort(short x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)(x & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)((x >>> 8) & 0xFF));
        bbwi.position(bbwi.position() + 2);
    }

    private final void writeBigEndianShort(short x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)((x >>> 8) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)(x & 0xFF));
        bbwi.position(bbwi.position() + 2);
    }

    private final void writeLittleEndianLong(int x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)(x & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)((x >>> 8) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 2, (byte)((x >>> 16) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 3, (byte)((x >>> 24) & 0xFF));
        bbwi.position(bbwi.position() + 4);
    }

    private final void writeBigEndianLong(int x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)((x >>> 24) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)((x >>> 16) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 2, (byte)((x >>> 8) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 3, (byte)(x & 0xFF));
        bbwi.position(bbwi.position() + 4);
    }

    private final void writeLittleEndianLongLong(long x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)(x & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)((x >>> 8) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 2, (byte)((x >>> 16) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 3, (byte)((x >>> 24) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 4, (byte)((x >>> 32) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 5, (byte)((x >>> 40) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 6, (byte)((x >>> 48) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 7, (byte)((x >>> 56) & 0xFF));
        bbwi.position(bbwi.position() + 8);
    }

    private final void writeBigEndianLongLong(long x) {
        bbwi.byteBuffer.put(bbwi.position(), (byte)((x >>> 56) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 1, (byte)((x >>> 48) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 2, (byte)((x >>> 40) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 3, (byte)((x >>> 32) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 4, (byte)((x >>> 24) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 5, (byte)((x >>> 16) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 6, (byte)((x >>> 8) & 0xFF));
        bbwi.byteBuffer.put(bbwi.position() + 7, (byte)(x & 0xFF));
        bbwi.position(bbwi.position() + 8);
    }

    public void write_wchar(char x)
    {
        // Don't allow transmission of wchar/wstring data with
        // foreign ORBs since it's against the spec.
        if (ORBUtility.isForeignORB(orb)) {
            throw wrapper.wcharDataInGiop10(CompletionStatus.COMPLETED_MAYBE);
        }

        // If it's one of our legacy ORBs, do what they did:
        alignAndReserve(2, 2);

        if (littleEndian) {
            writeLittleEndianWchar(x);
        } else {
            writeBigEndianWchar(x);
        }
    }

    public void write_short(short x)
    {
        alignAndReserve(2, 2);

        if (littleEndian) {
            writeLittleEndianShort(x);
        } else {
            writeBigEndianShort(x);
        }
    }

    public final void write_ushort(short x)
    {
        write_short(x);
    }

    public void write_long(int x)
    {
        alignAndReserve(4, 4);

        if (littleEndian) {
            writeLittleEndianLong(x);
        } else {
            writeBigEndianLong(x);
        }
    }

    public final void write_ulong(int x)
    {
        write_long(x);
    }

    public void write_longlong(long x)
    {
        alignAndReserve(8, 8);

        if (littleEndian) {
            writeLittleEndianLongLong(x);
        } else {
            writeBigEndianLongLong(x);
        }
    }

    public final void write_ulonglong(long x)
    {
        write_longlong(x);
    }

    public final void write_float(float x)
    {
        write_long(Float.floatToIntBits(x));
    }

    public final void write_double(double x)
    {
        write_longlong(Double.doubleToLongBits(x));
    }

    public void write_string(String value)
    {
      writeString(value);
    }

    protected int writeString(String value)
    {
        if (value == null) {
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
        }

        CodeSetConversion.CTBConverter converter = getCharConverter();

        converter.convert(value);

        // A string is encoded as an unsigned CORBA long for the
        // number of bytes to follow (including a terminating null).
        // There is only one octet per character in the string.
        int len = converter.getNumBytes() + 1;

        handleSpecialChunkBegin(computeAlignment(4) + 4 + len);

        write_long(len);
        int indirection = get_offset() - 4;

        internalWriteOctetArray(converter.getBytes(), 0, converter.getNumBytes());

        // Write the null ending
        write_octet((byte)0);

        handleSpecialChunkEnd();
        return indirection;
    }

    public void write_wstring(String value)
    {
        if (value == null)
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // Don't allow transmission of wchar/wstring data with
        // foreign ORBs since it's against the spec.
        if (ORBUtility.isForeignORB(orb)) {
            throw wrapper.wcharDataInGiop10(CompletionStatus.COMPLETED_MAYBE);
        }

        // When talking to our legacy ORBs, do what they did:
        int len = value.length() + 1;

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(4 + (len * 2) + computeAlignment(4));

        write_long(len);

        for (int i = 0; i < len - 1; i++)
            write_wchar(value.charAt(i));

        // Write the null ending
        write_short((short)0);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    // Performs no checks and doesn't tamper with chunking
    void internalWriteOctetArray(byte[] value, int offset, int length)
    {
        int n = offset;

        // This flag forces the alignAndReserve method to be called the
        // first time an octet is written. This is necessary to ensure
        // that the body is aligned on an 8-octet boundary. Note the 'if'
        // condition inside the 'while' loop below. Also, refer to the
        // write_octet() method that has a similar change.
        boolean align = true;

        while (n < length+offset) {
            int avail;
            int bytes;
            int wanted;

            if ((bbwi.position() + 1 > bbwi.buflen) || align) {
                align = false;
                alignAndReserve(1, 1);
            }
            avail = bbwi.buflen - bbwi.position();
            wanted = (length + offset) - n;
            bytes = (wanted < avail) ? wanted : avail;
            for (int i = 0; i < bytes; i++)
                bbwi.byteBuffer.put(bbwi.position() + i, value[n+i]);
            bbwi.position(bbwi.position() + bytes);
            n += bytes;
        }
    }

    public final void write_octet_array(byte b[], int offset, int length)
    {
        if ( b == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(length);

        internalWriteOctetArray(b, offset, length);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public void write_Principal(Principal p)
    {
        write_long(p.name().length);
        write_octet_array(p.name(), 0, p.name().length);
    }

    public void write_any(Any any)
    {
        if ( any == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        write_TypeCode(any.type());
        any.write_value(parent);
    }

    public void write_TypeCode(TypeCode tc)
    {
        if ( tc == null ) {
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
        }
        TypeCodeImpl tci;
        if (tc instanceof TypeCodeImpl) {
            tci = (TypeCodeImpl)tc;
        }
        else {
            tci = new TypeCodeImpl(orb, tc);
        }

        tci.write_value((org.omg.CORBA_2_3.portable.OutputStream)parent);
    }

    public void write_Object(org.omg.CORBA.Object ref)
    {
        if (ref == null) {
            IOR nullIOR = IORFactories.makeIOR( orb ) ;
            nullIOR.write(parent);
            return;
        }

        // IDL to Java formal 01-06-06 1.21.4.2
        if (ref instanceof org.omg.CORBA.LocalObject)
            throw wrapper.writeLocalObject(CompletionStatus.COMPLETED_MAYBE);

        IOR ior = ORBUtility.connectAndGetIOR( orb, ref ) ;
        ior.write(parent);
        return;
    }

    // ------------ RMI related methods --------------------------

    public void write_abstract_interface(java.lang.Object obj) {
        boolean corbaObject = false; // Assume value type.
        org.omg.CORBA.Object theObject = null;

        // Is it a CORBA.Object?

        if (obj != null && obj instanceof org.omg.CORBA.Object) {

            // Yes.

            theObject = (org.omg.CORBA.Object)obj;
            corbaObject = true;
        }

        // Write our flag...

        write_boolean(corbaObject);

        // Now write out the object...

        if (corbaObject) {
            write_Object(theObject);
        } else {
            try {
                write_value((java.io.Serializable)obj);
            } catch(ClassCastException cce) {
                if (obj instanceof java.io.Serializable)
                    throw cce;
                else
                    ORBUtility.throwNotSerializableForCorba(obj.getClass().getName());
            }
        }
    }

    public void write_value(Serializable object, Class clz) {

        write_value(object);
    }

    private void writeWStringValue(String string) {

        int indirection = writeValueTag(mustChunk, true, null);

        // Write WStringValue's repository ID
        write_repositoryId(repIdStrs.getWStringValueRepId());

        // Add indirection for object to indirection table
        updateIndirectionTable(indirection, string, string);

        // Write Value chunk
        if (mustChunk) {
            start_block();
            end_flag--;
            chunkedValueNestingLevel--;
        } else
            end_flag--;

        write_wstring(string);

        if (mustChunk)
            end_block();

        // Write end tag
        writeEndTag(mustChunk);
    }

    private void writeArray(Serializable array, Class clazz) {

        if (valueHandler == null)
            valueHandler = ORBUtility.createValueHandler(); //d11638

        // Write value_tag
        int indirection = writeValueTag(mustChunk, true,
                                        Util.getCodebase(clazz));

        // Write repository ID
        write_repositoryId(repIdStrs.createSequenceRepID(clazz));

        // Add indirection for object to indirection table
        updateIndirectionTable(indirection, array, array);

        // Write Value chunk
        if (mustChunk) {
            start_block();
            end_flag--;
            chunkedValueNestingLevel--;
        } else
            end_flag--;

        if (valueHandler instanceof ValueHandlerMultiFormat) {
            ValueHandlerMultiFormat vh = (ValueHandlerMultiFormat)valueHandler;
            vh.writeValue(parent, array, streamFormatVersion);
        } else
            valueHandler.writeValue(parent, array);

        if (mustChunk)
            end_block();

        // Write end tag
        writeEndTag(mustChunk);
    }

    private void writeValueBase(org.omg.CORBA.portable.ValueBase object,
                                Class clazz) {
        // _REVISIT_ could check to see whether chunking really needed
        mustChunk = true;

        // Write value_tag
        int indirection = writeValueTag(true, true, Util.getCodebase(clazz));

        // Get rep id
        String repId = ((ValueBase)object)._truncatable_ids()[0];

        // Write rep id
        write_repositoryId(repId);

        // Add indirection for object to indirection table
        updateIndirectionTable(indirection, object, object);

        // Write Value chunk
        start_block();
        end_flag--;
        chunkedValueNestingLevel--;
        writeIDLValue(object, repId);
        end_block();

        // Write end tag
        writeEndTag(true);
    }

    private void writeRMIIIOPValueType(Serializable object, Class clazz) {
        if (valueHandler == null)
            valueHandler = ORBUtility.createValueHandler(); //d11638

        Serializable key = object;

        // Allow the ValueHandler to call writeReplace on
        // the Serializable (if the method is present)
        object = valueHandler.writeReplace(key);

        if (object == null) {
            // Write null tag and return
            write_long(0);
            return;
        }

        if (object != key) {
            if (valueCache != null && valueCache.containsKey(object)) {
                writeIndirection(INDIRECTION_TAG, valueCache.getVal(object));
                return;
            }

            clazz = object.getClass();
        }

        if (mustChunk || valueHandler.isCustomMarshaled(clazz)) {
            mustChunk = true;
        }

        // Write value_tag
        int indirection = writeValueTag(mustChunk, true, Util.getCodebase(clazz));

        // Write rep. id
        write_repositoryId(repIdStrs.createForJavaType(clazz));

        // Add indirection for object to indirection table
        updateIndirectionTable(indirection, object, key);

        if (mustChunk) {
            // Write Value chunk
            end_flag--;
            chunkedValueNestingLevel--;
            start_block();
        } else
            end_flag--;

        if (valueHandler instanceof ValueHandlerMultiFormat) {
            ValueHandlerMultiFormat vh = (ValueHandlerMultiFormat)valueHandler;
            vh.writeValue(parent, object, streamFormatVersion);
        } else
            valueHandler.writeValue(parent, object);

        if (mustChunk)
            end_block();

        // Write end tag
        writeEndTag(mustChunk);
    }

    public void write_value(Serializable object, String repository_id) {

        // Handle null references
        if (object == null) {
            // Write null tag and return
            write_long(0);
            return;
        }

        // Handle shared references
        if (valueCache != null && valueCache.containsKey(object)) {
            writeIndirection(INDIRECTION_TAG, valueCache.getVal(object));
            return;
        }

        Class clazz = object.getClass();
        boolean oldMustChunk = mustChunk;

        if (mustChunk)
            mustChunk = true;

        if (inBlock)
            end_block();

        if (clazz.isArray()) {
            // Handle arrays
            writeArray(object, clazz);
        } else if (object instanceof org.omg.CORBA.portable.ValueBase) {
            // Handle IDL Value types
            writeValueBase((org.omg.CORBA.portable.ValueBase)object, clazz);
        } else if (shouldWriteAsIDLEntity(object)) {
            writeIDLEntity((IDLEntity)object);
        } else if (object instanceof java.lang.String) {
            writeWStringValue((String)object);
        } else if (object instanceof java.lang.Class) {
            writeClass(repository_id, (Class)object);
        } else {
            // RMI-IIOP value type
            writeRMIIIOPValueType(object, clazz);
        }

        mustChunk = oldMustChunk;

        // Check to see if we need to start another block for a
        // possible outer value
        if (mustChunk)
            start_block();

    }

    public void write_value(Serializable object)
    {
        write_value(object, (String)null);
    }

    public void write_value(Serializable object, org.omg.CORBA.portable.BoxedValueHelper factory)
    {
        // Handle null references
        if (object == null) {
            // Write null tag and return
            write_long(0);
            return;
        }

        // Handle shared references
        if ((valueCache != null) && valueCache.containsKey(object)) {
            writeIndirection(INDIRECTION_TAG, valueCache.getVal(object));
            return;
        }

        boolean oldMustChunk = mustChunk;

        boolean isCustom = false;
        if (factory instanceof ValueHelper) {
            short modifier;
            try {
                modifier = ((ValueHelper)factory).get_type().type_modifier();
            } catch(BadKind ex) {  // tk_value_box
                modifier = VM_NONE.value;
            }
            if (object instanceof CustomMarshal &&
                modifier == VM_CUSTOM.value) {
                isCustom = true;
                mustChunk = true;
            }
            if (modifier == VM_TRUNCATABLE.value)
                mustChunk = true;
        }

        if (mustChunk) {

            if (inBlock)
                end_block();

            // Write value_tag
            int indirection = writeValueTag(true,
                                            orb.getORBData().useRepId(),
                                            Util.getCodebase(object.getClass())
                                           );

            if (orb.getORBData().useRepId()) {
                write_repositoryId(factory.get_id());
            }

            // Add indirection for object to indirection table
            updateIndirectionTable(indirection, object, object);

            // Write Value chunk
            start_block();
            end_flag--;
            chunkedValueNestingLevel--;
            if (isCustom)
                ((CustomMarshal)object).marshal(parent);
            else
                factory.write_value(parent, object);
            end_block();

            // Write end tag
            writeEndTag(true);
        }
        else {
            // Write value_tag
            int indirection = writeValueTag(false,
                                            orb.getORBData().useRepId(),
                                            Util.getCodebase(object.getClass())
                                           );

            if (orb.getORBData().useRepId()) {
                write_repositoryId(factory.get_id());
            }

            // Add indirection for object to indirection table
            updateIndirectionTable(indirection, object, object);

            // Write Value chunk
            end_flag--;
            // no need to test for custom on the non-chunked path
            factory.write_value(parent, object);

            // Write end tag
            writeEndTag(false);
        }

        mustChunk = oldMustChunk;

        // Check to see if we need to start another block for a
        // possible outer value
        if (mustChunk)
            start_block();

    }

    public int get_offset() {
        return bbwi.position();
    }

    public void start_block() {
        if (debug) {
            dprint("CDROutputStream_1_0 start_block, position" + bbwi.position());
        }

        //Move inBlock=true to after write_long since write_long might
        //trigger grow which will lead to erroneous behavior with a
        //missing blockSizeIndex.
        //inBlock = true;

        // Save space in the buffer for block size
        write_long(0);

        //Has to happen after write_long since write_long could
        //trigger grow which is overridden by supper classes to
        //depend on inBlock.
        inBlock = true;

        blockSizePosition = get_offset();

        // Remember where to put the size of the endblock less 4
        blockSizeIndex = bbwi.position();

        if (debug) {
            dprint("CDROutputStream_1_0 start_block, blockSizeIndex "
                   + blockSizeIndex);
        }

    }

    // Utility method which will hopefully decrease chunking complexity
    // by allowing us to end_block and update chunk lengths without
    // calling alignAndReserve.  Otherwise, it's possible to get into
    // recursive scenarios which lose the chunking state.
    protected void writeLongWithoutAlign(int x) {
        if (littleEndian) {
            writeLittleEndianLong(x);
        } else {
            writeBigEndianLong(x);
        }
    }

    public void end_block() {
        if (debug) {
            dprint("CDROutputStream_1_0.java end_block");
        }

        if (!inBlock)
            return;

        if (debug) {
            dprint("CDROutputStream_1_0.java end_block, in a block");
        }

        inBlock = false;

        // Test to see if the block was of zero length
        // If so, remove the block instead of ending it
        // (This can happen if the last field written
        //  in a value was another value)
        if (get_offset() == blockSizePosition) {
            // Need to assert that blockSizeIndex == bbwi.position()?  REVISIT

            bbwi.position(bbwi.position() - 4);
            blockSizeIndex = -1;
            blockSizePosition = -1;
            return;
        }

        int oldSize = bbwi.position();
        bbwi.position(blockSizeIndex - 4);

        writeLongWithoutAlign(oldSize - blockSizeIndex);

        bbwi.position(oldSize);
        blockSizeIndex = -1;
        blockSizePosition = -1;

        // System.out.println("      post end_block: " + get_offset() + " " + bbwi.position());
    }

    public org.omg.CORBA.ORB orb()
    {
        return orb;
    }

    // ------------ End RMI related methods --------------------------

    public final void write_boolean_array(boolean[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(length);

        for (int i = 0; i < length; i++)
            write_boolean(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public final void write_char_array(char[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(length);

        for (int i = 0; i < length; i++)
            write_char(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public void write_wchar_array(char[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(computeAlignment(2) + (length * 2));

        for (int i = 0; i < length; i++)
            write_wchar(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public final void write_short_array(short[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(computeAlignment(2) + (length * 2));

        for (int i = 0; i < length; i++)
            write_short(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public final void write_ushort_array(short[]value, int offset, int length) {
        write_short_array(value, offset, length);
    }

    public final void write_long_array(int[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(computeAlignment(4) + (length * 4));

        for (int i = 0; i < length; i++)
            write_long(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public final void write_ulong_array(int[]value, int offset, int length) {
        write_long_array(value, offset, length);
    }

    public final void write_longlong_array(long[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(computeAlignment(8) + (length * 8));

        for (int i = 0; i < length; i++)
            write_longlong(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public final void write_ulonglong_array(long[]value, int offset, int length) {
        write_longlong_array(value, offset, length);
    }

    public final void write_float_array(float[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(computeAlignment(4) + (length * 4));

        for (int i = 0; i < length; i++)
            write_float(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public final void write_double_array(double[]value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        // This will only have an effect if we're already chunking
        handleSpecialChunkBegin(computeAlignment(8) + (length * 8));

        for (int i = 0; i < length; i++)
            write_double(value[offset + i]);

        // This will only have an effect if we're already chunking
        handleSpecialChunkEnd();
    }

    public void write_string_array(String[] value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        for(int i = 0; i < length; i++)
            write_string(value[offset + i]);
    }

    public void write_wstring_array(String[] value, int offset, int length) {
        if ( value == null )
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);

        for(int i = 0; i < length; i++)
            write_wstring(value[offset + i]);
    }

    public final void write_any_array(org.omg.CORBA.Any value[], int offset, int length)
    {
        for(int i = 0; i < length; i++)
            write_any(value[offset + i]);
    }

    //--------------------------------------------------------------------//
    // CDROutputStream state management.
    //

    public void writeTo(java.io.OutputStream s)
        throws java.io.IOException
    {
        byte[] tmpBuf = null;

        if (bbwi.byteBuffer.hasArray())
        {
            tmpBuf = bbwi.byteBuffer.array();
        }
        else
        {
            int size = bbwi.position();
            tmpBuf = new byte[size];
            // Micro-benchmarks are showing a loop of ByteBuffer.get(int) is
            // faster than ByteBuffer.get(byte[], offset, length)
            for (int i = 0; i < size; i++)
                tmpBuf[i] = bbwi.byteBuffer.get(i);
        }

        s.write(tmpBuf, 0, bbwi.position());
    }

    public void writeOctetSequenceTo(org.omg.CORBA.portable.OutputStream s) {

        byte[] buf = null;

        if (bbwi.byteBuffer.hasArray())
        {
            buf = bbwi.byteBuffer.array();
        }
        else
        {
            int size = bbwi.position();
            buf = new byte[size];
            // Micro-benchmarks are showing a loop of ByteBuffer.get(int) is
            // faster than ByteBuffer.get(byte[], offset, length)
            for (int i = 0; i < size; i++)
                buf[i] = bbwi.byteBuffer.get(i);
        }

        s.write_long(bbwi.position());
        s.write_octet_array(buf, 0, bbwi.position());

    }

    public final int getSize() {
        return bbwi.position();
    }

    public int getIndex() {
        return bbwi.position();
    }

    public boolean isLittleEndian() {
        return littleEndian;
    }

    public void setIndex(int value) {
        bbwi.position(value);
    }

    public ByteBufferWithInfo getByteBufferWithInfo() {
        return bbwi;
    }

    public void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
        this.bbwi = bbwi;
    }

    public ByteBuffer getByteBuffer() {
        ByteBuffer result = null;;
        if (bbwi != null) {
            result = bbwi.byteBuffer;
        }
        return result;
    }

    public void setByteBuffer(ByteBuffer byteBuffer) {
        bbwi.byteBuffer = byteBuffer;
    }

    private final void updateIndirectionTable(int indirection, java.lang.Object object,
                                              java.lang.Object key) {
        // int indirection = get_offset();
        if (valueCache == null)
            valueCache = new CacheTable(orb,true);
        valueCache.put(object, indirection);
        if (key != object)
            valueCache.put(key, indirection);
    }

    private final void write_repositoryId(String id) {
        // Use an indirection if available
        if (repositoryIdCache != null && repositoryIdCache.containsKey(id)) {
            writeIndirection(INDIRECTION_TAG, repositoryIdCache.getVal(id));
            return;
        }

        // Write it as a string.  Note that we have already done the
        // special case conversion of non-Latin-1 characters to escaped
        // Latin-1 sequences in RepositoryId.

        // It's not a good idea to cache them now that we can have
        // multiple code sets.
        int indirection = writeString(id);

        // Add indirection for id to indirection table
        if (repositoryIdCache == null)
        repositoryIdCache = new CacheTable(orb,true);
        repositoryIdCache.put(id, indirection);
    }

    private void write_codebase(String str, int pos) {
        if (codebaseCache != null && codebaseCache.containsKey(str)) {
            writeIndirection(INDIRECTION_TAG, codebaseCache.getVal(str));
        }
        else {
            write_string(str);
            if (codebaseCache == null)
                codebaseCache = new CacheTable(orb,true);
            codebaseCache.put(str, pos);
        }
    }

    private final int writeValueTag(boolean chunkIt, boolean useRepId,
                                    String codebase) {
        int indirection = 0;
        if (chunkIt && !useRepId){
            if (codebase == null) {
                write_long(repIdUtil.getStandardRMIChunkedNoRepStrId());
                indirection = get_offset() - 4;
            } else {
                write_long(repIdUtil.getCodeBaseRMIChunkedNoRepStrId());
                indirection = get_offset() - 4;
                write_codebase(codebase, get_offset());
            }
        } else if (chunkIt && useRepId){
            if (codebase == null) {
                write_long(repIdUtil.getStandardRMIChunkedId());
                indirection = get_offset() - 4;
            } else {
                write_long(repIdUtil.getCodeBaseRMIChunkedId());
                indirection = get_offset() - 4;
                write_codebase(codebase, get_offset());
            }
        } else if (!chunkIt && !useRepId) {
            if (codebase == null) {
                write_long(repIdUtil.getStandardRMIUnchunkedNoRepStrId());
                indirection = get_offset() - 4;
            } else {
                write_long(repIdUtil.getCodeBaseRMIUnchunkedNoRepStrId());
                indirection = get_offset() - 4;
                write_codebase(codebase, get_offset());
            }
        } else if (!chunkIt && useRepId) {
            if (codebase == null) {
                write_long(repIdUtil.getStandardRMIUnchunkedId());
                indirection = get_offset() - 4;
            } else {
                write_long(repIdUtil.getCodeBaseRMIUnchunkedId());
                indirection = get_offset() - 4;
                write_codebase(codebase, get_offset());
            }
        }
        return indirection;
    }

    private void writeIDLValue(Serializable object, String repID)
    {
        if (object instanceof StreamableValue) {
            ((StreamableValue)object)._write(parent);

        } else if (object instanceof CustomValue) {
            ((CustomValue)object).marshal(parent);

        } else {
            BoxedValueHelper helper = Utility.getHelper(object.getClass(), null, repID);
            boolean isCustom = false;
            if (helper instanceof ValueHelper && object instanceof CustomMarshal) {
                try {
                    if (((ValueHelper)helper).get_type().type_modifier() == VM_CUSTOM.value)
                        isCustom = true;
                } catch(BadKind ex) {
                    throw wrapper.badTypecodeForCustomValue( CompletionStatus.COMPLETED_MAYBE,
                        ex ) ;
                }
            }
            if (isCustom)
                ((CustomMarshal)object).marshal(parent);
            else
                helper.write_value(parent, object);
        }
    }

    // Handles end tag compaction...
    private void writeEndTag(boolean chunked){

        if (chunked) {
            if (get_offset() == end_flag_position) {

                if (bbwi.position() == end_flag_index) {

                    // We are exactly at the same position and index as the
                    // end of the last end tag.  Thus, we can back up over it
                    // and compact the tags.
                    bbwi.position(bbwi.position() - 4);

                } else {

                    // Special case in which we're at the beginning of a new
                    // fragment, but the position is the same.  We can't back up,
                    // so we just write the new end tag without compaction.  This
                    // occurs when a value ends and calls start_block to open a
                    // continuation chunk, but it's called at the very end of
                    // a fragment.
                }
            }

            writeNestingLevel();

            // Remember the last index and position.  These are only used when chunking.
            end_flag_index = bbwi.position();
            end_flag_position = get_offset();

            chunkedValueNestingLevel++;
        }

        // Increment the nesting level
        end_flag++;
    }

    /**
     * Handles ORB versioning of the end tag.  Should only
     * be called if chunking.
     *
     * If talking to our older ORBs (Standard Extension,
     * Kestrel, and Ladybird), write the end flag that takes
     * into account all enclosing valuetypes.
     *
     * If talking a newer or foreign ORB, or if the orb
     * instance is null, write the end flag that only takes
     * into account the enclosing chunked valuetypes.
     */
    private void writeNestingLevel() {
        if (orb == null ||
            ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) ||
            ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) {

            write_long(chunkedValueNestingLevel);

        } else {
            write_long(end_flag);
        }
    }

    private void writeClass(String repository_id, Class clz) {

        if (repository_id == null)
            repository_id = repIdStrs.getClassDescValueRepId();

        // Write value_tag
        int indirection = writeValueTag(mustChunk, true, null);
        updateIndirectionTable(indirection, clz, clz);

        write_repositoryId(repository_id);

        if (mustChunk) {
            // Write Value chunk
            start_block();
            end_flag--;
            chunkedValueNestingLevel--;
        } else
            end_flag--;

        writeClassBody(clz);

        if (mustChunk)
            end_block();

        // Write end tag
        writeEndTag(mustChunk);
    }

    // Pre-Merlin/J2EE 1.3 ORBs wrote the repository ID
    // and codebase strings in the wrong order.  This handles
    // backwards compatibility.
    private void writeClassBody(Class clz) {
        if (orb == null ||
            ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) ||
            ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) {

            write_value(Util.getCodebase(clz));
            write_value(repIdStrs.createForAnyType(clz));
        } else {

            write_value(repIdStrs.createForAnyType(clz));
            write_value(Util.getCodebase(clz));
        }
    }

    // Casts and returns an Object as a Serializable
    // This is required for JDK 1.1 only to avoid VerifyErrors when
    // passing arrays as Serializable
    // private java.io.Serializable make_serializable(java.lang.Object object)
    // {
    //  return (java.io.Serializable)object;
    // }

    private boolean shouldWriteAsIDLEntity(Serializable object)
    {
        return ((object instanceof IDLEntity) && (!(object instanceof ValueBase)) &&
                (!(object instanceof org.omg.CORBA.Object)));

    }

    private void writeIDLEntity(IDLEntity object) {

        // _REVISIT_ could check to see whether chunking really needed
        mustChunk = true;

        String repository_id = repIdStrs.createForJavaType(object);
        Class clazz = object.getClass();
        String codebase = Util.getCodebase(clazz);

        // Write value_tag
        int indirection = writeValueTag(true, true, codebase);
        updateIndirectionTable(indirection, object, object);

        // Write rep. id
        write_repositoryId(repository_id);

        // Write Value chunk
        end_flag--;
        chunkedValueNestingLevel--;
        start_block();

        // Write the IDLEntity using reflection
        try {
            ClassLoader clazzLoader = (clazz == null ? null : clazz.getClassLoader());
            final Class helperClass = Utility.loadClassForClass(clazz.getName()+"Helper", codebase,
                                                   clazzLoader, clazz, clazzLoader);
            final Class argTypes[] = {org.omg.CORBA.portable.OutputStream.class, clazz};
            // getDeclaredMethod requires RuntimePermission accessDeclaredMembers
            // if a different class loader is used (even though the javadoc says otherwise)
            Method writeMethod = null;
            try {
                writeMethod = (Method)AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public java.lang.Object run() throws NoSuchMethodException {
                            return helperClass.getDeclaredMethod(kWriteMethod, argTypes);
                        }
                    }
                );
            } catch (PrivilegedActionException pae) {
                // this gets caught below
                throw (NoSuchMethodException)pae.getException();
            }
            java.lang.Object args[] = {parent, object};
            writeMethod.invoke(null, args);
        } catch (ClassNotFoundException cnfe) {
            throw wrapper.errorInvokingHelperWrite( CompletionStatus.COMPLETED_MAYBE, cnfe ) ;
        } catch(NoSuchMethodException nsme) {
            throw wrapper.errorInvokingHelperWrite( CompletionStatus.COMPLETED_MAYBE, nsme ) ;
        } catch(IllegalAccessException iae) {
            throw wrapper.errorInvokingHelperWrite( CompletionStatus.COMPLETED_MAYBE, iae ) ;
        } catch(InvocationTargetException ite) {
            throw wrapper.errorInvokingHelperWrite( CompletionStatus.COMPLETED_MAYBE, ite ) ;
        }
        end_block();

        // Write end tag
        writeEndTag(true);
    }

    /* DataOutputStream methods */

    public void write_Abstract (java.lang.Object value) {
        write_abstract_interface(value);
    }

    public void write_Value (java.io.Serializable value) {
        write_value(value);
    }

    // This will stay a custom add-on until the java-rtf issue is resolved.
    // Then it should be declared in org.omg.CORBA.portable.OutputStream.
    //
    // Pads the string representation of bigDecimal with zeros to fit the given
    // digits and scale before it gets written to the stream.
    public void write_fixed(java.math.BigDecimal bigDecimal, short digits, short scale) {
        String string = bigDecimal.toString();
        String integerPart;
        String fractionPart;
        StringBuffer stringBuffer;

        // Get rid of the sign
        if (string.charAt(0) == '-' || string.charAt(0) == '+') {
            string = string.substring(1);
        }

        // Determine integer and fraction parts
        int dotIndex = string.indexOf('.');
        if (dotIndex == -1) {
            integerPart = string;
            fractionPart = null;
        } else if (dotIndex == 0 ) {
            integerPart = null;
            fractionPart = string;
        } else {
            integerPart = string.substring(0, dotIndex);
            fractionPart = string.substring(dotIndex + 1);
        }

        // Pad both parts with zeros as necessary
        stringBuffer = new StringBuffer(digits);
        if (fractionPart != null) {
            stringBuffer.append(fractionPart);
        }
        while (stringBuffer.length() < scale) {
            stringBuffer.append('0');
        }
        if (integerPart != null) {
            stringBuffer.insert(0, integerPart);
        }
        while (stringBuffer.length() < digits) {
            stringBuffer.insert(0, '0');
        }

        // This string contains no sign or dot
        this.write_fixed(stringBuffer.toString(), bigDecimal.signum());
    }

    // This method should be remove by the java-rtf issue.
    // Right now the scale and digits information of the type code is lost.
    public void write_fixed(java.math.BigDecimal bigDecimal) {
        // This string might contain sign and/or dot
        this.write_fixed(bigDecimal.toString(), bigDecimal.signum());
    }

    // The string may contain a sign and dot
    public void write_fixed(String string, int signum) {
        int stringLength = string.length();
        // Each octet contains (up to) two decimal digits
        byte doubleDigit = 0;
        char ch;
        byte digit;

        // First calculate the length of the string without optional sign and dot
        int numDigits = 0;
        for (int i=0; i<stringLength; i++) {
            ch = string.charAt(i);
            if (ch == '-' || ch == '+' || ch == '.')
                continue;
            numDigits++;
        }
        for (int i=0; i<stringLength; i++) {
            ch = string.charAt(i);
            if (ch == '-' || ch == '+' || ch == '.')
                continue;
            digit = (byte)Character.digit(ch, 10);
            if (digit == -1) {
                throw wrapper.badDigitInFixed( CompletionStatus.COMPLETED_MAYBE ) ;
            }
            // If the fixed type has an odd number of decimal digits,
            // then the representation begins with the first (most significant) digit.
            // Otherwise, this first half-octet is all zero, and the first digit
            // is in the second half-octet.
            if (numDigits % 2 == 0) {
                doubleDigit |= digit;
                this.write_octet(doubleDigit);
                doubleDigit = 0;
            } else {
                doubleDigit |= (digit << 4);
            }
            numDigits--;
        }
        // The sign configuration, in the last half-octet of the representation,
        // is 0xD for negative numbers and 0xC for positive and zero values
        if (signum == -1) {
            doubleDigit |= 0xd;
        } else {
            doubleDigit |= 0xc;
        }
        this.write_octet(doubleDigit);
    }

    private final static String _id = "IDL:omg.org/CORBA/DataOutputStream:1.0";
    private final static String[] _ids = { _id };

    public String[] _truncatable_ids() {
        if (_ids == null)
            return null;

        return (String[])_ids.clone();
    }

    /* for debugging */

    public void printBuffer() {
        CDROutputStream_1_0.printBuffer(this.bbwi);
    }

    public static void printBuffer(ByteBufferWithInfo bbwi) {

        System.out.println("+++++++ Output Buffer ++++++++");
        System.out.println();
        System.out.println("Current position: " + bbwi.position());
        System.out.println("Total length : " + bbwi.buflen);
        System.out.println();

        char[] charBuf = new char[16];

        try {

            for (int i = 0; i < bbwi.position(); i += 16) {

                int j = 0;

                // For every 16 bytes, there is one line
                // of output.  First, the hex output of
                // the 16 bytes with each byte separated
                // by a space.
                while (j < 16 && j + i < bbwi.position()) {
                    int k = bbwi.byteBuffer.get(i + j);
                    if (k < 0)
                        k = 256 + k;
                    String hex = Integer.toHexString(k);
                    if (hex.length() == 1)
                        hex = "0" + hex;
                    System.out.print(hex + " ");
                    j++;
                }

                // Add any extra spaces to align the
                // text column in case we didn't end
                // at 16
                while (j < 16) {
                    System.out.print("   ");
                    j++;
                }

                // Now output the ASCII equivalents.  Non-ASCII
                // characters are shown as periods.
                int x = 0;

                while (x < 16 && x + i < bbwi.position()) {
                    if (ORBUtility.isPrintable((char)bbwi.byteBuffer.get(i + x)))
                        charBuf[x] = (char)bbwi.byteBuffer.get(i + x);
                    else
                        charBuf[x] = '.';
                    x++;
                }
                System.out.println(new String(charBuf, 0, x));
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
        System.out.println("++++++++++++++++++++++++++++++");
    }

    public void writeIndirection(int tag, int posIndirectedTo)
    {
        // Must ensure that there are no chunks between the tag
        // and the actual indirection value.  This isn't talked about
        // in the spec, but seems to cause headaches in our code.
        // At the very least, this method isolates the indirection code
        // that was duplicated so often.

        handleSpecialChunkBegin(computeAlignment(4) + 8);

        // write indirection tag
        write_long(tag);

        // write indirection
        // Use parent.getRealIndex() so that it can be overridden by TypeCodeOutputStreams
/*
        System.out.println("CDROutputStream_1_0 writing indirection pos " + posIndirectedTo +
                           " - real index " + parent.getRealIndex(get_offset()) + " = " +
                           (posIndirectedTo - parent.getRealIndex(get_offset())));
*/
        write_long(posIndirectedTo - parent.getRealIndex(get_offset()));

        handleSpecialChunkEnd();
    }

    protected CodeSetConversion.CTBConverter getCharConverter() {
        if (charConverter == null)
            charConverter = parent.createCharCTBConverter();

        return charConverter;
    }

    protected CodeSetConversion.CTBConverter getWCharConverter() {
        if (wcharConverter == null)
            wcharConverter = parent.createWCharCTBConverter();

        return wcharConverter;
    }

    protected void dprint(String msg) {
        if (debug)
            ORBUtility.dprint(this, msg);
    }

    void alignOnBoundary(int octetBoundary) {
        alignAndReserve(octetBoundary, 0);
    }

    public void start_value(String rep_id) {

        if (debug) {
            dprint("start_value w/ rep id "
                   + rep_id
                   + " called at pos "
                   + get_offset()
                   + " position "
                   + bbwi.position());
        }

        if (inBlock)
            end_block();

        // Write value_tag
        writeValueTag(true, true, null);

        // Write rep. id
        write_repositoryId(rep_id);

        // Write Value chunk
        end_flag--;
        chunkedValueNestingLevel--;

        // Make sure to chunk the custom data
        start_block();
    }

    public void end_value() {

        if (debug) {
            dprint("end_value called at pos "
                   + get_offset()
                   + " position "
                   + bbwi.position());
        }

        end_block();

        writeEndTag(true);

        // Check to see if we need to start another block for a
        // possible outer value.  Since we're in the stream
        // format 2 custom type contained by another custom
        // type, mustChunk should always be true.
        //
        // Here's why we need to open a continuation chunk:
        //
        // We need to enclose the default data of the
        // next subclass down in chunks.  There won't be
        // an end tag separating the superclass optional
        // data and the subclass's default data.

        if (debug) {
            dprint("mustChunk is " + mustChunk);
        }

        if (mustChunk) {
            start_block();
        }
    }

    public void close() throws IOException
    {
        // tell BufferManagerWrite to release any ByteBuffers
        getBufferManager().close();

        // It's possible bbwi.byteBuffer is shared between
        // this OutputStream and an InputStream. Thus, we check
        // if the Input/Output streams are using the same ByteBuffer.
        // If they sharing the same ByteBuffer we need to ensure only
        // one of those ByteBuffers are released to the ByteBufferPool.

        if (getByteBufferWithInfo() != null && getByteBuffer() != null)
        {
            MessageMediator messageMediator = parent.getMessageMediator();
            if (messageMediator != null)
            {
                CDRInputObject inputObj =
                               (CDRInputObject)messageMediator.getInputObject();
                if (inputObj != null)
                {
                    if (inputObj.isSharing(getByteBuffer()))
                    {
                        // Set InputStream's ByteBuffer and bbwi to null
                        // so its ByteBuffer cannot be released to the pool
                        inputObj.setByteBuffer(null);
                        inputObj.setByteBufferWithInfo(null);
                    }
                }
            }

            // release this stream's ByteBuffer to the pool
            ByteBufferPool byteBufferPool = orb.getByteBufferPool();
            if (debug)
            {
                // print address of ByteBuffer being released
                int bbAddress = System.identityHashCode(bbwi.byteBuffer);
                StringBuffer sb = new StringBuffer(80);
                sb.append(".close - releasing ByteBuffer id (");
                sb.append(bbAddress).append(") to ByteBufferPool.");
                String msg = sb.toString();
                dprint(msg);
             }
             byteBufferPool.releaseByteBuffer(getByteBuffer());
             bbwi.byteBuffer = null;
             bbwi = null;
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java CDROutputStream_1_0.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.