The files jacorb.jar and idl.jar in this directory are a patched version of JacORB 2.2.4. The patched libraries identify themselves as JacORB V 2.2.4 (JBoss patch 2), www.jacorb.org Instructions for generating these files are included below. Kudos to the JacORB team, for this great open-source ORB. Special thanks to: Gerald Brose, for creating JacORB Andre Spiegel, for his work on OBV in JacORB Francisco --------------------------------------------------------------------------- *** How to generate the jacorb.jar and idl.jar files in this directory *** (1) Obtain a JacORB 2.2.4+ source tree, with the following commands: cvs -d :pserver:anonymous@www.jacorb.org/cvsroot/jacorb checkout -r Root_RELEASE_2_2_5_BRANCH JacORB cd JacORB cvs update -r1.1 src/org/jacorb/util/Stack.java (2) Apply the patchfile below: Index: src/org/jacorb/orb/CDRInputStream.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/CDRInputStream.java,v retrieving revision 1.97 diff -u -r1.97 CDRInputStream.java --- src/org/jacorb/orb/CDRInputStream.java 31 May 2006 13:08:14 -0000 1.97 +++ src/org/jacorb/orb/CDRInputStream.java 5 May 2007 00:36:08 -0000 @@ -21,12 +21,17 @@ */ import java.io.IOException; +import java.io.Serializable; +import java.math.BigDecimal; import java.util.*; import org.apache.avalon.framework.configuration.*; import org.apache.avalon.framework.logger.*; import org.jacorb.orb.giop.CodeSet; +import org.jacorb.orb.giop.GIOPConnection; +import org.jacorb.util.ObjectUtil; +import org.jacorb.util.Stack; import org.jacorb.util.ValueHandler; import org.omg.CORBA.BAD_PARAM; @@ -45,7 +50,7 @@ * Read CDR encoded data * * @author Gerald Brose, FU Berlin - * $Id: CDRInputStream.java,v 1.97 2006/05/31 13:08:14 alphonse.bendt Exp $ + * $Id: CDRInputStream.java,v 1.115 2007/04/27 19:14:06 francisco Exp $ */ public class CDRInputStream @@ -53,25 +58,23 @@ { /** * encaps_stack is used to saving/restoring - * encapsulation information. Do NOT access this variable directly. - * It is initialized on demand. Use the method {@link #getEncapsStack()} + * encapsulation information. */ private Stack encaps_stack; + /** - * recursiveTCMap is used to to remember the original - * TCs for a given ID that is used in a recursive/repeated TC. Do - * NOT access this variable directly. It is initialized on demand. - * Use the method {@link #getRecursiveTCMap()} + * This Map is basically a one-entry map pool to be used in + * read_TypeCode() as the repeatedTCMap. */ - private Map recursiveTCMap; + private Map repeatedTCMap; /** * cachedTypecodes stores a mapping of ID/Typecode to * speed reading from the stream. Do NOT access this variable directly. It * is initialized on demand. Use the methods - * {@link #getCachedTypecode(String id)} and - * {@link #putCachedTypecode(String id, org.omg.CORBA.TypeCode result)} + * {@link #getCachedTypecode(Object id)} and + * {@link #putCachedTypecode(Object id, Pair result)} * Skip amount is * skip (size - ((pos - start_pos) - 4 - 4)); * EncapsulationSize - @@ -145,24 +148,40 @@ /** Ending position of the current chunk */ private int chunk_end_pos = -1; // -1 means we're not within a chunk + /** + * codesetEnabled denotes whether codeset marshalling is enabled. + */ + private boolean codesetEnabled; /** * for this stream to be able to return a live object reference, a * full ORB (not the Singleton!) must be known. If this stream is * used only to demarshal base type data, the Singleton is enough */ - private org.omg.CORBA.ORB orb = null; + private final org.omg.CORBA.ORB orb; /** * this is the lowest possible value_tag indicating the * begin of a valuetype (15.3.4) */ - private static final int max_block_size = 0x7fffff00; + private static final int MAX_BLOCK_SIZE = 0x7fffff00; + /** + * fixes RMI/IIOP related interoperability issues with the + * sun the orb that occured + * while receiving serialized collections. + * see mailing list for details: + * {@link http://lists.spline.inf.fu-berlin.de/mailman/htdig/jacorb-developer/2006-May/008251.html} + */ private boolean sunInteropFix; + + private Map tcMap; + public CDRInputStream(final org.omg.CORBA.ORB orb, final byte[] buf) { + super(); + buffer = buf; // orb may be null! if (orb != null) @@ -183,7 +202,9 @@ } } else + { this.orb = org.omg.CORBA.ORB.init(); + } } public CDRInputStream(final org.omg.CORBA.ORB orb, @@ -194,6 +215,10 @@ this.littleEndian = littleEndian; } + public CDRInputStream(byte[] buffer, boolean littleEndian) + { + this(null, buffer, littleEndian); + } /** * This stream is self-configuring, i.e. configure() is private @@ -203,9 +228,12 @@ private void configure(Configuration configuration) throws ConfigurationException { + final org.jacorb.config.Configuration jacorbConfig = (org.jacorb.config.Configuration)configuration; logger = - ((org.jacorb.config.Configuration)configuration).getNamedLogger("jacorb.orb.cdr"); + jacorbConfig.getNamedLogger("jacorb.orb.cdr"); + codesetEnabled = + configuration.getAttribute("jacorb.codeset","on").equals("on"); cometInteropFix = configuration.getAttribute("jacorb.interop.comet","off").equals("on"); laxBooleanEncoding = @@ -217,39 +245,6 @@ } - - - /** - * getEncapsStack is used to initialize encaps_stack - * on demand. - * - * @return a Stack value - */ - private Stack getEncapsStack() - { - if (encaps_stack == null) - { - encaps_stack = new Stack(); - } - return encaps_stack; - } - - - /** - * Gets the Map that keeps track of recursive TypeCodes. - * - * @return a Map value - */ - private Map getRecursiveTCMap() - { - if (recursiveTCMap == null) - { - recursiveTCMap = new HashMap(); - } - return recursiveTCMap; - } - - /** * Gets the Map that is used to demarshal shared valuetype instances. * @@ -302,24 +297,30 @@ * getCachedTypecode to retrieve a value from cachedTypecodes. * It may initialize the value on demand. * - * @param id a String value + * @param id a Object value, can be String (id) or actual TypeCode + * for sequence/array tcs * @return a org.omg.CORBA.TypeCode value, possibly null. */ - private org.omg.CORBA.TypeCode getCachedTypecode( String id ) + private Pair getCachedTypecode( Object id ) { - org.omg.CORBA.TypeCode result = null; + final Pair result; if ( cacheTypecodes ) { if ( cachedTypecodes == null ) { cachedTypecodes = new HashMap(); + result = null; } else { - result = ( org.omg.CORBA.TypeCode )cachedTypecodes.get( id ); + result = ( Pair )cachedTypecodes.get( id ); } } + else + { + result = null; + } return result; } @@ -328,10 +329,10 @@ * putCachedTypecode is used to store typecodes within the * cachedTypecodes. It will only do it cacheTypecodes is on. * - * @param id a String value - * @param result an org.omg.CORBA.TypeCode value + * @param id a String or TypeCode value + * @param result an Pair value */ - private void putCachedTypecode( String id, org.omg.CORBA.TypeCode result) + private void putCachedTypecode( Object id, Pair result) { if ( cacheTypecodes ) { @@ -353,24 +354,31 @@ } public void close() - throws IOException { // Don't need to call super.close as super is noop. + if( closed ) { return; } - BufferManager.getInstance().returnBuffer(buffer); + // commented out as this caused test failures. + // as the buffer has been passed into this CDRInputStream + // we cannot assume ownership of the buffer here (alphonse). + // BufferManager.getInstance().returnBuffer(buffer); + buffer = null; encaps_stack = null; - recursiveTCMap = null; closed = true; + + if (tcMap != null) + { + tcMap.clear(); + } } public org.omg.CORBA.ORB orb() { - if (orb == null) orb = org.omg.CORBA.ORB.init(new String[]{}, null); return orb; } @@ -384,26 +392,28 @@ (final boolean _littleEndian, final byte[] _buffer, final int _pos) { if (_littleEndian) + { return (((_buffer[_pos+3] & 0xff) << 24) + ((_buffer[_pos+2] & 0xff) << 16) + ((_buffer[_pos+1] & 0xff) << 8) + ((_buffer[_pos] & 0xff) << 0)); - else - return (((_buffer[_pos] & 0xff) << 24) + - ((_buffer[_pos+1] & 0xff) << 16) + - ((_buffer[_pos+2] & 0xff) << 8) + - ((_buffer[_pos+3] & 0xff) << 0)); + } + return (((_buffer[_pos] & 0xff) << 24) + + ((_buffer[_pos+1] & 0xff) << 16) + + ((_buffer[_pos+2] & 0xff) << 8) + + ((_buffer[_pos+3] & 0xff) << 0)); } private static final short _read2int (final boolean _littleEndian, final byte[] _buffer, final int _pos) { if (_littleEndian) + { return (short)(((_buffer[_pos+1] & 0xff) << 8) + ((_buffer[_pos] & 0xff) << 0)); - else - return (short)(((_buffer[_pos ] & 0xff) << 8) + - ((_buffer[_pos + 1] & 0xff) << 0)); + } + return (short)(((_buffer[_pos ] & 0xff) << 8) + + ((_buffer[_pos + 1] & 0xff) << 0)); } private final int _read_long() @@ -421,12 +431,10 @@ { if (littleEndian) { - return ((long) _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); - } - else - { - return ((long) _read_long() << 32) + ((long) _read_long() & 0xFFFFFFFFL); + return (_read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); } + + return ((long) _read_long() << 32) + (_read_long() & 0xFFFFFFFFL); } private final void handle_chunking() @@ -445,7 +453,7 @@ // tag is an end tag - if ( ! (-tag <= valueNestingLevel)) + if (-tag > valueNestingLevel) { throw new INTERNAL ( @@ -454,7 +462,7 @@ valueNestingLevel ); } - valueNestingLevel = - tag; + valueNestingLevel = -tag; valueNestingLevel--; if (valueNestingLevel > 0) @@ -463,17 +471,17 @@ handle_chunking(); } } - else if (tag < 0x7fffff00) + else if (tag > 0 && tag < 0x7fffff00) { // tag is the chunk size tag of another chunk chunk_end_pos = pos + tag; } - else // (tag >= 0x7fffff00) + else // (tag == 0 || tag >= 0x7fffff00) { - // tag is the value tag of a nested value + // tag is the null value tag or the value tag of a nested value - pos = saved_pos; // "unread" the value tag + pos = saved_pos; // "unread" the tag index = saved_index; } } @@ -503,7 +511,9 @@ int start = ei.start; if( pos < start + size ) + { pos = start + size; + } index = ei.index + size; } @@ -565,7 +575,7 @@ /* - * Return a copy of the current buffer. Currently only used by ProxyImpl. + * Return a copy of the current buffer. * * @return a byte[] value. */ @@ -596,10 +606,14 @@ throws java.io.IOException { if( closed ) + { throw new java.io.IOException("Stream already closed!"); + } if( available() < 1 ) + { return -1; + } ++index; return buffer[pos++]; // read_index++]; @@ -616,7 +630,7 @@ /** * Has the effect of read(b, 0, b.length); - * @see #read + * @see #read(byte[], int, int) */ public int read(final byte[] b) throws java.io.IOException @@ -678,33 +692,27 @@ { handle_chunking(); index++; - byte bb = buffer[pos++]; + byte value = buffer[pos++]; - if (bb == 0) + if (value == 0) { return false; } - else + + if (value == 1) { - if (bb == 1) - { - return true; - } - else - { - if (laxBooleanEncoding) - { - // Technically only valid values are 0 (false) and 1 (true) - // however some ORBs send values other than 1 for true. - return true; - } - else - { - throw new MARSHAL("Unexpected boolean value: " + bb - + " pos: " + pos + " index: " + index); - } - } + return true; + } + + if (laxBooleanEncoding) + { + // Technically only valid values are 0 (false) and 1 (true) + // however some ORBs send values other than 1 for true. + return true; } + + throw new MARSHAL("Unexpected boolean value: " + value + + " pos: " + pos + " index: " + index); } /** arrays */ @@ -734,17 +742,43 @@ } } + + /** + * read_char reads a character from the stream. + * + * @return a char value + */ public final char read_char() { handle_chunking(); + index++; - return (char)(0xff & buffer[pos++]); + return (char)(buffer[pos++] & 0xFF); } + + /** + * read_char_array reads an character array from the stream. + * + * @param value a char[], the result array. + * @param offset an int, an offset into value + * @param length an int, the length of the array to read + */ public final void read_char_array - (final char[] value, final int offset, final int length) + (final char[] value, final int offset, final int length) { + if (value == null) + { + throw new MARSHAL("Cannot marshall result into null array."); + } + else if ( offset + length > value.length || length < 0 || offset < 0 ) + { + throw new MARSHAL + ("Cannot marshall as indices for array are out bounds."); + } + handle_chunking(); + for (int j = offset; j < offset + length; j++) { index++; @@ -761,7 +795,9 @@ (final double[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -778,12 +814,32 @@ } } - public final java.math.BigDecimal read_fixed() + public final BigDecimal read_fixed() { handle_chunking(); - StringBuffer sb = new StringBuffer(); + final StringBuffer sb = new StringBuffer(); + + final int c = read_fixed_internal(sb); + + final java.math.BigDecimal result = + new java.math.BigDecimal( new java.math.BigInteger( sb.toString())); + + return read_fixed_negate(c, result); + } + + private BigDecimal read_fixed_negate(final int c, final java.math.BigDecimal result) + { + if( c == 0xD ) + { + return result.negate(); + } + + return result; + } + private int read_fixed_internal(StringBuffer sb) + { int b = buffer[pos++]; int c = b & 0x0F; // second half byte index++; @@ -791,23 +847,33 @@ while(true) { c = (b & 0xF0) >>> 4; - sb.append(c ); + sb.append(c); + c = b & 0x0F; if( c == 0xC || c == 0xD ) + { break; + } sb.append(c ); + b = buffer[pos++]; index++; } + return c; + } + + public final java.math.BigDecimal read_fixed(short digits, short scale) + { + handle_chunking(); - java.math.BigDecimal result = - new java.math.BigDecimal( new java.math.BigInteger( sb.toString())); + final StringBuffer sb = new StringBuffer(); - if( c == 0xD ) - return result.negate(); - else - return result; + final int c = read_fixed_internal(sb); + + final java.math.BigDecimal result = + new java.math.BigDecimal( new java.math.BigInteger( sb.toString()), scale); + return read_fixed_negate(c, result); } public final float read_float() @@ -819,7 +885,9 @@ (final float[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -860,7 +928,9 @@ (final int[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -894,19 +964,19 @@ if (littleEndian) { - return ((long) _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); - } - else - { - return ((long) _read_long() << 32) + ((long) _read_long() & 0xFFFFFFFFL); + return (_read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); } + + return ((long) _read_long() << 32) + (_read_long() & 0xFFFFFFFFL); } public final void read_longlong_array (final long[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -921,7 +991,7 @@ { for(int j=offset; j < offset+length; j++) { - value[j] = ( (long) _read_long() & 0xFFFFFFFFL) + + value[j] = ( _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); } } @@ -930,7 +1000,7 @@ for(int j=offset; j < offset+length; j++) { value[j] = ((long) _read_long() << 32) + - ((long) _read_long() & 0xFFFFFFFFL); + (_read_long() & 0xFFFFFFFFL); } } @@ -955,15 +1025,13 @@ { return null; } - else - { - return ((org.jacorb.orb.ORB)orb)._getObject( pior ); - } + + return ((org.jacorb.orb.ORB)orb)._getObject( pior ); } - public org.omg.CORBA.Object read_Object(final java.lang.Class clz) + public org.omg.CORBA.Object read_Object(final java.lang.Class clazz) { - if (org.omg.CORBA.portable.ObjectImpl.class.isAssignableFrom(clz)) + if (org.omg.CORBA.portable.ObjectImpl.class.isAssignableFrom(clazz)) { org.omg.CORBA.Object obj = read_Object(); if (obj instanceof org.omg.CORBA.portable.ObjectImpl) @@ -971,7 +1039,7 @@ org.omg.CORBA.portable.ObjectImpl stub = null; try { - stub = (org.omg.CORBA.portable.ObjectImpl)clz.newInstance(); + stub = (org.omg.CORBA.portable.ObjectImpl)clazz.newInstance(); } catch (InstantiationException e) { @@ -985,17 +1053,14 @@ ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate()); return stub; } - else - { - return obj; - } + return obj; } - else if (clz.isInterface() && - java.rmi.Remote.class.isAssignableFrom(clz)) + else if (clazz.isInterface() && + java.rmi.Remote.class.isAssignableFrom(clazz)) { return (org.omg.CORBA.Object) org.jacorb.util.ValueHandler.portableRemoteObject_narrow( - read_Object(), clz); + read_Object(), clazz); } else { @@ -1054,7 +1119,9 @@ (final short[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -1075,6 +1142,14 @@ index += length * 2; } + + /** + * read_string reads a string from the buffer. It is optimized + * for whether it is reading a blank string, and whether codeset translation + * is active. + * + * @return a String value, possibly blank, never null. + */ public final String read_string() { String result = null; @@ -1094,13 +1169,18 @@ index += (size + 4); pos += (size + 4); - String csname = CodeSet.csName(codeSet); + if ((size > 0) && (buffer[ start + size - 1 ] == 0)) { size --; } + // Optimize for empty strings. + if (size == 0) + { + return ""; + } if(start + size > buffer.length) { @@ -1111,40 +1191,79 @@ throw new MARSHAL ("Invalid size for string extraction"); } - try { - result = new String (buffer, start, size, csname); + if (codesetEnabled) + { + String csname = CodeSet.csName(codeSet); + + try + { + result = new String (buffer, start, size, csname); + } + catch (java.io.UnsupportedEncodingException ex) + { + if (logger != null && logger.isErrorEnabled()) + { + logger.error("Charset " + csname + " is unsupported"); + result = ""; + } + } } - catch (java.io.UnsupportedEncodingException ex) { - if (logger != null && logger.isErrorEnabled()) { - logger.error("Charset " + csname + " is unsupported"); - result = ""; + else + { + char[] buf = new char[size]; + + for (int i=0; iupdateTcMap is used during cached typecodes. As a cached + * typecode is being used we may miss placing markers for the recursive + * tcMap. Therefore, by recording the original typecodes start, and as we + * know the length it is possible find and calculate and extra positions + * that should be added. + * + * @param tcMap a Map value which may be updated. + * @param new_start an int value + * @param size an int value + * @param old_start an Integer value + */ + private void updateTcMap(final Map tcMap, + final int new_start, + final int size, + final Integer old_start ) + { + final SortedMap sortedMap = ((TreeMap)tcMap).subMap + ( old_start, ObjectUtil.newInteger( size + old_start.intValue() ) ); + + // If we have found anything between the original start position and the size. + if( sortedMap.size() > 0 ) + { + final TreeMap toMerge = new TreeMap(); + final Iterator iterator = sortedMap.entrySet().iterator(); + + while( iterator.hasNext() ) + { + final Map.Entry entry = (Map.Entry)iterator.next(); + + int value = ((Integer)entry.getKey()).intValue(); + // This calculation is the offset; the distance between the missing + // tc and the original start added onto the new start. + toMerge.put + ( + ObjectUtil.newInteger( new_start + (value - old_start.intValue() ) ), + entry.getValue() + ); + } + tcMap.putAll( toMerge ); + } + } + public final int read_ulong() { handle_chunking(); @@ -1574,7 +1821,9 @@ (final int[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -1607,19 +1856,19 @@ if (littleEndian) { - return ((long) _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); - } - else - { - return ((long) _read_long() << 32) + ((long) _read_long() & 0xFFFFFFFFL); + return (_read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); } + + return ((long) _read_long() << 32) + (_read_long() & 0xFFFFFFFFL); } public final void read_ulonglong_array (final long[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -1634,7 +1883,7 @@ { for (int j = offset; j < offset+length; j++) { - value[j] = ( (long) _read_long() & 0xFFFFFFFFL) + + value[j] = ( _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); } } @@ -1643,7 +1892,7 @@ for (int j = offset; j < offset+length; j++) { value[j] = ((long) _read_long() << 32) + - ((long) _read_long() & 0xFFFFFFFFL); + (_read_long() & 0xFFFFFFFFL); } } @@ -1671,7 +1920,9 @@ (final short[] value, final int offset, final int length) { if (length == 0) + { return; + } handle_chunking(); @@ -1705,10 +1956,8 @@ return read_wchar (wchar_little_endian); } - else - { - return read_wchar (littleEndian); - } + + return read_wchar (littleEndian); } /** @@ -1723,7 +1972,6 @@ return buffer[ pos++ ]; } - private final char read_wchar(final boolean wchar_little_endian) { switch( codeSetW ) @@ -1736,49 +1984,51 @@ " only allows 2 Byte encodings for wchar, but the selected TCSW is UTF-8" ); } - short b = (short) (0xff & buffer[pos++]); + short value = (short) (0xff & buffer[pos++]); index++; - if( (b & 0x80) == 0 ) + if( (value & 0x80) == 0 ) { - return (char) b; + return (char) value; } - else if( (b & 0xe0) == 0xc0 ) + else if( (value & 0xe0) == 0xc0 ) { index++; - return (char)(((b & 0x1F) << 6) | - ((short)buffer[pos++] & 0x3F)); + return (char)(((value & 0x1F) << 6) | + (buffer[pos++] & 0x3F)); } else { index += 2; short b2 = (short)(0xff & buffer[pos++]); - return (char)(( ( b & 0x0F) << 12) | + return (char)(( ( value & 0x0F) << 12) | ( (b2 & 0x3F) << 6) | - ( (short)buffer[pos++] & 0x3F)); + ( buffer[pos++] & 0x3F)); } } case CodeSet.UTF16 : { - char c; + char value; if( wchar_little_endian ) { - c = (char) ( (buffer[ pos++ ] & 0xFF) | + value = (char) ( (buffer[ pos++ ] & 0xFF) | (buffer[ pos++ ] << 8) ); } else { - c = (char) ( (buffer[ pos++ ] << 8) | + value = (char) ( (buffer[ pos++ ] << 8) | (buffer[ pos++ ] & 0xFF) ); } index += 2; - return c; + return value; + } + default: + { + throw new MARSHAL( "Bad CodeSet: " + codeSetW ); } } - - throw new MARSHAL( "Bad CodeSet: " + codeSetW ); } /** @@ -1790,11 +2040,6 @@ */ private final boolean readBOM() { - /* - if( !use_BOM ) - return false; - */ - if( (buffer[ pos ] == (byte) 0xFE) && (buffer[ pos + 1 ] == (byte) 0xFF) ) { @@ -1829,7 +2074,9 @@ { handle_chunking(); for(int j=offset; j < offset+length; j++) + { value[j] = read_wchar(); // inlining later... + } } public final String read_wstring() @@ -1930,7 +2177,9 @@ throws IOException { if( pos < 0 ) + { throw new MARSHAL("Mark has not been set!"); + } pos = marked_pos; index = marked_index; } @@ -1952,142 +2201,115 @@ * from this CDRInputStream, and remarshals it to the given OutputStream, * out. Called from Any. */ - final void read_value(final org.omg.CORBA.TypeCode tc, + final void read_value(final org.omg.CORBA.TypeCode typeCode, final org.omg.CORBA.portable.OutputStream out) { - if (tc == null) + if (typeCode == null) { throw new BAD_PARAM("TypeCode is null"); } - int kind = tc.kind().value(); + int kind = typeCode.kind().value(); try { switch (kind) { - case TCKind._tk_null: - case TCKind._tk_void: - break; - case TCKind._tk_boolean: - out.write_boolean( read_boolean()); - break; - case TCKind._tk_char: - out.write_char( read_char()); - break; - case TCKind._tk_wchar: - out.write_wchar( read_wchar()); - break; - case TCKind._tk_octet: - out.write_octet( read_octet()); - break; - case TCKind._tk_ushort: - out.write_ushort( read_ushort()); - break; - case TCKind._tk_short: - out.write_short( read_short()); - break; - case TCKind._tk_long: - out.write_long( read_long()); - break; - case TCKind._tk_ulong: - out.write_ulong( read_ulong()); - break; - case TCKind._tk_float: - out.write_float( read_float()); - break; - case TCKind._tk_double: - out.write_double( read_double()); - break; - case TCKind._tk_longlong: - out.write_longlong( read_longlong()); - break; - case TCKind._tk_ulonglong: - out.write_ulonglong( read_ulonglong()); - break; - case TCKind._tk_any: - out.write_any( read_any()); - break; - case TCKind._tk_TypeCode: - out.write_TypeCode( read_TypeCode()); - break; - case TCKind._tk_Principal: - throw new NO_IMPLEMENT ("Principal deprecated"); - case TCKind._tk_objref: - out.write_Object( read_Object()); - break; - case TCKind._tk_string: - out.write_string( read_string()); - break; - case TCKind._tk_wstring: - out.write_wstring( read_wstring()); - break; - case TCKind._tk_fixed: - out.write_fixed (read_fixed()); - break; - case TCKind._tk_array: + case TCKind._tk_null: // 0 + // fallthrough + case TCKind._tk_void: // 1 { - int length = tc.length(); - for( int i = 0; i < length; i++ ) - read_value( tc.content_type(), out ); break; } - case TCKind._tk_sequence: + case TCKind._tk_short: // 2 { - int len = read_long(); - out.write_long(len); - for( int i = 0; i < len; i++ ) - read_value( tc.content_type(), out ); + out.write_short( read_short()); break; } - case TCKind._tk_except: - out.write_string( read_string()); - // don't break, fall through to ... - case TCKind._tk_struct: + case TCKind._tk_long: // 3 { - for( int i = 0; i < tc.member_count(); i++) - read_value( tc.member_type(i), out ); + out.write_long( read_long()); break; } - case TCKind._tk_enum: - out.write_long( read_long() ); - break; - case TCKind._tk_alias: + case TCKind._tk_ushort: // 4 { - read_value( tc.content_type(), out ); + out.write_ushort( read_ushort()); break; } - case TCKind._tk_value_box: + case TCKind._tk_ulong: // 5 { - String id = tc.id(); - org.omg.CORBA.portable.BoxedValueHelper helper = - ((org.jacorb.orb.ORB)orb).getBoxedValueHelper(id); - if (helper == null) + out.write_ulong( read_ulong()); + break; + } + case TCKind._tk_float: // 6 + { + out.write_float( read_float()); + break; + } + case TCKind._tk_double: // 7 + { + out.write_double( read_double()); + break; + } + case TCKind._tk_boolean: // 8 + { + out.write_boolean( read_boolean()); + break; + } + case TCKind._tk_char: // 9 + { + out.write_char( read_char()); + break; + } + case TCKind._tk_octet: // 10 + { + out.write_octet( read_octet()); + break; + } + case TCKind._tk_any: // 11 + { + out.write_any( read_any()); + break; + } + case TCKind._tk_TypeCode: // 12 + { + out.write_TypeCode( read_TypeCode()); + break; + } + case TCKind._tk_Principal: // 13 + { + throw new NO_IMPLEMENT ("Principal deprecated"); + } + case TCKind._tk_objref: // 14 + { + out.write_Object( read_Object()); + break; + } + case TCKind._tk_struct: // 15 + { + for( int i = 0; i < typeCode.member_count(); i++) { - throw new MARSHAL ("No BoxedValueHelper for id " + id); + read_value( typeCode.member_type(i), out ); } - java.io.Serializable value = read_value(helper); - ((org.omg.CORBA_2_3.portable.OutputStream)out) - .write_value(value, helper); break; } - case TCKind._tk_union: + case TCKind._tk_union: // 16 { - org.omg.CORBA.TypeCode disc = tc.discriminator_type(); + org.omg.CORBA.TypeCode disc = typeCode.discriminator_type(); disc = TypeCode.originalType(disc); - int def_idx = tc.default_index(); + int def_idx = typeCode.default_index(); int member_idx = -1; switch( disc.kind().value() ) { - case TCKind._tk_short: + case TCKind._tk_short: // 2 { short s = read_short(); out.write_short(s); - for(int i = 0 ; i < tc.member_count() ; i++) + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_short()) + if(s == typeCode.member_label(i).extract_short()) { member_idx = i; break; @@ -2097,15 +2319,15 @@ break; } - case TCKind._tk_long: + case TCKind._tk_long: // 3 { int s = read_long(); out.write_long(s); - for(int i = 0 ; i < tc.member_count() ; i++) + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_long()) + if(s == typeCode.member_label(i).extract_long()) { member_idx = i; break; @@ -2114,15 +2336,15 @@ } break; } - case TCKind._tk_ushort: + case TCKind._tk_ushort: // 4 { short s = read_ushort(); out.write_ushort(s); - for(int i = 0 ; i < tc.member_count() ; i++) + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_ushort()) + if(s == typeCode.member_label(i).extract_ushort()) { member_idx = i; break; @@ -2132,15 +2354,15 @@ break; } - case TCKind._tk_ulong: + case TCKind._tk_ulong: // 5 { int s = read_ulong(); out.write_ulong(s); - for(int i = 0 ; i < tc.member_count() ; i++) + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_ulong()) + if(s == typeCode.member_label(i).extract_ulong()) { member_idx = i; break; @@ -2149,15 +2371,22 @@ } break; } - case TCKind._tk_longlong: + case TCKind._tk_float: // 6 + // fallthrough + case TCKind._tk_double: // 7 { - long s = read_longlong(); - out.write_longlong(s); - for(int i = 0 ; i < tc.member_count() ; i++) + throw new MARSHAL( + "Invalid union discriminator type: " + disc); + } + case TCKind._tk_boolean: // 8 + { + boolean b = read_boolean(); + out.write_boolean( b ); + for(int i = 0 ; i < typeCode.member_count() ; i++) { - if(i != def_idx) + if( i != def_idx) { - if(s == tc.member_label(i).extract_longlong()) + if( b == typeCode.member_label(i).extract_boolean() ) { member_idx = i; break; @@ -2166,15 +2395,15 @@ } break; } - case TCKind._tk_ulonglong: + case TCKind._tk_char: // 9 { - long s = read_ulonglong(); - out.write_ulonglong(s); - for(int i = 0 ; i < tc.member_count() ; i++) + char s = read_char(); + out.write_char(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_ulonglong()) + if(s == typeCode.member_label(i).extract_char()) { member_idx = i; break; @@ -2183,15 +2412,34 @@ } break; } - case TCKind._tk_char: + case TCKind._tk_octet: // 10 + // fallthrough + case TCKind._tk_any: // 11 + // fallthrough + case TCKind._tk_TypeCode: // 12 + // fallthrough + case TCKind._tk_Principal: // 13 + // fallthrough + case TCKind._tk_objref: // 14 + // fallthrough + case TCKind._tk_struct: // 15 + // fallthrough + case TCKind._tk_union: // 16 { - char s = read_char(); - out.write_char(s); - for(int i = 0 ; i < tc.member_count() ; i++) + throw new MARSHAL( + "Invalid union discriminator type: " + disc); + } + case TCKind._tk_enum: // 17 + { + int s = read_long(); + out.write_long(s); + for( int i = 0 ; i < typeCode.member_count() ; i++) { - if(i != def_idx) + if( i != def_idx) { - if(s == tc.member_label(i).extract_char()) + int label = + typeCode.member_label(i).create_input_stream().read_long(); + if(s == label) { member_idx = i; break; @@ -2200,15 +2448,28 @@ } break; } - case TCKind._tk_boolean: + case TCKind._tk_string: // 18 + // fallthrough + case TCKind._tk_sequence: // 19 + // fallthrough + case TCKind._tk_array: // 20 + // fallthrough + case TCKind._tk_alias: // 21 + // fallthrough + case TCKind._tk_except: // 22 { - boolean b = read_boolean(); - out.write_boolean( b ); - for(int i = 0 ; i < tc.member_count() ; i++) + throw new MARSHAL( + "Invalid union discriminator type: " + disc); + } + case TCKind._tk_longlong: // 23 + { + long s = read_longlong(); + out.write_longlong(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { - if( i != def_idx) + if(i != def_idx) { - if( b == tc.member_label(i).extract_boolean() ) + if(s == typeCode.member_label(i).extract_longlong()) { member_idx = i; break; @@ -2217,17 +2478,15 @@ } break; } - case TCKind._tk_enum: + case TCKind._tk_ulonglong: // 24 { - int s = read_long(); - out.write_long(s); - for( int i = 0 ; i < tc.member_count() ; i++) + long s = read_ulonglong(); + out.write_ulonglong(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { - if( i != def_idx) + if(i != def_idx) { - int label = - tc.member_label(i).create_input_stream().read_long(); - if(s == label) + if(s == typeCode.member_label(i).extract_ulonglong()) { member_idx = i; break; @@ -2237,35 +2496,119 @@ break; } default: - throw new MARSHAL("Invalid union discriminator type: " + disc); + { + throw new MARSHAL("Invalid union discriminator type: " + disc); + } } // switch if( member_idx != -1 ) { - read_value( tc.member_type( member_idx ), out ); + read_value( typeCode.member_type( member_idx ), out ); } else if( def_idx != -1 ) { - read_value( tc.member_type( def_idx ), out ); + read_value( typeCode.member_type( def_idx ), out ); } break; } - case 0xffffffff: + case TCKind._tk_enum: // 17 { - org.omg.CORBA.TypeCode _tc = - (org.omg.CORBA.TypeCode)(getRecursiveTCMap().get ( tc.id() )); - + out.write_long( read_long() ); + break; + } + case TCKind._tk_string: // 18 + { + out.write_string( read_string()); + break; + } + case TCKind._tk_sequence: // 19 + { + int len = read_long(); + out.write_long(len); + for( int i = 0; i < len; i++ ) + { + read_value( typeCode.content_type(), out ); + } + break; + } + case TCKind._tk_array: // 20 + { + int length = typeCode.length(); + for( int i = 0; i < length; i++ ) + { + read_value( typeCode.content_type(), out ); + } + break; + } + case TCKind._tk_alias: // 21 + { + read_value( typeCode.content_type(), out ); + break; + } + case TCKind._tk_except: // 22 + { + out.write_string( read_string()); - if( _tc == null ) + for( int i = 0; i < typeCode.member_count(); i++) { - throw new MARSHAL("No recursive TC found for " + tc.id()); + read_value( typeCode.member_type(i), out ); } - read_value( _tc , out ); + break; + } + case TCKind._tk_longlong: // 23 + { + out.write_longlong( read_longlong()); + break; + } + case TCKind._tk_ulonglong: // 24 + { + out.write_ulonglong( read_ulonglong()); + break; + } + case TCKind._tk_longdouble: // 25 + { + throw new org.omg.CORBA.BAD_TYPECODE( + "type longdouble not supported in java"); + } + case TCKind._tk_wchar: // 26 + { + out.write_wchar( read_wchar()); + break; + } + case TCKind._tk_wstring: // 27 + { + out.write_wstring( read_wstring()); + break; + } + case TCKind._tk_fixed: // 28 + { + out.write_fixed (read_fixed()); + break; + } + case TCKind._tk_value: // 29 + { + Serializable val = read_value(); + ((org.omg.CORBA_2_3.portable.OutputStream)out).write_value(val, typeCode.id()); + break; + } + case TCKind._tk_value_box: // 30 + { + String id = typeCode.id(); + org.omg.CORBA.portable.BoxedValueHelper helper = + ((org.jacorb.orb.ORB)orb).getBoxedValueHelper(id); + if (helper == null) + { + throw new MARSHAL ("No BoxedValueHelper for id " + id); + } + java.io.Serializable value = read_value(helper); + ((org.omg.CORBA_2_3.portable.OutputStream)out).write_value(value, helper); break; } default: - throw new MARSHAL("Cannot handle TypeCode with kind " + kind); + { + throw new MARSHAL("Cannot handle TypeCode with kind " + kind); + } } } catch (BadKind ex) @@ -2280,7 +2623,6 @@ } } - public java.io.Serializable read_value() { int tag = read_long(); @@ -2304,7 +2646,9 @@ tag = tag & 0xfffffff6; if (tag == 0x7fffff00) + { throw new MARSHAL ("missing value type information"); + } else if (tag == 0x7fffff02) { return read_typed_value(start_offset, codebase); @@ -2314,20 +2658,21 @@ return read_multi_typed_value( start_offset, codebase ); } else + { throw new MARSHAL("unknown value tag: 0x" + Integer.toHexString(theTag) + " (offset=0x" + Integer.toHexString(start_offset) + ")"); + } } /** * Overrides read_value(java.io.Serializable value) in * org.omg.CORBA_2_3.portable.InputStream */ - public java.io.Serializable read_value(final String rep_id) { int tag = read_long(); - int start_offset = pos - 4; + final int start_offset = pos - 4; if (tag == 0xffffffff) { @@ -2340,7 +2685,7 @@ return null; } - String codebase = ((tag & 1) != 0) ? read_codebase() : null; + final String codebase = ((tag & 1) != 0) ? read_codebase() : null; chunkedValue = ((tag & 8) != 0); int theTag = tag; @@ -2380,7 +2725,6 @@ * Overrides read_value(value) in * org.omg.CORBA_2_3.portable.InputStream */ - public java.io.Serializable read_value(java.io.Serializable value) { if (value instanceof org.omg.CORBA.portable.Streamable) @@ -2430,8 +2774,8 @@ if (tag == 0x7fffff00) { - return read_untyped_value ( new String[]{ ValueHandler.getRMIRepositoryID(clz) }, - start_offset, codebase); + return read_untyped_value (new String[]{ValueHandler.getRMIRepositoryID(clz)}, + start_offset, codebase); } else if (tag == 0x7fffff02) { @@ -2444,8 +2788,10 @@ else { throw new MARSHAL("unknown value tag: 0x" + - Integer.toHexString(theTag) + " (offset=0x" + - Integer.toHexString(start_offset) + ")"); + Integer.toHexString(theTag) + + " (offset=0x" + + Integer.toHexString(start_offset) + + ")"); } } @@ -2453,8 +2799,6 @@ * Overrides read_value(factory) in * org.omg.CORBA_2_3.portable.InputStream */ - - public java.io.Serializable read_value (final org.omg.CORBA.portable.BoxedValueHelper factory) { @@ -2484,7 +2828,7 @@ if( result != null ) { - getValueMap().put (new Integer(start_offset), result); + getValueMap().put(ObjectUtil.newInteger(start_offset), result); } return result; @@ -2498,9 +2842,11 @@ return read_typed_value(start_offset, codebase); } else + { throw new MARSHAL("unknown value tag: 0x" + Integer.toHexString(theTag) + " (offset=0x" + Integer.toHexString(start_offset) + ")"); + } } /** @@ -2510,71 +2856,52 @@ * `index'. */ private java.io.Serializable read_untyped_value(final String[] repository_ids, - final int index, - final String codebase) + final int index, + final String codebase) { java.io.Serializable result = null; if (chunkedValue || valueNestingLevel > 0) { valueNestingLevel++; - int chunk_size_tag = readChunkSizeTag(); - chunk_end_pos = pos + chunk_size_tag; + readChunkSizeTag(); } - for (int r = 0; r < repository_ids.length; r++) + for (int i = 0; i < repository_ids.length; i++) { - if (repository_ids[r].equals("IDL:omg.org/CORBA/WStringValue:1.0")) + if (repository_ids[i].equals("IDL:omg.org/CORBA/WStringValue:1.0")) { // special handling of strings, according to spec result = read_wstring(); break; } - else if (repository_ids[r].startsWith("RMI:javax.rmi.CORBA.ClassDesc:")) + else if (repository_ids[i].startsWith("RMI:javax.rmi.CORBA.ClassDesc:")) { // special handling of java.lang.Class instances - String classCodebase = (String)read_value(String.class); - String reposId = (String)read_value(String.class); - String className = + final String classCodebase = (String)read_value(String.class); + final String reposId = (String)read_value(String.class); + final String className = org.jacorb.ir.RepositoryID.className(reposId, null); - ClassLoader ctxcl = - Thread.currentThread().getContextClassLoader(); try { - if (ctxcl != null) - { - try - { - result = ctxcl.loadClass(className); - } - catch (ClassNotFoundException cnfe) - { - result = ValueHandler.loadClass(className, - classCodebase, - null); - } - } - else - { - result = ValueHandler.loadClass(className, - classCodebase, - null); - } + result = loadClass(className, classCodebase); } catch (ClassNotFoundException e) { - if( r < repository_ids.length-1 ) + if( i < repository_ids.length-1 ) + { continue; - else - throw new MARSHAL("class not found: " + className); + } + + throw new MARSHAL("class not found: " + className); } break; } - else if (repository_ids[r].startsWith ("IDL:")) + else if (repository_ids[i].startsWith ("IDL:")) { org.omg.CORBA.portable.ValueFactory factory = - ((org.omg.CORBA_2_3.ORB)orb()).lookup_value_factory (repository_ids[r]); + ((org.omg.CORBA_2_3.ORB)orb()).lookup_value_factory (repository_ids[i]); if (factory != null) { @@ -2582,78 +2909,49 @@ result = factory.read_value (this); break; } - else + + if( i < repository_ids.length-1 ) { - if( r < repository_ids.length-1 ) - continue; - else - throw new MARSHAL ("No factory found for: " + repository_ids[0] ); + continue; } + + throw new MARSHAL ("No factory found for: " + repository_ids[0] ); } else // RMI { - // Load the value's class, using the context class loader - // of the current thread if possible. Here's Francisco - // Reverbel's explanation of why - // this is needed in JBoss: - - // "It seems that ValueHandler.loadClass() uses the thread - // context classloader only after it looks for other - // classloaders in the call stack (weird). In some - // situations (when EJBs are undeployed and then - // redeployed) it finds in the call stack a classloader - // used for an undeployed EJB. A value of class Foo is - // then unmarshalled with type - // classloaderOfEJB1:Foo, when the expected type is - // classloaderOfEJB2:Foo. I am getting ClassCastExceptions is this - // situation. - // Explicitly using the thread context class loader in the - // first place solves the problem." - - String className = - org.jacorb.ir.RepositoryID.className(repository_ids[r], null); - - Class c = null; - //#ifjdk 1.2 - ClassLoader ctxcl = Thread.currentThread().getContextClassLoader(); - //#else - //# ClassLoader ctxcl = null; - //#endif + final String className = + org.jacorb.ir.RepositoryID.className(repository_ids[i], null); + try { - if (ctxcl != null) - { - try - { - c = ctxcl.loadClass(className); - } - catch (ClassNotFoundException cnfe) - { - c = ValueHandler.loadClass(className, codebase, null); - } - } - else - { - c = ValueHandler.loadClass(className, codebase, null); - } + final Class clazz = loadClass(className, codebase); - if (IDLEntity.class.isAssignableFrom(c)) + if (IDLEntity.class.isAssignableFrom(clazz)) { java.lang.reflect.Method readMethod = null; - if (c != org.omg.CORBA.Any.class) + if (clazz != org.omg.CORBA.Any.class) { - String helperClassName = c.getName() + "Helper"; + String helperClassName = clazz.getName() + "Helper"; try { - Class helperClass = - c.getClassLoader().loadClass( - helperClassName); + final ClassLoader classLoader = clazz.getClassLoader(); + final Class helperClass; + if (classLoader == null) + { + helperClass = ObjectUtil.classForName(helperClassName); + } + else + { + helperClass = + classLoader.loadClass(helperClassName); + } + Class[] paramTypes = { org.omg.CORBA.portable.InputStream.class }; readMethod = - helperClass.getMethod("read", paramTypes); + helperClass.getMethod("read", paramTypes); } catch (ClassNotFoundException e) { @@ -2692,52 +2990,100 @@ } } else - result = ValueHandler.readValue(this, index, c, - repository_ids[r], + { + result = ValueHandler.readValue(this, index, clazz, + repository_ids[i], null); + } } catch (ClassNotFoundException e) { - if( r < repository_ids.length-1 ) + if( i < repository_ids.length-1 ) + { continue; - else - throw new MARSHAL ("class not found: " + className); - } + } + throw new MARSHAL ("class not found: " + className); + } } } // value type instances may be null... if( result != null ) { - getValueMap().put (new Integer (index), result); + getValueMap().put(ObjectUtil.newInteger(index), result); } return result; } + /** Load the value's class, using the context class loader + * of the current thread if possible. Here's Francisco + * Reverbel's explanation of why + * this is needed in JBoss: + * + * "It seems that ValueHandler.loadClass() uses the thread + * context classloader only after it looks for other + * classloaders in the call stack (weird). In some + * situations (when EJBs are undeployed and then + * redeployed) it finds in the call stack a classloader + * used for an undeployed EJB. A value of class Foo is + * then unmarshalled with type + * classloaderOfEJB1:Foo, when the expected type is + * classloaderOfEJB2:Foo. I am getting ClassCastExceptions is this + * situation. + * Explicitly using the thread context class loader in the + * first place solves the problem." + */ + private Class loadClass(String className, final String codebase) throws ClassNotFoundException + { + Class clazz; + //#ifjdk 1.2 + ClassLoader clazzLoader = Thread.currentThread().getContextClassLoader(); + //#else + //# ClassLoader ctxcl = null; + //#endif + + if (clazzLoader == null) + { + clazz = ValueHandler.loadClass(className, codebase, null); + } + else + { + try + { + clazz = clazzLoader.loadClass(className); + } + catch (ClassNotFoundException e) + { + clazz = ValueHandler.loadClass(className, codebase, null); + } + } + return clazz; + } + /** * try to read in the chunk size. * special handling if there's no chunk size * in the stream. */ - private int readChunkSizeTag() + private void readChunkSizeTag() { int savedPos = pos; int savedIndex = index; int chunk_size_tag = read_long(); - if (!sunInteropFix || chunk_size_tag > 0 && chunk_size_tag < max_block_size) + if (!sunInteropFix || chunk_size_tag > 0 && chunk_size_tag < MAX_BLOCK_SIZE) { - // looks like the correct chunk size - return chunk_size_tag; + // valid chunk size: set the ending position of the chunk + chunk_end_pos = pos + chunk_size_tag; } - else + else { - // reset buffer - pos = savedPos; - index = savedIndex; - return max_block_size; + // reset buffer and remember that we're not within a chunk + pos = savedPos; + index = savedIndex; + chunk_end_pos = -1; } } @@ -2746,7 +3092,6 @@ * by a single RepositoryID. It is assumed that the tag and the codebase * of the value have already been read. */ - private java.io.Serializable read_typed_value( final int index, final String codebase) { @@ -2758,7 +3103,6 @@ * by an array of RepositoryIDs. It is assumed that the tag and the codebase * of the value have already been read. */ - private java.io.Serializable read_multi_typed_value( final int index, final String codebase) { @@ -2766,7 +3110,9 @@ String[] ids = new String[ id_count ]; for( int i = 0; i < id_count; i++ ) + { ids[i] = read_repository_id(); + } return read_untyped_value (ids, index, codebase); } @@ -2785,23 +3131,22 @@ int index = read_long(); index = index + pos - 4; - String repId = (String)getRepIdMap().get (new Integer(index)); + String repId = (String)getRepIdMap().get(ObjectUtil.newInteger(index)); if (repId == null) + { throw new MARSHAL("stale RepositoryID indirection"); - else - return repId; - } - else - { - // a new id - pos -= 4; - index -= 4; - int start_offset = pos; - String repId = read_string(); - - getRepIdMap().put (new Integer(start_offset), repId); + } return repId; } + + // a new id + pos -= 4; + index -= 4; + int start_offset = pos; + String repId = read_string(); + + getRepIdMap().put(ObjectUtil.newInteger(start_offset), repId); + return repId; } /** @@ -2817,23 +3162,22 @@ // indirection int index = read_long(); index = index + pos - 4; - String codebase = (String)getCodebaseMap().get (new Integer(index)); + String codebase = (String)getCodebaseMap().get(ObjectUtil.newInteger(index)); if (codebase == null) + { throw new MARSHAL("stale codebase indirection"); - else - return codebase; - } - else - { - // a new codebase string - pos -= 4; - index -= 4; - int start_offset = pos; - String codebase = read_string(); - getCodebaseMap().put (new Integer(start_offset), codebase); + } + return codebase; } + // a new codebase string + pos -= 4; + index -= 4; + int start_offset = pos; + String codebase = read_string(); + getCodebaseMap().put (ObjectUtil.newInteger(start_offset), codebase); + return codebase; } /** @@ -2845,9 +3189,10 @@ // indirection int index = read_long(); index = index + pos - 4; - java.lang.Object value = getValueMap().get (new Integer(index)); - if (value == null) { + java.lang.Object value = getValueMap().get (ObjectUtil.newInteger(index)); + if (value == null) + { // Java to IDL Language Mapping, v1.1, page 1-44: // // "The ValueHandler object may receive an IndirectionException @@ -2864,11 +3209,11 @@ throw new org.omg.CORBA.portable.IndirectionException (index); } - else - return (java.io.Serializable)value; + + return (java.io.Serializable)value; } - private String validateName (String name) + private String validateName(String name) { if (name != null && name.length() == 0) { @@ -2877,16 +3222,15 @@ return name; } - private String validateID (String id) + private String validateID(String id) { if (id == null || id.length() == 0) { - id = "IDL:"; + return "IDL:"; } return id; } - /** * Reads an abstract interface from this stream. The abstract interface * Reads an abstract interface from this stream. The abstract interface @@ -2894,7 +3238,6 @@ * union contains a CORBA object reference, or false if the union contains * a value. */ - public java.lang.Object read_abstract_interface() { return read_boolean() ? (java.lang.Object)read_Object() @@ -2907,14 +3250,12 @@ * union contains a CORBA object reference, or false if the union contains * a value. */ - - public java.lang.Object read_abstract_interface(final java.lang.Class clz) + public java.lang.Object read_abstract_interface(final java.lang.Class clazz) { - return read_boolean() ? (java.lang.Object)read_Object(clz) - : (java.lang.Object)read_value(clz); + return read_boolean() ? (java.lang.Object)read_Object(clazz) + : (java.lang.Object)read_value(clazz); } - public int get_pos() { return pos; @@ -2926,9 +3267,46 @@ * store an object into the map before actually reading its state. * This is essential for unmarshalling recursive values. */ - public void register_value(final java.io.Serializable value) { - getValueMap().put(new Integer(currentValueIndex), value); + getValueMap().put(ObjectUtil.newInteger(currentValueIndex), value); + } + + /** + * Pair is merely a private storage class used by + * {@link #cachedTypecodes}. + */ + private static final class Pair + { + /** + * first is the typecode we are caching. + */ + public final org.omg.CORBA.TypeCode typeCode; + /** + * second is the location the original typecode was found. + */ + public final Integer position; + + /** + * Create a new Pair. + * + * @param typeCode an org.omg.CORBA.TypeCode value + * @param position an Integer value + */ + public Pair( org.omg.CORBA.TypeCode typeCode, Integer position ) + { + this.typeCode = typeCode; + this.position = position; + } + + /** + * toString used for debugging ONLY. + * + * @return a String value + */ + public String toString() + { + return (typeCode + " and " + position ); + } } } Index: src/org/jacorb/orb/CDROutputStream.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/CDROutputStream.java,v retrieving revision 1.106 diff -u -r1.106 CDROutputStream.java --- src/org/jacorb/orb/CDROutputStream.java 17 May 2006 13:14:37 -0000 1.106 +++ src/org/jacorb/orb/CDROutputStream.java 5 May 2007 00:36:08 -0000 @@ -21,20 +21,23 @@ */ import java.io.*; +import java.math.BigDecimal; import java.util.*; import org.apache.avalon.framework.configuration.*; import org.jacorb.ir.RepositoryID; import org.jacorb.orb.giop.CodeSet; +import org.jacorb.orb.giop.GIOPConnection; import org.jacorb.util.ValueHandler; import org.jacorb.util.ObjectUtil; import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.CODESET_INCOMPATIBLE; +import org.omg.CORBA.DATA_CONVERSION; +import org.omg.CORBA.INTERNAL; import org.omg.CORBA.MARSHAL; import org.omg.CORBA.NO_IMPLEMENT; -import org.omg.CORBA.INTERNAL; import org.omg.CORBA.TCKind; import org.omg.CORBA.TypeCodePackage.BadKind; import org.omg.CORBA.TypeCodePackage.Bounds; @@ -44,7 +47,7 @@ /** * @author Gerald Brose, 1999 - * @version $Id: CDROutputStream.java,v 1.106 2006/05/17 13:14:37 alphonse.bendt Exp $ + * @version $Id: CDROutputStream.java,v 1.123 2007/04/26 23:07:26 francisco Exp $ * * A stream for CDR marshalling. * @@ -83,13 +86,6 @@ */ private Stack encaps_stack; - /** - * recursiveTCMap is used to remember the original TCs for a - * given ID that is used in a recursive/repeated TC. Do NOT access this - * variable directly. It is initialised on demand. Use the method - * {@link #getRecursiveTCMap() getRecursiveTCMap()} - */ - private Map recursiveTCMap; /** * valueMap is used to maps all value objects that have @@ -124,6 +120,18 @@ */ private Map cachedTypecodes; + /** + * This Map is basically a one-entry map pool to be used in + * write_TypeCode() as the repeatedTCMap. + */ + private Map repeatedTCMap; + + /** + * This Map is basically a one-entry map pool to be used in + * write_TypeCode() as the recursiveTCMap. + */ + private Map recursiveTCMap; + /** Remembers the starting position of the current chunk. */ private int chunk_size_tag_pos = -1; // -1 means we're not within a chunk private int chunk_size_tag_index; @@ -138,7 +146,7 @@ /** True if write_value_internal called writeReplace */ private boolean writeReplaceCalled = false; - private List deferredArrayQueue = new ArrayList(); + private final List deferredArrayQueue = new ArrayList(); private org.omg.CORBA.ORB orb = null; @@ -148,6 +156,11 @@ to be bitwise or'ed into value tags. */ private int chunkingFlag = 0; + /** + * codesetEnabled denotes whether codeset marshalling is enabled. + */ + private boolean codesetEnabled; + /** configurable properties */ private boolean useBOM = false; private boolean chunkCustomRmiValuetypes = false; @@ -164,8 +177,10 @@ */ public void configure(Configuration configuration) - throws ConfigurationException { + codesetEnabled = + configuration.getAttribute("jacorb.codeset","on").equals("on"); + useBOM = configuration.getAttribute("jacorb.use_bom","off").equals("on"); @@ -176,6 +191,7 @@ useIndirection = !( configuration.getAttribute("jacorb.interop.indirection_encoding_disable","off").equals("on")); + } private static class DeferredWriteFrame @@ -188,6 +204,8 @@ public DeferredWriteFrame( int write_pos, int start, int length, byte[] buf ) { + super(); + this.write_pos = write_pos; this.start = start; this.length = length; @@ -205,6 +223,7 @@ public CDROutputStream() { + super(); bufMgr = BufferManager.getInstance(); // the BufferManager will be configured by now! buffer = bufMgr.getPreferredMemoryBuffer(); } @@ -220,14 +239,7 @@ if (orb != null ) { this.orb = orb; - try - { - configure(((org.jacorb.orb.ORB)orb).getConfiguration()); - } - catch( ConfigurationException ce ) - { - throw new INTERNAL("ConfigurationException: " + ce); - } + configure(((org.jacorb.orb.ORB)orb).getConfiguration()); } } @@ -240,6 +252,8 @@ public CDROutputStream(final byte[] buf) { + super(); + bufMgr = BufferManager.getInstance(); buffer = buf; } @@ -271,21 +285,6 @@ /** - * Gets the Map that is used to store recursive TypeCodes. - * - * @return a Map value - */ - private Map getRecursiveTCMap() - { - if (recursiveTCMap == null) - { - recursiveTCMap = new HashMap(); - } - return recursiveTCMap; - } - - - /** * Gets the Map that is used to detect reference sharing when * marshaling valuetype instances. * @@ -295,7 +294,7 @@ { if (valueMap == null) { - valueMap = ObjectUtil.createIdentityHashMap(); + valueMap = new IdentityHashMap(); } return valueMap; } @@ -352,7 +351,7 @@ DeferredWriteFrame next_frame = null; - if( deferredArrayQueue != null && deferredArrayQueue.size() > 0 ) + if(deferredArrayQueue.size() > 0 ) { // find the first frame that falls within the current window, // i.e. that need s to be written @@ -376,7 +375,6 @@ while( write_idx < start + length ) { - if( next_frame != null && write_idx == next_frame.write_pos ) { if ( ! (next_frame.length <= start + length - write_idx)) @@ -394,8 +392,7 @@ next_frame = null; // and look up the next frame - if( deferredArrayQueue != null && - list_idx < deferredArrayQueue.size() ) + if(list_idx < deferredArrayQueue.size() ) { next_frame = (DeferredWriteFrame)deferredArrayQueue.get( list_idx++ ); if( next_frame.write_pos > start + length ) @@ -454,10 +451,7 @@ buffer = null; closed = true; - if (deferredArrayQueue != null) - { - deferredArrayQueue.clear(); - } + deferredArrayQueue.clear(); deferred_writes = 0; } @@ -508,11 +502,9 @@ private final void check(final int i) { - byte [] new_buf; - if (buffer == null || (pos + i + 2) > buffer.length) { - new_buf = bufMgr.getBuffer( pos+i+2, true); + final byte[] new_buf = bufMgr.getBuffer( pos+i+2, true); if (buffer != null) { @@ -522,7 +514,6 @@ bufMgr.returnBuffer (buffer, true); buffer = new_buf; - new_buf = null; } } @@ -573,7 +564,7 @@ // set up new indirection maps for this encapsulation - valueMap = ObjectUtil.createIdentityHashMap(); + valueMap = new IdentityHashMap(); repIdMap = new HashMap(); codebaseMap = new HashMap(); @@ -609,7 +600,10 @@ public final void endEncapsulation() { if( encaps_start == -1 ) + { throw new MARSHAL("Too many end-of-encapsulations"); + } + if( encaps_stack == null ) { throw new MARSHAL("Internal Error - closeEncapsulation failed"); @@ -638,16 +632,16 @@ public byte[] getBufferCopy() { - ByteArrayOutputStream bos = - new ByteArrayOutputStream(); + final ByteArrayOutputStream bos = + new ByteArrayOutputStream(size()); try { write( bos, 0, size()); } - catch( IOException io ) + catch( IOException e ) { - // Debug.output(1, io ); + throw new INTERNAL("should not happen: " + e.toString()); } return bos.toByteArray(); @@ -665,10 +659,7 @@ public void reset() { - if (deferredArrayQueue != null) - { - deferredArrayQueue.clear(); - } + deferredArrayQueue.clear(); pos = 0; deferred_writes = 0; index = 0; @@ -745,12 +736,10 @@ } return new CDRInputStream(orb(), baos.toByteArray()); } - else - { - byte[] result = new byte[index + 1]; - System.arraycopy(buffer, 0, result, 0, result.length); - return new CDRInputStream(orb, result); - } + + byte[] result = new byte[index + 1]; + System.arraycopy(buffer, 0, result, 0, result.length); + return new CDRInputStream(orb, result); } public final void write_any(final org.omg.CORBA.Any value) @@ -764,9 +753,13 @@ check(1); if( value ) + { buffer[pos++] = 1; + } else + { buffer[pos++] = 0; + } index++; } @@ -781,9 +774,13 @@ for( int i = offset; i < offset+length; i++ ) { if( value[i] ) + { buffer[pos++] = 1; + } else + { buffer[pos++] = 0; + } } index += length; } @@ -791,83 +788,114 @@ /** - * Writes char according to specified encoding. + * write_char writes a character to the output stream. If + * codeset translation is active then it will use String and an encoding to + * get the bytes. It can then do a test for whether to throw DATA_CONVERSION. + * + * @param c a char value */ - public final void write_char(final char c) + public final void write_char (final char c) { - check( 1 ); - - int too_large_mask = - (codeSet == CodeSet.ISO8859_1)? - 0xFF00 : //ISO8859-1 - 0xFF80; //UTF-8 - - if( (c & too_large_mask) != 0 )//Are there any 1s in the MSB? - { - throw new org.omg.CORBA.DATA_CONVERSION( - "char (" + c + - ") out of range for " + - CodeSet.csName( codeSet) ); + // According to 15.3.1.6 of CORBA 3.0 'a single instance of the char type + // may only hold one octet of any multi-byte character encoding.' + // Therefore we ensure that we are in the single byte range i.e. + // less than 0xFF or \377. + if (c > '\377') + { + throw new DATA_CONVERSION ("Char " + c + " out of range"); } + check( 1 ); + buffer[pos++] = (byte)c; index++; - buffer[ pos++ ] = (byte) c; } + public final void write_char_array (final char[] value, final int offset, final int length) { if( value == null ) - throw new MARSHAL( "Null References" ); + { + throw new MARSHAL("Cannot marshall null array."); + } + else if ( offset + length > value.length || length < 0 || offset < 0 ) + { + throw new MARSHAL + ("Cannot marshall as indices for array are out bounds."); + } - //no alignment necessary check( length ); - int too_large_mask = - (codeSet == CodeSet.ISO8859_1)? - 0xFF00 : //ISO8859-1 - 0xFF80; //UTF-8 - - - for( int i = offset; i < offset+length; i++) + for (int i=offset; i < length+offset; i++) { - if( (value[i] & too_large_mask) != 0 ) + if (value[i] > '\377') { - throw new MARSHAL("char (" + value[i] + - ") out of range for " + - CodeSet.csName( codeSet )); + throw new DATA_CONVERSION ("Char " + value[i] + " out of range"); } - - buffer[ pos++ ] = (byte) value[i]; + buffer[pos++] = (byte)value[i]; } - - index += length; + index+=length; } + + /** + * write_string writes a string to the output stream. It is + * optimised for whether it is writing a blank string or for whether codeset + * translation is active. + * + * @param s a String value + */ public final void write_string(final String s) { + // size leaves room for ulong, plus the string itself (one or more + // bytes per char in the string, depending on the codeset), plus the + // terminating NUL char + int size; + // sizePosition is the position in the buffer for the size to be + // written. + int sizePosition; + if( s == null ) { - throw new MARSHAL("Null References"); + throw new MARSHAL("Cannot marshall null string."); } - // size indicator ulong + length in chars( i.e. bytes for type char) - // incl. terminating NUL char - int size = 4 + s.length() + 1; - check( size, 4 ); + if (codesetEnabled) + { + // in the worst case (UTF-8) a string char might take up to 3 bytes + size = 4 + 3 * s.length() + 1; + } + else + { + // just one byte per string char + size = 4 + s.length() + 1; + } + check(size, 4); + sizePosition = pos; - int sizepos = pos; pos += 4; index += 4; - char ch; for (int i = 0; i < s.length(); i++) - write_char_i(s.charAt(i),false,false, codeSet); + { + if (codesetEnabled) + { + write_char_i(s.charAt(i),false,false, codeSet); + } + else + { + buffer[pos++] = (byte)s.charAt(i); + index++; + } + } buffer[ pos++ ] = (byte) 0; //terminating NUL char index ++; - size = pos - (sizepos + 4); // compute translated size - _write4int( buffer,sizepos,size); + + // Now write the size back in. + size = pos - (sizePosition + 4); // compute translated size + + _write4int( buffer, sizePosition, size); } public final void write_wchar(final char c) @@ -898,10 +926,11 @@ if( giop_minor == 2 && write_length_indicator ) { //the chars length in bytes - write_octet( (byte) 1 ); + buffer[pos++] = (byte) 1; + index++; } - buffer[ pos++ ] = (byte) c; + buffer[pos++] = (byte) c; index++; } else if( c > 0x07FF ) @@ -909,7 +938,8 @@ if( giop_minor == 2 && write_length_indicator ) { //the chars length in bytes - write_octet( (byte) 3 ); + buffer[pos++] = (byte) 3; + index++; } buffer[pos++]=(byte)(0xE0 | ((c >> 12) & 0x0F)); @@ -923,7 +953,8 @@ if( giop_minor == 2 && write_length_indicator ) { //the chars length in bytes - write_octet( (byte) 2 ); + buffer[pos++] = (byte) 2 ; + index++; } buffer[pos++]=(byte)(0xC0 | ((c >> 6) & 0x1F)); @@ -940,7 +971,8 @@ if( write_length_indicator ) { //the chars length in bytes - write_octet( (byte) 2 ); + buffer[pos++] = (byte) 2; + index++; } if( write_bom ) @@ -976,12 +1008,16 @@ (final char[] value, final int offset, final int length) { if( value == null ) + { throw new MARSHAL("Null References"); + } check( length * 3 ); for( int i = offset; i < offset+length; i++) + { write_wchar( value[i] ); + } } public final void write_wstring(final String s) @@ -1083,13 +1119,14 @@ } } + public final void write_fixed(BigDecimal value, short digits, short scale) + { + write_fixed(value); + } + public final void write_fixed(final java.math.BigDecimal value) { - //#ifjdk 1.2 String v = value.unscaledValue().toString(); - //#else - //# String v = value.movePointRight(value.scale()).toString(); - //#endif byte [] representation; int b, c; @@ -1133,7 +1170,6 @@ System.arraycopy(representation,0,buffer,pos,representation.length); index += representation.length; pos += representation.length; - } public final void write_float(final float value) @@ -1257,7 +1293,6 @@ public void write_Object(final org.omg.CORBA.Object value) { - if( value == null ) { IORHelper.write(this, null_ior ); @@ -1265,10 +1300,15 @@ else { if( value instanceof org.omg.CORBA.LocalObject ) + { throw new MARSHAL("Attempt to serialize a locality-constrained object."); + } org.omg.CORBA.portable.ObjectImpl obj = (org.omg.CORBA.portable.ObjectImpl)value; - IORHelper.write(this, ((Delegate)obj._get_delegate()).getIOR() ); + + IOR intermediary = ((Delegate)obj._get_delegate()).getIOR(); + + IORHelper.write(this, intermediary); } } @@ -1362,332 +1402,557 @@ } } - public final void write_TypeCode (org.omg.CORBA.TypeCode value) + public final void write_TypeCode (org.omg.CORBA.TypeCode typeCode) { - String id = null; - org.omg.CORBA.TypeCode cached = null; - - try - { - // Get the id for this typecode. - id = value.id(); - } - // Masking on purpose as only determining whether to cache here. - catch (BadKind e) - { - } - - if (compactTypeCodes > 0 && id != null) + if (compactTypeCodes > 0) { - if (cachedTypecodes == null) + final String id; + try { - cachedTypecodes = new HashMap(); + switch (typeCode.kind().value()) + { + case TCKind._tk_objref: //14 + case TCKind._tk_struct: //15 + case TCKind._tk_union: //16 + case TCKind._tk_enum: //17 + { + id = typeCode.id(); + break; + } + case TCKind._tk_string: //18 + case TCKind._tk_sequence: //19 + case TCKind._tk_array: //20 + { + id = null; + break; //dummy cases for optimized switch + } + case TCKind._tk_alias: //21 + case TCKind._tk_except: //22 + { + id = typeCode.id(); + break; + } + case TCKind._tk_longlong: // 23 + case TCKind._tk_ulonglong: // 24 + case TCKind._tk_longdouble:// 25 + case TCKind._tk_wchar: // 26 + case TCKind._tk_wstring: // 27 + case TCKind._tk_fixed: // 28 + { + id = null; + break; //dummy cases for optimized switch + } + case TCKind._tk_value: // 29 + case TCKind._tk_value_box: // 30 + { + id = typeCode.id(); + break; + } + case TCKind._tk_native: // 31 + { + id = null; + break; //dummy cases for optimized switch + } + case TCKind._tk_abstract_interface: //32 + case TCKind._tk_local_interface: //33 + { + id = typeCode.id(); + break; + } + default: + { + id = null; + break; //TC has no id + } + } } - else + catch(org.omg.CORBA.TypeCodePackage.BadKind e) { - // We may previously have already compacted and cached this - // typecode. - cached = (org.omg.CORBA.TypeCode)cachedTypecodes.get (id); + throw new INTERNAL("should never happen"); } - // If we don't have a cached value get the compact form and - // cache it. - if (cached == null) - { - value = value.get_compact_typecode(); - cachedTypecodes.put (id, value); - } - else + if (id != null) { - value = cached; + final org.omg.CORBA.TypeCode cached; + + if (cachedTypecodes == null) + { + cachedTypecodes = new HashMap(); + cached = null; + } + else + { + // We may previously have already compacted and cached this + // typecode. + cached = (org.omg.CORBA.TypeCode)cachedTypecodes.get(id); + } + + // If we don't have a cached value get the compact form and + // cache it. + if (cached == null) + { + typeCode = typeCode.get_compact_typecode(); + cachedTypecodes.put(id, typeCode); + } + else + { + typeCode = cached; + } } } - write_TypeCode (value, null); + + if (repeatedTCMap == null) + { + repeatedTCMap = new HashMap(); + } + + if (recursiveTCMap == null) + { + recursiveTCMap = new HashMap(); + } + + try + { + write_TypeCode(typeCode, recursiveTCMap, repeatedTCMap); + } + finally + { + repeatedTCMap.clear(); + recursiveTCMap.clear(); + } } - private final void writeRecursiveTypeCode - (final org.omg.CORBA.TypeCode value, final Map tcMap) throws BadKind + private final void writeIndirectionMarker(final Object key, + final Map indirectionTCMap) { write_long( -1 ); // recursion marker int negative_offset = - ((Integer) tcMap.get( value.id())).intValue() - size() - 4; + ((Integer) indirectionTCMap.get(key)).intValue() - pos - 4; + + write_long( negative_offset ); + } + + + private final void writeIndirectionMarker(final org.omg.CORBA.TypeCode value, + final Map recursiveTCMap, + boolean typeCodeKey) + throws BadKind + { + final java.lang.Object key; + + /* Sequence and array tcs will be stored under the actual TypeCode as they + * do not have IDs. + */ + if (typeCodeKey) + { + key = value; + } + else + { + key = value.id(); + } + + write_long( -1 ); // recursion marker + int negative_offset = ((Integer) recursiveTCMap.get(key)).intValue() - pos - 4; write_long( negative_offset ); } - private final void write_TypeCode - (final org.omg.CORBA.TypeCode value, Map tcMap) + private final void write_TypeCode(final org.omg.CORBA.TypeCode typeCode, + final Map recursiveTCMap, + final Map repeatedTCMap) { - if (value == null) + if (typeCode == null) { throw new BAD_PARAM("TypeCode is null"); } - int _kind = value.kind().value(); - int _mc; // member count + int _kind = -1; + final int _memberCount; try { - if( TypeCode.isRecursive(value) && - tcMap != null && - tcMap.containsKey( value.id()) ) + if(TypeCode.isRecursive(typeCode) && recursiveTCMap.containsKey( typeCode.id()) ) { - writeRecursiveTypeCode( value, tcMap ); + writeIndirectionMarker( typeCode.id(), recursiveTCMap ); } else { + _kind = typeCode.kind().value(); // regular TypeCodes switch( _kind ) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 23: - case 24: - case 25: - case 26: - write_long( _kind ); - break; - case TCKind._tk_objref: - write_long( _kind ); - beginEncapsulation(); - write_string( value.id() ); - write_string( value.name() ); - endEncapsulation(); - break; - case TCKind._tk_struct: - case TCKind._tk_except: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) + case 0: //_tk_null + case 1: //_tk_void + case 2: //_tk_short + case 3: //_tk_long + case 4: //_tk_ushort + case 5: //_tk_ulong + case 6: //_tk_float + case 7: //_tk_double + case 8: //_tk_boolean + case 9: //_tk_char + case 10: //_tk_octet + case 11: //_tk_any + case 12: //_tk_TypeCode + case 13: //_tk_Principal { - writeRecursiveTypeCode( value, tcMap ); + write_long( _kind ); + break; } - else + case TCKind._tk_objref: // 14 { - write_long( _kind ); - if (tcMap == null) + if (useIndirection && repeatedTCMap.containsKey(typeCode)) { - tcMap = new HashMap(); + writeIndirectionMarker(typeCode, repeatedTCMap); } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id(), value ); - - beginEncapsulation(); - write_string(value.id()); - write_string(value.name()); - _mc = value.member_count(); - write_long(_mc); - for( int i = 0; i < _mc; i++) + else { - write_string( value.member_name(i) ); - write_TypeCode( value.member_type(i), tcMap ); + write_long( _kind ); + + // remember tc start pos before we start writing it + // out + Integer tcStartPos = ObjectUtil.newInteger(pos); + recursiveTCMap.put(typeCode.id(), tcStartPos); + + beginEncapsulation(); + write_string( typeCode.id() ); + write_string( typeCode.name() ); + endEncapsulation(); + + //add typecode to cache not until here to account for + //recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); } - endEncapsulation(); - } - break; - case TCKind._tk_enum: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) - { - writeRecursiveTypeCode( value, tcMap ); + break; } - else + case TCKind._tk_struct: // 15 { - write_long( _kind ); - if (tcMap == null) + if (useIndirection && repeatedTCMap.containsKey(typeCode)) { - tcMap = new HashMap(); + writeIndirectionMarker(typeCode, repeatedTCMap); } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id(), value ); - - beginEncapsulation(); - write_string( value.id()); - write_string( value.name()); - _mc = value.member_count(); - write_long(_mc); - for( int i = 0; i < _mc; i++) + else { - write_string( value.member_name(i) ); + write_long( _kind ); + + final Integer tcStartPos = ObjectUtil.newInteger( pos ); + recursiveTCMap.put( typeCode.id(), tcStartPos ); + + beginEncapsulation(); + write_string(typeCode.id()); + write_string(typeCode.name()); + _memberCount = typeCode.member_count(); + write_long(_memberCount); + for( int i = 0; i < _memberCount; i++) + { + write_string( typeCode.member_name(i) ); + write_TypeCode( typeCode.member_type(i), recursiveTCMap, repeatedTCMap ); + } + endEncapsulation(); + + // add typecode to cache not until here to account for + // recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); } - endEncapsulation(); + break; } - break; - case TCKind._tk_union: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) + case TCKind._tk_union: // 16 { - writeRecursiveTypeCode( value, tcMap ); + if (useIndirection && repeatedTCMap.containsKey(typeCode)) + { + writeIndirectionMarker(typeCode, repeatedTCMap); + } + else + { + write_long( _kind ); + // remember tc start pos before we start writing it + // out + final Integer tcStartPos = ObjectUtil.newInteger( pos ); + recursiveTCMap.put( typeCode.id(), tcStartPos ); + + beginEncapsulation(); + write_string( typeCode.id() ); + write_string( typeCode.name() ); + + write_TypeCode(typeCode.discriminator_type(), + recursiveTCMap, + repeatedTCMap); + write_long( typeCode.default_index()); + _memberCount = typeCode.member_count(); + write_long(_memberCount); + for( int i = 0; i < _memberCount; i++) + { + if( i == typeCode.default_index() ) + { + write_octet((byte)0); + } + else + { + typeCode.member_label(i).write_value( this ); + } + write_string( typeCode.member_name(i)); + write_TypeCode( typeCode.member_type(i), recursiveTCMap, repeatedTCMap ); + } + endEncapsulation(); + + // add typecode to cache not until here to account + // for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); + } + break; } - else + case TCKind._tk_enum: // 17 { - write_long( _kind ); - if (tcMap == null) + if (useIndirection && repeatedTCMap.containsKey(typeCode)) { - tcMap = new HashMap(); + writeIndirectionMarker(typeCode, repeatedTCMap); } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id() , value ); + else + { + write_long( _kind ); - beginEncapsulation(); - write_string( value.id() ); - write_string( value.name() ); + final Integer tcStartPos = ObjectUtil.newInteger( pos ); + recursiveTCMap.put( typeCode.id(), tcStartPos ); - write_TypeCode( value.discriminator_type()); - write_long( value.default_index()); - _mc = value.member_count(); - write_long(_mc); - for( int i = 0; i < _mc; i++) - { - if( i == value.default_index() ) - { - write_octet((byte)0); - } - else + beginEncapsulation(); + write_string( typeCode.id()); + write_string( typeCode.name()); + _memberCount = typeCode.member_count(); + write_long(_memberCount); + for( int i = 0; i < _memberCount; i++) { - value.member_label(i).write_value( this ); + write_string( typeCode.member_name(i) ); } - write_string( value.member_name(i)); - write_TypeCode( value.member_type(i), tcMap ); + endEncapsulation(); + + repeatedTCMap.put(typeCode, tcStartPos); } - endEncapsulation(); - } - break; - case TCKind._tk_wstring: - case TCKind._tk_string: - write_long( _kind ); - write_long(value.length()); - break; - case TCKind._tk_fixed: - write_long( _kind ); - write_ushort( value.fixed_digits() ); - write_short( value.fixed_scale() ); - break; - case TCKind._tk_array: - case TCKind._tk_sequence: - write_long( _kind ); - beginEncapsulation(); - write_TypeCode( value.content_type(), tcMap); - write_long(value.length()); - endEncapsulation(); - break; - case TCKind._tk_alias: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) - { - writeRecursiveTypeCode( value, tcMap ); + break; } - else + case TCKind._tk_string: // 18 { write_long( _kind ); - if (tcMap == null) + write_long(typeCode.length()); + break; + } + case TCKind._tk_sequence: // 19 + // fallthrough + case TCKind._tk_array: // 20 + { + // Sequence and array TypeCodes don't have an id + // so we need to store using the actual TypeCode + if (useIndirection && repeatedTCMap.containsKey(typeCode)) { - tcMap = new HashMap(); + writeIndirectionMarker(typeCode, repeatedTCMap, true); } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id(), value ); + else + { + write_long( _kind ); + + // remember tc start pos before we start writing it + // out + Integer tcStartPos = ObjectUtil.newInteger(pos); + recursiveTCMap.put(typeCode, tcStartPos); + + beginEncapsulation(); + write_TypeCode( typeCode.content_type(), recursiveTCMap, repeatedTCMap); + write_long(typeCode.length()); + endEncapsulation(); - beginEncapsulation(); - write_string(value.id()); - write_string(value.name()); - write_TypeCode( value.content_type(), tcMap); - endEncapsulation(); + //add typecode to cache not until here to account + //for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); + } + break; } - break; - case TCKind._tk_value: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) + case TCKind._tk_alias: // 21 { - writeRecursiveTypeCode( value, tcMap ); + if (useIndirection && repeatedTCMap.containsKey(typeCode)) + { + writeIndirectionMarker(typeCode, repeatedTCMap); + } + else + { + write_long( _kind ); + + // remember tc start pos before we start writing it + // out + Integer tcStartPos = ObjectUtil.newInteger(pos); + recursiveTCMap.put(typeCode, tcStartPos); + + beginEncapsulation(); + write_string(typeCode.id()); + write_string(typeCode.name()); + write_TypeCode( typeCode.content_type(), recursiveTCMap, repeatedTCMap); + endEncapsulation(); + + //add typecode to cache not until here to account + //for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); + } + break; } - else + case TCKind._tk_except: // 22 { - write_long( _kind ); - if (tcMap == null) + if (useIndirection && repeatedTCMap.containsKey(typeCode)) { - tcMap = new HashMap(); + writeIndirectionMarker(typeCode, repeatedTCMap); } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id(), value ); - - beginEncapsulation(); - write_string(value.id()); - write_string(value.name()); - write_short( value.type_modifier() ); - org.omg.CORBA.TypeCode base = value.concrete_base_type(); - if (base != null) - write_TypeCode(base, tcMap); else - write_long (TCKind._tk_null); - _mc = value.member_count(); - write_long(_mc); - for( int i = 0; i < _mc; i++) { - write_string( value.member_name(i) ); - write_TypeCode( value.member_type(i), tcMap ); - write_short( value.member_visibility(i) ); + write_long( _kind ); + + // remember tc start pos before we start writing it + // out + Integer tcStartPos = ObjectUtil.newInteger(pos); + recursiveTCMap.put(typeCode, tcStartPos); + + beginEncapsulation(); + write_string(typeCode.id()); + write_string(typeCode.name()); + _memberCount = typeCode.member_count(); + write_long(_memberCount); + for( int i = 0; i < _memberCount; i++) + { + write_string( typeCode.member_name(i) ); + write_TypeCode( typeCode.member_type(i), recursiveTCMap, repeatedTCMap ); + } + endEncapsulation(); + + //add typecode to cache not until here to account + //for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); } - endEncapsulation(); + break; } - break; - case TCKind._tk_value_box: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) + case TCKind._tk_longlong: // 23 + // fallthrough + case TCKind._tk_ulonglong: // 24 { - writeRecursiveTypeCode( value, tcMap ); + write_long( _kind ); + break; } - else + case TCKind._tk_longdouble: // 25 { - write_long( _kind ); - if (tcMap == null) - { - tcMap = new HashMap(); - } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id(), value ); - - beginEncapsulation(); - write_string(value.id()); - write_string(value.name()); - write_TypeCode( value.content_type(), tcMap); - endEncapsulation(); + throw new MARSHAL("Cannot handle TypeCode with kind: " + _kind); } - break; - case TCKind._tk_abstract_interface: - if (useIndirection && tcMap != null && - tcMap.containsKey (value.id())) + case TCKind._tk_wchar: // 26 { - writeRecursiveTypeCode( value, tcMap ); + write_long( _kind ); + break; } - else + case TCKind._tk_wstring: // 27 { write_long( _kind ); - if (tcMap == null) + write_long(typeCode.length()); + break; + } + case TCKind._tk_fixed: //28 + { + write_long( _kind ); + write_ushort( typeCode.fixed_digits() ); + write_short( typeCode.fixed_scale() ); + break; + } + case TCKind._tk_value: // 29 + { + if (useIndirection && + repeatedTCMap.containsKey(typeCode)) + { + writeIndirectionMarker(typeCode, repeatedTCMap); + } + else + { + write_long( _kind ); + + final Integer tcStartPos = ObjectUtil.newInteger( pos ); + recursiveTCMap.put( typeCode.id(), tcStartPos ); + + beginEncapsulation(); + write_string(typeCode.id()); + write_string(typeCode.name()); + write_short( typeCode.type_modifier() ); + final org.omg.CORBA.TypeCode baseType = typeCode.concrete_base_type(); + if (baseType == null) + { + write_long (TCKind._tk_null); + } + else + { + write_TypeCode(baseType, recursiveTCMap, repeatedTCMap); + } + _memberCount = typeCode.member_count(); + write_long(_memberCount); + for( int i = 0; i < _memberCount; i++) + { + write_string( typeCode.member_name(i) ); + write_TypeCode( typeCode.member_type(i), recursiveTCMap, repeatedTCMap ); + write_short( typeCode.member_visibility(i) ); + } + endEncapsulation(); + + // add typecode to cache not until here to account + // for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); + } + break; + } + case TCKind._tk_value_box: // 30 + { + if (useIndirection && repeatedTCMap.containsKey(typeCode)) { - tcMap = new HashMap(); + writeIndirectionMarker(typeCode, repeatedTCMap); } - tcMap.put( value.id(), new Integer( pos ) ); - getRecursiveTCMap().put( value.id(), value ); + else + { + write_long( _kind ); + final Integer tcStartPos = ObjectUtil.newInteger( pos ); + recursiveTCMap.put( typeCode.id(), tcStartPos ); - beginEncapsulation(); - write_string(value.id()); - write_string(value.name()); - endEncapsulation(); + beginEncapsulation(); + write_string(typeCode.id()); + write_string(typeCode.name()); + write_TypeCode( typeCode.content_type(), recursiveTCMap, repeatedTCMap); + endEncapsulation(); + + // add typecode to cache not until here to account + // for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); + } + break; + } + case TCKind._tk_native: + { + throw new MARSHAL("Cannot handle TypeCode with kind: " + _kind); + } + case TCKind._tk_abstract_interface: + { + if (useIndirection && repeatedTCMap.containsKey(typeCode)) + { + writeIndirectionMarker(typeCode, repeatedTCMap); + } + else + { + write_long( _kind ); + final Integer tcStartPos = ObjectUtil.newInteger( pos ); + recursiveTCMap.put( typeCode.id(), tcStartPos ); + + beginEncapsulation(); + write_string(typeCode.id()); + write_string(typeCode.name()); + endEncapsulation(); + + // add typecode to cache not until here to account + // for recursive TCs + repeatedTCMap.put(typeCode, tcStartPos); + } + break; } - break; default: - throw new MARSHAL ("Cannot handle TypeCode with kind: " + _kind); + { + throw new MARSHAL ("Cannot handle TypeCode with kind: " + _kind); + } } } } @@ -1741,140 +2006,116 @@ * InputStream in and remarshals it to this CDROutputStream. * Called from Any. */ - public final void write_value ( final org.omg.CORBA.TypeCode tc, - final org.omg.CORBA.portable.InputStream in ) + public final void write_value ( final org.omg.CORBA.TypeCode typeCode, + final org.omg.CORBA.portable.InputStream input ) { - if (tc == null) + if (typeCode == null) { throw new BAD_PARAM("TypeCode is null"); } - int kind = tc.kind().value(); + int kind = typeCode.kind().value(); try { switch (kind) { - case TCKind._tk_null: - case TCKind._tk_void: - break; - case TCKind._tk_boolean: - write_boolean( in.read_boolean()); - break; - case TCKind._tk_char: - write_char( in.read_char()); - break; - case TCKind._tk_wchar: - write_wchar( in.read_wchar()); - break; - case TCKind._tk_octet: - write_octet( in.read_octet()); - break; - case TCKind._tk_short: - write_short( in.read_short()); - break; - case TCKind._tk_ushort: - write_ushort(in.read_ushort()); - break; - case TCKind._tk_long: - write_long( in.read_long()); - break; - case TCKind._tk_ulong: - write_ulong( in.read_ulong()); - break; - case TCKind._tk_float: - write_float( in.read_float()); - break; - case TCKind._tk_double: - write_double(in.read_double()); - break; - case TCKind._tk_longlong: - write_longlong(in.read_longlong()); - break; - case TCKind._tk_ulonglong: - write_ulonglong( in.read_ulonglong()); - break; - case TCKind._tk_any: - write_any( in.read_any()); - break; - case TCKind._tk_TypeCode: - write_TypeCode(in.read_TypeCode()); - break; - case TCKind._tk_Principal: - throw new NO_IMPLEMENT ("Principal deprecated"); - case TCKind._tk_objref: - write_Object( in.read_Object()); - break; - case TCKind._tk_string: - write_string( in.read_string()); - break; - case TCKind._tk_wstring: - write_wstring( in.read_wstring()); - break; - case TCKind._tk_fixed: - write_fixed (in.read_fixed()); - break; - case TCKind._tk_array: + case TCKind._tk_null: // 0 + // fallthrough + case TCKind._tk_void: // 1 { - int length = tc.length(); - if( tc.content_type().kind().value() == TCKind._tk_octet ) - { - check( length ); - in.read_octet_array( buffer, pos, length); - index+= length; - pos += length; - } - else - { - for( int i = 0; i < length; i++ ) - write_value( tc.content_type(), in ); - } break; } - case TCKind._tk_sequence: + case TCKind._tk_short: // 2 { - int len = in.read_long(); - write_long(len); - - org.omg.CORBA.TypeCode content_tc = tc.content_type(); - for( int i = 0; i < len; i++ ) - write_value( content_tc, in ); - + write_short( input.read_short()); + break; + } + case TCKind._tk_long: // 3 + { + write_long( input.read_long()); + break; + } + case TCKind._tk_ushort: // 4 + { + write_ushort(input.read_ushort()); + break; + } + case TCKind._tk_ulong: // 5 + { + write_ulong( input.read_ulong()); + break; + } + case TCKind._tk_float: // 6 + { + write_float( input.read_float()); + break; + } + case TCKind._tk_double: // 7 + { + write_double(input.read_double()); break; } - case TCKind._tk_except: - write_string( in.read_string()); - // don't break, fall through to ... - case TCKind._tk_struct: + case TCKind._tk_boolean: // 8 { - for( int i = 0; i < tc.member_count(); i++) - write_value( tc.member_type(i), in ); + write_boolean( input.read_boolean()); break; } - case TCKind._tk_enum: + case TCKind._tk_char: // 9 { - write_long( in.read_long() ); + write_char( input.read_char()); break; } - case TCKind._tk_union: + case TCKind._tk_octet: // 10 { - org.omg.CORBA.TypeCode disc = - (org.omg.CORBA.TypeCode) tc.discriminator_type(); + write_octet( input.read_octet()); + break; + } + case TCKind._tk_any: // 11 + { + write_any( input.read_any()); + break; + } + case TCKind._tk_TypeCode: // 12 + { + write_TypeCode(input.read_TypeCode()); + break; + } + case TCKind._tk_Principal: // 13 + { + throw new NO_IMPLEMENT ("Principal deprecated"); + } + case TCKind._tk_objref: // 14 + { + write_Object( input.read_Object()); + break; + } + case TCKind._tk_struct: // 15 + { + for( int i = 0; i < typeCode.member_count(); i++) + { + write_value( typeCode.member_type(i), input ); + } + break; + } + case TCKind._tk_union: // 16 + { + org.omg.CORBA.TypeCode disc = typeCode.discriminator_type(); disc = TypeCode.originalType(disc); - int def_idx = tc.default_index(); + int def_idx = typeCode.default_index(); int member_idx = -1; switch( disc.kind().value() ) { - case TCKind._tk_short: + case TCKind._tk_short: // 2 { - short s = in.read_short(); + short s = input.read_short(); write_short(s); - for(int i = 0 ; i < tc.member_count() ; i++) + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_short()) + if(s == typeCode.member_label(i).extract_short()) { member_idx = i; break; @@ -1883,15 +2124,15 @@ } break; } - case TCKind._tk_ushort: + case TCKind._tk_long: // 3 { - short s = in.read_ushort(); - write_ushort(s); - for(int i = 0 ; i < tc.member_count() ; i++) + int s = input.read_long(); + write_long(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_ushort()) + if(s == typeCode.member_label(i).extract_long()) { member_idx = i; break; @@ -1900,15 +2141,15 @@ } break; } - case TCKind._tk_long: + case TCKind._tk_ushort: // 4 { - int s = in.read_long(); - write_long(s); - for(int i = 0 ; i < tc.member_count() ; i++) + short s = input.read_ushort(); + write_ushort(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_long()) + if(s == typeCode.member_label(i).extract_ushort()) { member_idx = i; break; @@ -1917,15 +2158,15 @@ } break; } - case TCKind._tk_ulong: + case TCKind._tk_ulong: // 5 { - int s = in.read_ulong(); + int s = input.read_ulong(); write_ulong(s); - for(int i = 0 ; i < tc.member_count() ; i++) + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_ulong()) + if(s == typeCode.member_label(i).extract_ulong()) { member_idx = i; break; @@ -1934,15 +2175,22 @@ } break; } - case TCKind._tk_longlong: + case TCKind._tk_float: // 6 + // fallthrough + case TCKind._tk_double: // 7 { - long s = in.read_longlong(); - write_longlong(s); - for(int i = 0 ; i < tc.member_count() ; i++) + throw new MARSHAL( + "Invalid union discriminator type: " + disc); + } + case TCKind._tk_boolean: // 8 + { + boolean s = input.read_boolean(); + write_boolean(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_longlong()) + if(s == typeCode.member_label(i).extract_boolean()) { member_idx = i; break; @@ -1951,15 +2199,15 @@ } break; } - case TCKind._tk_ulonglong: + case TCKind._tk_char: // 9 { - long s = in.read_ulonglong(); - write_ulonglong(s); - for(int i = 0 ; i < tc.member_count() ; i++) + char s = input.read_char(); + write_char(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_ulonglong()) + if(s == typeCode.member_label(i).extract_char()) { member_idx = i; break; @@ -1968,15 +2216,32 @@ } break; } - case TCKind._tk_boolean: + case TCKind._tk_octet: // 10 + case TCKind._tk_any: // 11 + case TCKind._tk_TypeCode: // 12 + case TCKind._tk_Principal: // 13 + case TCKind._tk_objref: // 14 + case TCKind._tk_struct: // 15 + case TCKind._tk_union: // 16 { - boolean s = in.read_boolean(); - write_boolean(s); - for(int i = 0 ; i < tc.member_count() ; i++) + throw new MARSHAL( + "Invalid union discriminator type: " + disc); + } + case TCKind._tk_enum: // 17 + { + int s = input.read_long(); + write_long(s); + for( int i = 0 ; i < typeCode.member_count(); i++ ) { - if(i != def_idx) + if( i != def_idx) { - if(s == tc.member_label(i).extract_boolean()) + int label = + typeCode.member_label(i).create_input_stream().read_long(); + /* we have to use the any's input + stream because enums are not + inserted as longs */ + + if( s == label) { member_idx = i; break; @@ -1985,21 +2250,24 @@ } break; } - case TCKind._tk_enum: + case TCKind._tk_string: // 18 + case TCKind._tk_sequence: // 19 + case TCKind._tk_array: // 20 + case TCKind._tk_alias: // 21 + case TCKind._tk_except: // 22 { - int s = in.read_long(); - write_long(s); - for( int i = 0 ; i < tc.member_count(); i++ ) + throw new MARSHAL( + "Invalid union discriminator type: " + disc); + } + case TCKind._tk_longlong: // 23 + { + long s = input.read_longlong(); + write_longlong(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { - if( i != def_idx) + if(i != def_idx) { - int label = - tc.member_label(i).create_input_stream().read_long(); - /* we have to use the any's input - stream because enums are not - inserted as longs */ - - if( s == label) + if(s == typeCode.member_label(i).extract_longlong()) { member_idx = i; break; @@ -2008,15 +2276,15 @@ } break; } - case TCKind._tk_char: + case TCKind._tk_ulonglong: // 24 { - char s = in.read_char(); - write_char(s); - for(int i = 0 ; i < tc.member_count() ; i++) + long s = input.read_ulonglong(); + write_ulonglong(s); + for(int i = 0 ; i < typeCode.member_count() ; i++) { if(i != def_idx) { - if(s == tc.member_label(i).extract_char()) + if(s == typeCode.member_label(i).extract_ulonglong()) { member_idx = i; break; @@ -2026,7 +2294,9 @@ break; } default: - throw new MARSHAL("Invalid union discriminator type: " + disc); + { + throw new MARSHAL("Invalid union discriminator type: " + disc); + } } // write the member or default value, if any @@ -2038,45 +2308,124 @@ if( member_idx != -1 ) { - write_value( tc.member_type( member_idx ), in ); + write_value( typeCode.member_type( member_idx ), input ); } else if( def_idx != -1 ) { - write_value( tc.member_type( def_idx ), in ); + write_value( typeCode.member_type( def_idx ), input ); + } + break; + } + case TCKind._tk_enum: // 17 + { + write_long( input.read_long() ); + break; + } + case TCKind._tk_string: // 18 + { + write_string( input.read_string()); + break; + } + case TCKind._tk_sequence: // 19 + { + int len = input.read_long(); + write_long(len); + + org.omg.CORBA.TypeCode content_tc = typeCode.content_type(); + for( int i = 0; i < len; i++ ) + { + write_value(content_tc, input); } + break; } - case TCKind._tk_alias: + case TCKind._tk_array: // 20 { - write_value( tc.content_type(), in ); + int length = typeCode.length(); + if( typeCode.content_type().kind().value() == TCKind._tk_octet ) + { + check( length ); + input.read_octet_array( buffer, pos, length); + index+= length; + pos += length; + } + else + { + for( int i = 0; i < length; i++ ) + { + write_value( typeCode.content_type(), input ); + } + } + break; + } + case TCKind._tk_alias: // 21 + { + write_value( typeCode.content_type(), input ); + break; + } + case TCKind._tk_except: // 22 + { + write_string( input.read_string()); + for (int i = 0; i < typeCode.member_count(); i++) + { + write_value(typeCode.member_type(i), input); + } + break; + } + case TCKind._tk_longlong: // 23 + { + write_longlong(input.read_longlong()); + break; + } + case TCKind._tk_ulonglong: // 24 + { + write_ulonglong( input.read_ulonglong()); + break; + } + case TCKind._tk_longdouble: // 25 + { + throw new org.omg.CORBA.BAD_TYPECODE( + "type longdouble not supported in java"); + } + case TCKind._tk_wchar: // 26 + { + write_wchar( input.read_wchar()); + break; + } + case TCKind._tk_wstring: // 27 + { + write_wstring( input.read_wstring()); + break; + } + case TCKind._tk_fixed: // 28 + { + write_fixed (input.read_fixed()); + break; + } + case TCKind._tk_value: // 29 + { + final Serializable val = ((org.omg.CORBA_2_3.portable.InputStream)input).read_value(); + write_value(val, typeCode.id()); break; } case TCKind._tk_value_box: { - String id = tc.id(); + String id = typeCode.id(); org.omg.CORBA.portable.BoxedValueHelper helper = ((org.jacorb.orb.ORB)orb()).getBoxedValueHelper(id); if (helper == null) - throw new RuntimeException - ("No BoxedValueHelper for id " + id); + { + throw new MARSHAL("No BoxedValueHelper for id " + id); + } java.io.Serializable value = - ((org.omg.CORBA_2_3.portable.InputStream)in).read_value(helper); + ((org.omg.CORBA_2_3.portable.InputStream)input).read_value(helper); write_value (value, helper); break; } - case 0xffffffff: + default: { - org.omg.CORBA.TypeCode _tc = - (org.omg.CORBA.TypeCode)( getRecursiveTCMap().get( tc.id() ) ); - if( _tc == null ) - { - throw new MARSHAL("Recursive TypeCode not found for " + tc.id()); - } - write_value( _tc , in ); - break; + throw new MARSHAL("Cannot handle TypeCode with kind " + kind); } - default: - throw new MARSHAL("Cannot handle TypeCode with kind " + kind); } } catch (BadKind ex) @@ -2098,21 +2447,25 @@ public void write_value(final java.io.Serializable value) { if (!write_special_value (value)) + { write_value_internal (value, ValueHandler.getRMIRepositoryID (value.getClass())); + } } public void write_value(final java.io.Serializable value, - final org.omg.CORBA.portable.BoxedValueHelper factory) + final org.omg.CORBA.portable.BoxedValueHelper factory) { if (!write_special_value (value)) { - check(7,4); - getValueMap().put (value, new Integer(pos)); write_previous_chunk_size(); + check(7,4); + getValueMap().put (value, ObjectUtil.newInteger(pos)); if ((value instanceof org.omg.CORBA.portable.IDLEntity) || (value instanceof java.lang.String)) + { write_long (0x7fffff00 | chunkingFlag); + } else { // repository id is required for RMI: types @@ -2126,19 +2479,25 @@ } public void write_value(final java.io.Serializable value, - final java.lang.Class clz) + final java.lang.Class clazz) { if (!write_special_value (value)) { - Class c = value.getClass(); - String repId = ValueHandler.getRMIRepositoryID(c); - if (c == clz && !repId.startsWith("RMI:")) + final Class _clazz = value.getClass(); + final String repId = ValueHandler.getRMIRepositoryID(_clazz); + if (_clazz == clazz && !repId.startsWith("RMI:")) + { // the repository id is required for "RMI:" valuetypes write_value_internal (value, null); - else if (clz.isInstance (value)) + } + else if (clazz.isInstance (value)) + { write_value_internal (value, repId); + } else + { throw new BAD_PARAM(); + } } } @@ -2146,7 +2505,9 @@ final String repository_id) { if (!write_special_value (value)) + { write_value_internal (value, repository_id); + } } /** @@ -2162,20 +2523,16 @@ write_long (0x00000000); return true; } - else - { - Integer index = (Integer)getValueMap().get (value); - if (index != null) - { - // value has already been written -- make an indirection - write_long (0xffffffff); - write_long (index.intValue() - size()); - return true; - } - else - return false; + Integer index = (Integer)getValueMap().get (value); + if (index != null) + { + // value has already been written -- make an indirection + write_long (0xffffffff); + write_long (index.intValue() - size()); + return true; } + return false; } /** @@ -2197,7 +2554,7 @@ pos += remainder; } - getRepIdMap().put (repository_id, new Integer(pos)); + getRepIdMap().put (repository_id, ObjectUtil.newInteger(pos)); write_string (repository_id); } else @@ -2235,7 +2592,7 @@ pos += remainder; } - getCodebaseMap().put (codebase, new Integer(pos)); + getCodebaseMap().put (codebase, ObjectUtil.newInteger(pos)); write_string (codebase); } else @@ -2252,7 +2609,6 @@ */ private void write_value_header(final String[] repository_ids) { - write_previous_chunk_size(); if (repository_ids != null) { if( repository_ids.length > 1 ) @@ -2274,20 +2630,19 @@ } } else + { write_long (0x7fffff00 | chunkingFlag); + } } /** * Writes to this stream a value header with the specified `repository_id'. * and `codebase' string. */ - - private void write_value_header - (final String[] repository_ids, final String codebase) + private void write_value_header(final String[] repository_ids, final String codebase) { if (codebase != null) { - write_previous_chunk_size(); if ( repository_ids != null ) { if( repository_ids.length > 1 ) @@ -2318,7 +2673,9 @@ } } else + { write_value_header (repository_ids); + } } /** @@ -2333,8 +2690,9 @@ private void write_value_internal(final java.io.Serializable value, final String repository_id) { + write_previous_chunk_size(); check(7,4); - getValueMap().put(value, new Integer(pos)); + getValueMap().put(value, ObjectUtil.newInteger(pos)); if (value.getClass() == String.class) { @@ -2379,24 +2737,24 @@ { String[] repository_ids = (repository_id == null) ? null : new String[]{ repository_id }; - Class cls = value.getClass(); - String codebase = ValueHandler.getCodebase(cls); + Class clazz = value.getClass(); + String codebase = ValueHandler.getCodebase(clazz); if (value instanceof org.omg.CORBA.portable.IDLEntity) { java.lang.reflect.Method writeMethod = null; - if (cls != org.omg.CORBA.Any.class) + if (clazz != org.omg.CORBA.Any.class) { - String helperClassName = cls.getName() + "Helper"; + String helperClassName = clazz.getName() + "Helper"; try { Class helperClass = - (cls.getClassLoader() != null) - ? cls.getClassLoader().loadClass(helperClassName) + (clazz.getClassLoader() != null) + ? clazz.getClassLoader().loadClass(helperClassName) : ObjectUtil.classForName(helperClassName); Class[] paramTypes = - { org.omg.CORBA.portable.OutputStream.class, cls }; + { org.omg.CORBA.portable.OutputStream.class, clazz }; writeMethod = helperClass.getMethod("write", paramTypes); } catch (ClassNotFoundException e) @@ -2441,40 +2799,50 @@ { writeValueNestingLevel++; if (chunkCustomRmiValuetypes - && ValueHandler.isCustomMarshaled(cls)) + && ValueHandler.isCustomMarshaled(clazz)) + { chunkingFlag = 0x00000008; - write_value_header( repository_ids, codebase ); - start_chunk(); + } + + Serializable newValue = value; if (!writeReplaceCalled) { // writeReplace must be called only once for this value - java.io.Serializable newValue = - ValueHandler.writeReplace(value); + newValue = ValueHandler.writeReplace(value); writeReplaceCalled = true; // won't call it again + } + + if (newValue != value) + { + // recompute codebase and/or repositoryID as might have changed + String new_rep_id = + ValueHandler.getRMIRepositoryID(newValue.getClass()); + repository_ids = + (new_rep_id == null) ? null : new String []{new_rep_id}; + clazz = newValue.getClass(); + codebase = ValueHandler.getCodebase(clazz); + } - if (newValue != value) + write_value_header( repository_ids, codebase ); + start_chunk(); + + if (newValue != value) + { + // look at the new value + Integer index = (Integer)getValueMap().get(newValue); + if (index != null) { - // look at the new value - Integer index = (Integer)getValueMap().get(newValue); - if (index != null) - { - // previously marshaled value -- make an indirection - write_long (0xffffffff); - write_long (index.intValue() - size()); - } - else if (value instanceof org.omg.CORBA.Object) - { - write_Object((org.omg.CORBA.Object)newValue); - } - else - { - ValueHandler.writeValue(this, newValue); - } + // previously marshaled value -- make an indirection + write_long (0xffffffff); + write_long (index.intValue() - size()); + } + else if (newValue instanceof org.omg.CORBA.Object) + { + write_Object((org.omg.CORBA.Object)newValue); } else { - // writeReplace did't make a difference - ValueHandler.writeValue(this, value); + ValueHandler.writeValue(this, newValue); } } else @@ -2488,7 +2856,9 @@ finally { if (--writeValueNestingLevel == 0) + { writeReplaceCalled = false; + } } } } @@ -2533,9 +2903,9 @@ */ private void write_previous_chunk_size() { - if( chunk_size_tag_pos != -1 ) + if (chunk_size_tag_pos != -1) { - if ( pos == chunk_octets_pos) + if (pos == chunk_octets_pos) { // empty chunk: erase chunk size tag pos = chunk_size_tag_pos; // the tag will be overwritten @@ -2544,19 +2914,9 @@ else { // go to the beginning of the chunk and write the size tag - - // check(7, 4); // DO NOT align to a 4-byte boundary - - int current_pos = pos; - int current_idx = index; - - pos = chunk_size_tag_pos; - index = chunk_size_tag_index; - write_long( current_pos - chunk_octets_pos ); - - pos = current_pos; - index = current_idx; - + rewrite_long(chunk_size_tag_pos, + chunk_size_tag_index, + pos - chunk_octets_pos); } chunk_size_tag_pos = -1; // no chunk is currently open } @@ -2569,13 +2929,33 @@ chunk_size_tag_index = index; // insert four bytes here as a place-holder - write_long( 0 ); // need to go back later and write the actual size + write_long(0); // need to go back later and write the actual size // remember starting position of chunk data chunk_octets_pos = pos; } /** + * Writes a CORBA long value to (write_pos, write_index) without clearing + * the buffer padding. In the case of a non-sequential write, clearing + * buffer positions after the data just written is likely to erase data + * previously written. + */ + private final void rewrite_long(int write_pos, + int write_index, + final int value) + { + final int align = 4; + int remainder = align - (write_index % align); + if (remainder != align) + { + write_index += remainder; + write_pos += remainder; + } + _write4int(buffer, write_pos, value); + } + + /** * Writes an abstract interface to this stream. The abstract interface is * written as a union with a boolean discriminator, which is true if the * union contains a CORBA object reference, or false if the union contains @@ -2594,4 +2974,5 @@ write_value((java.io.Serializable)object); } } + } Index: src/org/jacorb/orb/Delegate.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/Delegate.java,v retrieving revision 1.121 diff -u -r1.121 Delegate.java --- src/org/jacorb/orb/Delegate.java 22 May 2006 15:03:50 -0000 1.121 +++ src/org/jacorb/orb/Delegate.java 5 May 2007 00:36:08 -0000 @@ -1515,13 +1515,7 @@ replyEndTime, p.get_object_key(), p.getEffectiveProfile().version().minor ); - try{ - // TODO - ros.configure(configuration); - } catch (ConfigurationException e) - { - throw new RuntimeException(); - } + ros.configure(configuration); // CodeSets are only negotiated once per connection, // not for each individual request Index: src/org/jacorb/orb/dsi/ServerRequest.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/dsi/ServerRequest.java,v retrieving revision 1.39 diff -u -r1.39 ServerRequest.java --- src/org/jacorb/orb/dsi/ServerRequest.java 19 May 2006 20:14:50 -0000 1.39 +++ src/org/jacorb/orb/dsi/ServerRequest.java 5 May 2007 00:36:08 -0000 @@ -431,13 +431,8 @@ in.isLocateRequest(), logger ); - try - { - out.configure(orb.getConfiguration()); - } catch (ConfigurationException e) - { - throw new RuntimeException(); - } + out.configure(orb.getConfiguration()); + return out; } Index: src/org/jacorb/orb/giop/GIOPConnection.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/giop/GIOPConnection.java,v retrieving revision 1.52 diff -u -r1.52 GIOPConnection.java --- src/org/jacorb/orb/giop/GIOPConnection.java 9 Jan 2006 16:32:54 -0000 1.52 +++ src/org/jacorb/orb/giop/GIOPConnection.java 5 May 2007 00:36:08 -0000 @@ -43,7 +43,7 @@ * Created: Sun Aug 12 21:30:48 2002 * * @author Nicolas Noffke - * @version $Id: GIOPConnection.java,v 1.52 2006/01/09 16:32:54 andre.spiegel Exp $ + * @version $Id: GIOPConnection.java,v 1.52.2.1 2006/07/07 09:03:23 andre.spiegel Exp $ */ public abstract class GIOPConnection @@ -377,16 +377,20 @@ } else { - if (logger.isErrorEnabled()) + if (logger.isDebugEnabled()) { - logger.error( "Failed to read GIOP message, incorrect magic number" ); + logger.debug("GIOPConnection.getMessage(): invalid header read: " + msg_header.value ); } - if (logger.isDebugEnabled()) + if (logger.isErrorEnabled()) { - logger.debug("GIOPConnection.getMessage()" + msg_header.value ); + logger.error( "Failed to read GIOP message, incorrect magic number --> connection closed" ); } - + //close transport connection, there is nearly no chance to sync with + //peer on this connection again + close(); + //signal GIOPConnectionManager to throw this connection away + this.streamClosed(); return null; } } Index: src/org/jacorb/orb/giop/LocateRequestInputStream.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/giop/LocateRequestInputStream.java,v retrieving revision 1.16 diff -u -r1.16 LocateRequestInputStream.java --- src/org/jacorb/orb/giop/LocateRequestInputStream.java 6 May 2004 12:40:00 -0000 1.16 +++ src/org/jacorb/orb/giop/LocateRequestInputStream.java 5 May 2007 00:36:08 -0000 @@ -89,10 +89,6 @@ { close(); } - catch( java.io.IOException iox ) - { - //ignore - } finally { super.finalize(); Index: src/org/jacorb/orb/giop/ReplyInputStream.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/giop/ReplyInputStream.java,v retrieving revision 1.22 diff -u -r1.22 ReplyInputStream.java --- src/org/jacorb/orb/giop/ReplyInputStream.java 18 Nov 2004 23:27:20 -0000 1.22 +++ src/org/jacorb/orb/giop/ReplyInputStream.java 5 May 2007 00:36:08 -0000 @@ -173,10 +173,6 @@ { close(); } - catch( java.io.IOException iox ) - { - //ignore - } finally { super.finalize(); Index: src/org/jacorb/orb/giop/RequestInputStream.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/orb/giop/RequestInputStream.java,v retrieving revision 1.18 diff -u -r1.18 RequestInputStream.java --- src/org/jacorb/orb/giop/RequestInputStream.java 6 May 2004 12:40:00 -0000 1.18 +++ src/org/jacorb/orb/giop/RequestInputStream.java 5 May 2007 00:36:08 -0000 @@ -178,10 +178,6 @@ { close(); } - catch( java.io.IOException iox ) - { - //ignore - } finally { super.finalize(); Index: src/org/jacorb/util/ObjectUtil.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/util/ObjectUtil.java,v retrieving revision 1.17 diff -u -r1.17 ObjectUtil.java --- src/org/jacorb/util/ObjectUtil.java 21 Oct 2005 21:06:25 -0000 1.17 +++ src/org/jacorb/util/ObjectUtil.java 5 May 2007 00:36:09 -0000 @@ -20,19 +20,27 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -import java.util.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; /** * @author Gerald Brose, FU Berlin - * @version $Id: ObjectUtil.java,v 1.17 2005/10/21 21:06:25 alphonse.bendt Exp $ + * @version $Id: ObjectUtil.java,v 1.21 2006/11/30 13:11:07 alphonse.bendt Exp $ */ public class ObjectUtil { - private static Class identityHashMapClass = null; //for byte -> hexchar private static final char[] lookup = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + private ObjectUtil() + { + // utility class + } + /** * @return the contents of the resource as a string, or null * if the contents of the resource could not be located using url @@ -40,31 +48,42 @@ public static final String readURL( String url ) throws java.io.IOException { + final BufferedReader reader = new BufferedReader(newInputStreamReader(url)); + + try + { + return reader.readLine(); + } + finally + { + reader.close(); + } + } + + private static java.io.InputStreamReader newInputStreamReader(String url) throws MalformedURLException, IOException + { String token = "file://"; - String line = ""; java.io.InputStreamReader isr = null; - if (url.startsWith (token)) + if (url.startsWith(token)) + { try { - isr = new java.io.FileReader (url.substring(token.length())); + isr = new java.io.FileReader(url.substring(token.length())); } catch (Exception e) { - System.out.println ("Tried and failed to open file: " + + System.out.println ("Tried and failed to open file: " + // NOPMD url.substring(token.length())); // no worries, let the URL handle it } + } + if (isr == null) { - java.net.URL u = new java.net.URL(url); - isr = new java.io.InputStreamReader(u.openStream()); + java.net.URL urlCopy = new java.net.URL(url); + isr = new java.io.InputStreamReader(urlCopy.openStream()); } - - java.io.BufferedReader in = new java.io.BufferedReader(isr); - line = in.readLine(); - - in.close(); - return line; + return isr; } /** @@ -115,7 +134,10 @@ throws ClassNotFoundException, IllegalArgumentException { if (name == null) + { throw new IllegalArgumentException("Class name must not be null!"); + } + try { // Here we prefer classLoader.loadClass() over the three-argument @@ -134,45 +156,7 @@ } } - /** - * Creates an IdentityHashMap, using either the JDK 1.4 class or - * JacORB's drop-in replacement class if the former is not available. - * - * @return a newly created IdentityHashMap instance - */ - public static Map createIdentityHashMap() - { - if (identityHashMapClass == null) - { - try - { - identityHashMapClass = - ObjectUtil.classForName("java.util.IdentityHashMap"); - } - catch (ClassNotFoundException ex) - { - try - { - identityHashMapClass = - ObjectUtil.classForName("org.jacorb.util.IdentityHashMap"); - } - catch (ClassNotFoundException e) - { - throw new RuntimeException(e.toString()); - } - } - } - try - { - return (Map)identityHashMapClass.newInstance(); - } - catch (Exception exc) - { - throw new RuntimeException(exc.toString()); - } - } - - public static String bufToString( byte bs[], + public static String bufToString( byte values[], int start, int len) { @@ -184,12 +168,12 @@ if ((i % 16 ) == 0) { result.append( chars.toString() ); - result.append( "\n" ); + result.append( '\n' ); chars.setLength(0); } - chars.append( toAscii( bs[i] )); - result.append( toHex( bs[i] )); + chars.append( toAscii( values[i] )); + result.append( toHex( values[i] )); if ( (i % 4) == 3 ) { @@ -215,7 +199,7 @@ { pad += 1; } - + for ( int i = 0; i < pad; i++ ) { chars.insert( 0, ' ' ); @@ -230,33 +214,33 @@ /** * toHex converts a byte into a readable string. * - * @param b a byte value + * @param value a byte value * @return a String value */ - public static final String toHex(byte b) + public static final String toHex(byte value) { - StringBuffer sb = new StringBuffer(); + final StringBuffer buffer = new StringBuffer(); - int upper = (b >> 4) & 0x0F; - sb.append( lookup[upper] ); + int upper = (value >> 4) & 0x0F; + buffer.append( lookup[upper] ); - int lower = b & 0x0F; - sb.append( lookup[lower] ); + int lower = value & 0x0F; + buffer.append( lookup[lower] ); - sb.append( ' ' ); + buffer.append( ' ' ); - return sb.toString(); + return buffer.toString(); } - public static final char toAscii(byte b) + public static final char toAscii(byte value) { - if ( b > (byte) 31 && b < (byte) 127) + if ( value > (byte) 31 && value < (byte) 127) { - return (char) b; + return (char) value; } - + return '.'; } @@ -276,13 +260,33 @@ { int idx = args[i].indexOf('='); if (idx < 3 ) + { continue; + } String key = args[i].substring(2,idx); - System.out.println("putting: " + key + "," + args[i].substring(idx+1)); props.put(key, args[i].substring(idx+1)); } } return props; + } + + public static URL getResource(String name) + { + if (Thread.currentThread().getContextClassLoader() != null) + { + return Thread.currentThread().getContextClassLoader().getResource(name); + } + return ObjectUtil.class.getResource(name); + } + + /** + * factory method to create Integers from ints. + * should be used throughout the code to prepare + * transition to JDK 1.5 (Integer.valueOf(int)) + */ + public static Integer newInteger(int value) + { + return new Integer(value); // NOPMD } } Index: src/org/jacorb/util/Version.java =================================================================== RCS file: /cvsroot/jacorb/JacORB/src/org/jacorb/util/Version.java,v retrieving revision 1.29 diff -u -r1.29 Version.java --- src/org/jacorb/util/Version.java 10 Dec 2005 15:56:10 -0000 1.29 +++ src/org/jacorb/util/Version.java 5 May 2007 00:36:09 -0000 @@ -28,7 +28,7 @@ */ public final class Version { - public static final String version = "2.2.3"; - public static final String date = "10-Dec-2005"; + public static final String version = "2.2.4 (JBoss patch 2)"; + public static final String date = "04-May-2007"; public static final String longVersion = version + ", " + date; }