📄 vio.java
字号:
/* Vio.java -- Value type IO operations. Copyright (C) 2005 Free Software Foundation, Inc.This file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING. If not, write to theFree Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA02110-1301 USA.Linking this library statically or dynamically with other modules ismaking a combined work based on this library. Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule. An independent module is a module which is not derived fromor based on this library. If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so. If you do not wish to do so, delete thisexception statement from your version. */package gnu.CORBA.CDR;import gnu.CORBA.Minor;import gnu.CORBA.ObjectCreator;import org.omg.CORBA.CustomMarshal;import org.omg.CORBA.DataInputStream;import org.omg.CORBA.DataOutputStream;import org.omg.CORBA.MARSHAL;import org.omg.CORBA.NO_IMPLEMENT;import org.omg.CORBA.StringSeqHelper;import org.omg.CORBA.StringValueHelper;import org.omg.CORBA.SystemException;import org.omg.CORBA.WStringValueHelper;import org.omg.CORBA.portable.BoxedValueHelper;import org.omg.CORBA.portable.InputStream;import org.omg.CORBA.portable.OutputStream;import org.omg.CORBA.portable.Streamable;import org.omg.CORBA.portable.ValueFactory;import java.io.IOException;import java.io.Serializable;import java.lang.reflect.Constructor;import java.lang.reflect.Modifier;import java.util.StringTokenizer;import javax.rmi.CORBA.Util;import javax.rmi.CORBA.ValueHandler;/** * A specialised class for reading and writing the value types. * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */public abstract class Vio{ /** * If true, wrap value type data into chunks. This decrease the performance, * and is not required for interoperability with jdk 1.5, but is left in the * implementation as the optional mode for solving possible interoperability * problems with non-Sun CORBA implementations. * * The current implementation would accept both single chunk or multiple * chunks, but will always send a single chunk (if true) or unchunked data (if * false). */ public static boolean USE_CHUNKING = false; /** * The first field in the value record. The last octet may contain additional * flags (vf_CODEBASE, vf_ID and vf_MULTIPLE_IDS). The tag value is different * for the indirections (vt_INDIRECTION) and nulls (vt_NULL). */ public static final int vt_VALUE_TAG = 0x7fffff00; /** * The value tag flag, indicating that the codebase URL is present in the * value tag record. */ public static final int vf_CODEBASE = 0x1; /** * The value tag flag, indicating that a single repository id is present in * the value tag record. */ public static final int vf_ID = 0x2; /** * The value tag flag, indicating, that there are multiple repository ids * present in the record. If this flag is set, the flag vf_ID must also be * set, resulting the value of the least significant byte 0x6. */ public static final int vf_MULTIPLE_IDS = 0x4; /** * The value tag flag, indicating the presence of chunking. Each chunk is * preceeded by a positive int, indicating the number of bytes in the chunk. A * sequence of chunks is terminated by a non positive int. */ public static final int vf_CHUNKING = 0x8; /** * The indirection tag value. Such tag must be followed by the CORBA long, * indicating the offset in the CORBA message, where the indirected * information is present. This offset is assumed zero at the position where * the mentioned CORBA long starts and can refer both forward (positive * values) and backward (negative values). */ public static final int vt_INDIRECTION = 0xffffffff; /** * This tag value means that the value object being transferred is equal to * null. */ public static final int vt_NULL = 0x0; /** * The size of CORBA long (java int). */ static final int INT_SIZE = 4; /** * The String value helper (one instance is sufficient). */ public static final WStringValueHelper m_StringValueHelper = new WStringValueHelper(); /** * An instance of the value handler. */ static ValueHandler handler = Util.createValueHandler(); /** * Read the value base from the given input stream. Determines the required * class from the repository id. This includes operations that are not * required when an unitialised instance or at least class of the value type * is known. Hence it may be faster to use the alternative methods, * read(InputStream, Class) or read(InputStream, Serializable). * * @param input a stream to read from. * @param repository_id a repository id of the object being read, may be null. * * @return the loaded value. * * @throws MARSHAL if the reading has failed due any reason. */ public static Serializable read(InputStream input) { return read(input, (String) null); } /** * Read the value base from the given input stream. Determines the required * class from the repository id. This includes operations that are not * required when an unitialised instance or at least class of the value type * is known. Hence it may be faster to use the alternative methods, * read(InputStream, Class) or read(InputStream, Serializable). * * @param an_input a stream to read from. * @param repository_id a repository id of the object being read, may be null. * * @return the loaded value. * * @throws MARSHAL if the reading has failed due any reason. */ public static Serializable read(InputStream input, String repository_id) { try { final int position = getCurrentPosition(input); // We may need to jump back if the value is read via value factory. input.mark(512); int value_tag = input.read_long(); checkTag(value_tag); String codebase = null; String[] ids = null; String id = repository_id; // Check for the agreed null value. if (value_tag == vt_NULL) return null; else if (value_tag == vt_INDIRECTION) return readIndirection(input); else { // Read the value. if ((value_tag & vf_CODEBASE) != 0) { // The codebase is present. The codebase is a space // separated list of URLs from where the implementing // code can be downloaded. codebase = read_string(input); } if ((value_tag & vf_MULTIPLE_IDS) != 0) { // Multiple supported repository ids are present. ids = read_string_array(input); } else if ((value_tag & vf_ID) != 0) { // Single supported repository id is present. id = read_string(input); } } BoxedValueHelper helper = getHelper(null, id); // The existing implementing object. java.lang.Object ox = null; if (helper != null) ox = null; // Helper will care about the instantiating. else if (id.equals(WStringValueHelper.id())) helper = m_StringValueHelper; else ox = createInstance(id, ids, codebase); return (Serializable) read_instance(input, position, ox, value_tag, helper, id, ids, codebase); } catch (Exception ex) { MARSHAL m = new MARSHAL(); m.minor = Minor.Value; m.initCause(ex); throw m; } } /** * Read the value base from the given input stream when the value base class * is available. Hence there is no need to guess it from the repository id. * * @param input a stream to read from. * @param value_class the class of the value being read. * * @return the loaded value. * * @throws MARSHAL if the reading has failed due any reason. */ public static Serializable read(InputStream input, Class value_class) { final int position = getCurrentPosition(input); String id = null; String[] ids = null; String codebase = null; try { int value_tag = input.read_long(); checkTag(value_tag); // Check for the agreed null value. if (value_tag == vt_NULL) return null; else if (value_tag == vt_INDIRECTION) return readIndirection(input); else { // Read the value. if ((value_tag & vf_CODEBASE) != 0) { // The codebase is present. codebase = read_string(input); } if ((value_tag & vf_MULTIPLE_IDS) != 0) { // Multiple supported repository ids are present. ids = read_string_array(input); } else if ((value_tag & vf_ID) != 0) { // Single supported repository id is present. id = read_string(input); } } BoxedValueHelper vHelper = id != null ? getHelper(value_class, id) : getHelper(value_class, ids); java.lang.Object ox; if (vHelper == null) { try { ox = createInstance(id, ids, codebase); } catch (Exception e) { ox = null; } if (ox != null) { if (value_class != null && !value_class.isAssignableFrom(ox.getClass())) { MARSHAL m = new MARSHAL(ox.getClass() + " is not a " + value_class.getName()); m.minor = Minor.ClassCast; throw m; } } } else ox = null; ox = read_instance(input, position, ox, value_tag, vHelper, id, ids, codebase); return (Serializable) ox; } catch (MARSHAL m) { throw m; } catch (SystemException sysEx) { // OK. throw sysEx; } catch (Exception ex) { MARSHAL m = new MARSHAL("Cant read " + value_class); m.minor = Minor.Value; m.initCause(ex); throw m; } } /** * Read the value base from the given input stream when the unitialised * instance is available. Hence there is no need to guess the class from the * repository id and then to instantiate an instance. * * @param input a stream to read from. * * @param value_instance an pre-created instance of the value. If the helper * is not null, this parameter is ignored an should be null. * * @param helper a helper to create an instance and read the object- specific * part of the record. If the value_instance is used instead, this parameter * should be null. * * @return the loaded value. * * @throws MARSHAL if the reading has failed due any reason. */ public static Object read(InputStream input, Object value_instance, BoxedValueHelper helper) { final int position = getCurrentPosition(input); String id = null; String[] ids = null; String codebase = null; try { int value_tag = input.read_long(); checkTag(value_tag); // Check for the agreed null value. if (value_tag == vt_NULL) return null; else if (value_tag == vt_INDIRECTION) return readIndirection(input); else { // Read the value. if ((value_tag & vf_CODEBASE) != 0) { // The codebase is present. codebase = read_string(input); } if ((value_tag & vf_MULTIPLE_IDS) != 0) { // Multiple supported repository ids are present. ids = read_string_array(input); } else if ((value_tag & vf_ID) != 0) { // Single supported repository id is present. id = read_string(input); } } Class value_class = value_instance == null ? null : value_instance.getClass(); if (helper == null) helper = id != null ? getHelper(value_class, id) : getHelper( value_class, ids); value_instance = read_instance(input, position, value_instance, value_tag, helper, id, ids, codebase); return value_instance; } catch (Exception ex) { MARSHAL m = new MARSHAL(); m.minor = Minor.Value; m.initCause(ex); throw m; } } /** * Read using provided boxed value helper. This method expects the full value * type header, followed by contents, that are delegated to the provided * helper. It handles null. * * @param input the stream to read from. * @param helper the helper that reads the type-specific part of the content. * * @return the value, created by the helper, or null if the header indicates * that null was previously written. */ public static Serializable read(InputStream input, BoxedValueHelper helper) { return (Serializable) read(input, null, helper); } /** * Fill in the instance fields by the data from the input stream. The method * assumes that the value header, if any, is already behind. The information * from the stream is stored into the passed ox parameter. * * @param input an input stream to read from. * * @param value a pre-instantiated value type object, must be either * Streamable or CustomMarshal. If the helper is used, this parameter is * ignored and should be null. * * @param value_tag the tag that must be read previously. * @param helper the helper for read object specific part; may be null to read * in using other methods. * * @return the value that was read. */ static Object read_instance(InputStream input, final int position, Object value, int value_tag, BoxedValueHelper helper, String id, String[] ids, String codebase) { if (helper != m_StringValueHelper && id != null) if (id.equals(StringValueHelper.id())) { value = null; helper = m_StringValueHelper; } try { if ((value_tag & vf_CHUNKING) != 0) { BufferedCdrOutput output = createBuffer(input, 1024); // Read the current (not a nested one) value in this spec case. readNestedValue(value_tag, input, output, -1); BufferredCdrInput ci = new BufferredCdrInput(output.buffer.getBuffer()); ci.setRunTime(output.getRunTime()); input = new HeadlessInput(ci, input); } else { if (input instanceof BufferredCdrInput) { // Highly probable case. input = new HeadlessInput((BufferredCdrInput) input, null); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -