cdroutputstream_1_0.java

来自「JAVA 所有包」· Java 代码 · 共 1,932 行 · 第 1/4 页

JAVA
1,932
字号
/* * @(#)CDROutputStream_1_0.java	1.114 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * Licensed Materials - Property of IBM * RMI-IIOP v1.0 * Copyright IBM Corp. 1998 1999  All Rights Reserved * * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */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()    {        if (orb != null) {            // Get the appropriate versions based on the ORB version.  The            // ORB versioning info is only in the core ORB.            repIdUtil                 = RepositoryIdFactory.getRepIdUtility(orb);            repIdStrs                 = RepositoryIdFactory.getRepIdStringsFactory(orb);        } else {            // Get the latest versions            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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?