/** * * Copyright 2004-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.interop.rmi.iiop; import org.apache.geronimo.interop.SystemException; import org.apache.geronimo.interop.rmi.RmiTrace; import org.apache.geronimo.interop.util.ArrayUtil; import org.apache.geronimo.interop.util.BigEndian; import org.apache.geronimo.interop.util.ExceptionUtil; import org.apache.geronimo.interop.util.JavaClass; import org.apache.geronimo.interop.util.UTF8; import org.omg.CORBA.TCKind; import org.omg.GIOP.LocateReplyHeader_1_2; import org.omg.GIOP.LocateReplyHeader_1_2Helper; import org.omg.GIOP.MessageHeader_1_1; import org.omg.GIOP.MessageHeader_1_1Helper; import org.omg.GIOP.MsgType_1_1; import org.omg.GIOP.ReplyHeader_1_0; import org.omg.GIOP.ReplyHeader_1_0Helper; import org.omg.GIOP.ReplyHeader_1_2; import org.omg.GIOP.ReplyHeader_1_2Helper; import org.omg.GIOP.RequestHeader_1_0; import org.omg.GIOP.RequestHeader_1_0Helper; import org.omg.GIOP.RequestHeader_1_1; import org.omg.GIOP.RequestHeader_1_1Helper; import org.omg.GIOP.RequestHeader_1_2; import org.omg.GIOP.RequestHeader_1_2Helper; import org.omg.GIOP.Version; import org.omg.IOP.IOR; import org.omg.IOP.IORHelper; import org.omg.IOP.ServiceContext; import org.omg.IOP.TaggedProfile; /** ** CORBA 2.3 / GIOP 1.2 CDR OutputStream. **/ public class CdrOutputStream extends org.omg.CORBA_2_3.portable.OutputStream { private final String CRLF = "\r\n"; public static CdrOutputStream getInstance() { CdrOutputStream output = new CdrOutputStream(); output.init(new byte[DEFAULT_BUFFER_LENGTH], 0); return output; } public static CdrOutputStream getInstance(byte[] buffer) { CdrOutputStream output = new CdrOutputStream(); output.init(buffer, 0); return output; } public static CdrOutputStream getInstance(byte[] buffer, int offset) { CdrOutputStream output = new CdrOutputStream(); output.init(buffer, offset); return output; } public static CdrOutputStream getInstanceForEncapsulation() { CdrOutputStream output = getInstance(); output.write_boolean(false); // byte order: big endian return output; } public static CdrOutputStream getPooledInstance() { CdrOutputStream output = null; if (output == null) { output = getInstance(); } return output; } // ----------------------------------------------------------------------- // private data // ----------------------------------------------------------------------- private static final int DEFAULT_BUFFER_LENGTH = 64; private static final int MAXIMUM_POOLED_BUFFER_LENGTH = 1024; private static final boolean RMI_TRACE = true; private static IOR NULL_IOR = new IOR("", new TaggedProfile[0]); private static char[] GIOP_MAGIC = { 'G', 'I', 'O', 'P' }; private static ServiceContext[] EMPTY_SERVICE_CONTEXT_LIST = {}; private static Version GIOP_VERSION_1_0 = new Version((byte)1, (byte)0); private static Version GIOP_VERSION_1_1 = new Version((byte)1, (byte)1); private static Version GIOP_VERSION_1_2 = new Version((byte)1, (byte)2); private int _giopVersion = GiopVersion.VERSION_1_2; private boolean _unaligned; private byte[] _pooledBuffer; // ----------------------------------------------------------------------- // package-private data // ----------------------------------------------------------------------- byte[] _buffer; int _offset; int _length; // ----------------------------------------------------------------------- // public methods // ----------------------------------------------------------------------- public void init(byte[] buffer, int offset) { _buffer = buffer; _offset = offset; _length = _buffer.length; } public void recycle() { reset(); } public void reset() { _offset = 0; if (_buffer.length > MAXIMUM_POOLED_BUFFER_LENGTH) { _buffer = _pooledBuffer; _pooledBuffer = null; if (_buffer == null) { _buffer = new byte[DEFAULT_BUFFER_LENGTH]; } } _length = _buffer.length; } public void setUnaligned() { _unaligned = true; } public byte[] getBytes() { int n = _offset; byte[] bytes = new byte[n]; System.arraycopy(_buffer, 0, bytes, 0, n); return bytes; } public byte[] getBuffer() { return _buffer; } public int getOffset() { return _offset; } public int getLength() { return _length; } public byte[] getEncapsulation() { byte[] data = new byte[_offset]; System.arraycopy(_buffer, 0, data, 0, _offset); return data; } public void setGiopVersion(int version) { _giopVersion = version; } /** ** Align the buffer offset so the next item is written at an offset ** aligned according to <code>alignment</code>, which must be a ** power of 2 (and at least = 1). ** <p>The padding bytes are set to zero, to prevent the ** security problems inherent in uninitialised padding bytes. ** <p>Then we check if there is enough space left in the buffer for ** an item of <code>size</code> bytes; if not, we expand the buffer ** to make space. **/ public final void write_align(int alignment, int size) { if (_unaligned) { alignment = 1; } int needLength = _offset + alignment + size; if (needLength > _length) { // We need to increase the buffer size. We allow for a bit // of future expansion (if possible). int factor8 = 32; for (int pass = 1; pass <= 7; pass++, factor8 /= 2) { // We try factors 5, 3, 2, 1.5, 1.25, 1.125, 1. try { byte[] newBuffer = new byte[needLength + factor8 * needLength / 8]; // Copy old buffer contents into new buffer. System.arraycopy(_buffer, 0, newBuffer, 0, _offset); pool(_buffer); _buffer = newBuffer; _length = newBuffer.length; break; } catch (OutOfMemoryError ignore) { if (pass == 7) { throw new org.omg.CORBA.NO_MEMORY(needLength + " bytes"); } } } } int mask = alignment - 1; for (int i = (alignment - (_offset & mask)) & mask; i > 0; i--) { _buffer[_offset++] = 0; } } /** ** Convenience method needed in many places. **/ public void write_octet_sequence(byte[] bytes) { if (bytes == null) { bytes = ArrayUtil.EMPTY_BYTE_ARRAY; } int n = bytes.length; write_long(n); write_octet_array(bytes, 0, n); } public void write_message(int messageType) { MessageHeader_1_1 header = new MessageHeader_1_1(); header.magic = GIOP_MAGIC; switch (_giopVersion) { case GiopVersion.VERSION_1_0: header.GIOP_version = GIOP_VERSION_1_2; break; case GiopVersion.VERSION_1_1: header.GIOP_version = GIOP_VERSION_1_1; break; case GiopVersion.VERSION_1_2: header.GIOP_version = GIOP_VERSION_1_2; break; default: throw new IllegalStateException(); } header.flags = 0; header.message_type = (byte)messageType; header.message_size = 0; // header.message_size is rewritten later MessageHeader_1_1Helper.write(this, header); } public void write_message_size() { int messageSize = _offset - 12; int saveOffset = _offset; _offset = 8; write_long(messageSize); _offset = saveOffset; } public void write_request(RequestHeader_1_2 request, CdrOutputStream parameters) { if (request.service_context == null) { // Avoid allocation of empty array by Helper. request.service_context = EMPTY_SERVICE_CONTEXT_LIST; } write_message(MsgType_1_1._Request); switch (_giopVersion) { case GiopVersion.VERSION_1_0: RequestHeader_1_0 req10 = new RequestHeader_1_0(); req10.service_context = request.service_context; req10.request_id = request.request_id; req10.response_expected = (request.response_flags & 1) != 0; req10.operation = request.operation; req10.object_key = request.target.object_key(); RequestHeader_1_0Helper.write(this, req10); break; case GiopVersion.VERSION_1_1: RequestHeader_1_1 req11 = new RequestHeader_1_1(); req11.service_context = request.service_context; req11.request_id = request.request_id; req11.response_expected = (request.response_flags & 1) != 0; req11.operation = request.operation; req11.object_key = request.target.object_key(); RequestHeader_1_1Helper.write(this, req11); break; case GiopVersion.VERSION_1_2: RequestHeader_1_2Helper.write(this, request); break; default: throw new IllegalStateException(); } byte[] parametersBuffer = parameters.getBuffer(); int parametersLength = parameters.getOffset(); if (parametersLength > 0) { if (_giopVersion >= GiopVersion.VERSION_1_2) { write_align(8, 0); // parameters are 8-byte aligned } else { // TODO: should have padded service context earlier } write_octet_array(parametersBuffer, 0, parametersLength); } write_message_size(); } public void write_reply(ReplyHeader_1_2 reply, CdrOutputStream results) { if (reply.service_context == null) { // Avoid allocation of empty array by Helper. reply.service_context = EMPTY_SERVICE_CONTEXT_LIST; } write_message(MsgType_1_1._Reply); switch (_giopVersion) { case GiopVersion.VERSION_1_0: case GiopVersion.VERSION_1_1: ReplyHeader_1_0 rep10 = new ReplyHeader_1_0(); rep10.service_context = reply.service_context; rep10.request_id = reply.request_id; rep10.reply_status = reply.reply_status; ReplyHeader_1_0Helper.write(this, rep10); break; case GiopVersion.VERSION_1_2: ReplyHeader_1_2Helper.write(this, reply); break; default: throw new IllegalStateException(); } byte[] resultsBuffer = results.getBuffer(); int resultsLength = results.getOffset(); if (resultsLength > 0) { if (_giopVersion >= GiopVersion.VERSION_1_2) { write_align(8, 0); // results are 8-byte aligned } else { // TODO: should have padded service context earlier } write_octet_array(resultsBuffer, 0, resultsLength); } write_message_size(); } public void write_reply(LocateReplyHeader_1_2 reply) { write_message(MsgType_1_1._LocateReply); LocateReplyHeader_1_2Helper.write(this, reply); write_message_size(); } public void write_SystemException(Exception ex, boolean withStackTrace) { String type = "UNKNOWN"; if (ex instanceof org.omg.CORBA.SystemException) { type = JavaClass.getNameSuffix(ex.getClass().getName()); } else if (ex instanceof UnsupportedOperationException) { type = "BAD_OPERATION"; } else if (ex instanceof SecurityException) { type = "NO_PERMISSION"; } else if (ex instanceof java.rmi.NoSuchObjectException) { type = "OBJECT_NOT_EXIST"; } //else if (ex instanceof org.apache.geronimo.interop.transaction.TransactionRolledbackSystemException) //{ // type = "TRANSACTION_ROLLEDBACK"; //} String id = "IDL:omg.org/CORBA/" + type + ":1.0"; write_string(id); write_long(0); // minor (TODO: other values?) write_long(0); // completed (TODO: other values?) if (withStackTrace) { write_string(ExceptionUtil.getStackTrace(ex)); } } public void send_http_response(java.io.OutputStream output, String url) { StringBuffer respHeader = new StringBuffer(256); respHeader.append("HTTP/1.1 200 OK\r\n"); respHeader.append("Content-Length: "); respHeader.append(java.lang.Integer.toString(_offset)); respHeader.append(CRLF + CRLF); byte[] header = null; try { String h = respHeader.toString(); header = h.getBytes("ASCII"); } catch(Exception e) { throw new SystemException(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e)); } byte[] data = new byte[header.length + _offset]; System.arraycopy(header, 0, data, 0, header.length); System.arraycopy(_buffer, 0, data, header.length, _offset); if (RMI_TRACE) { RmiTrace.send(url, data); } try { output.write(data, 0, data.length); output.flush(); } catch (java.io.IOException ex) { throw new org.omg.CORBA.COMM_FAILURE(ex.toString()); } } /** * We support only POST message */ public void send_http_request(java.io.OutputStream output, String url, String httpHeaders) { StringBuffer hdr = new StringBuffer(512); hdr.append("POST /host/port/HIOP/2.0 HTTP/1.1\r\n"); hdr.append("Content-Length: "); hdr.append(java.lang.Integer.toString(_offset)); hdr.append(CRLF); hdr.append(httpHeaders); hdr.append(CRLF); byte[] header = null; try { header = hdr.toString().getBytes("ASCII"); } catch(Exception e) { throw new SystemException(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e)); } byte[] data = new byte[header.length + _offset]; System.arraycopy(header, 0, data, 0, header.length); System.arraycopy(_buffer, 0, data, header.length, _offset); if (RMI_TRACE) { RmiTrace.send(url, data); } try { output.write(data, 0, data.length); output.flush(); } catch (java.io.IOException ex) { throw new org.omg.CORBA.COMM_FAILURE(ex.toString()); } } public void send_message(java.io.OutputStream output, String url) { if (RMI_TRACE) { byte[] data = new byte[_offset]; System.arraycopy(_buffer, 0, data, 0, _offset); RmiTrace.send(url, data); } try { output.write(_buffer, 0, _offset); output.flush(); } catch (java.io.IOException ex) { throw new org.omg.CORBA.COMM_FAILURE(ex.toString()); } } // ----------------------------------------------------------------------- // public methods from org.omg.CORBA.portable.OutputStream // ----------------------------------------------------------------------- public void write_boolean(boolean value) { write_align(1, 1); if (value) { _buffer[_offset++] = 1; } else { _buffer[_offset++] = 0; } } public void write_char(char value) { write_align(1, 1); if ((int)value > 255) { throw new org.omg.CORBA.MARSHAL("write_char: value = " + value); } _buffer[_offset++] = (byte)value; } public void write_wchar(char value) { write_octet((byte)2); // size of wchar is 2 bytes write_align(1, 2); write_ushort_no_align_big_endian((int)value); } public void write_octet(byte value) { write_align(1, 1); _buffer[_offset++] = value; } public void write_short(short value) { write_align(2, 2); int oldOffset = _offset; _offset += 2; BigEndian.setShort(_buffer, oldOffset, value); } public void write_ushort(short value) { write_short(value); } public void write_long(int value) { write_align(4, 4); int oldOffset = _offset; _offset += 4; BigEndian.setInt(_buffer, oldOffset, value); } public void write_ulong(int value) { write_long(value); } public void write_longlong(long value) { write_align(8, 8); int oldOffset = _offset; _offset += 8; BigEndian.setLong(_buffer, oldOffset, value); } public void write_ulonglong(long value) { write_longlong(value); } public void write_float(float value) { write_long(Float.floatToIntBits(value)); } public void write_double(double value) { write_longlong(Double.doubleToLongBits(value)); } public void write_string(String value) { if (value == null) { value = ""; } write_align(4, 4); int size = UTF8.fromString(value, _buffer, _offset + 4, _length - 1); if (size == -1) { // No room to convert in-place, ok to allocate new byte array. byte[] bytes = UTF8.fromString(value); size = bytes.length; write_ulong(size + 1); write_octet_array(bytes, 0, size); } else { // Already converted already into _buffer. write_ulong(size + 1); _offset += size; } write_octet((byte)0); } public void write_wstring(String value) { if (value == null) { value = ""; } int size = value.length(); int numBytes = 2 * size; write_ulong(numBytes); // No terminating NUL write_align(1, numBytes); for (int i = 0; i < size; i++) { char c = value.charAt(i); BigEndian.setShort(_buffer, _offset, (short)c); _offset += 2; } } public void write_boolean_array(boolean[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_boolean(value[offset + i]); } } public void write_char_array(char[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_char(value[offset + i]); } } public void write_wchar_array(char[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_wchar(value[offset + i]); } } public void write_octet_array(byte[] value, int offset, int length) { write_align(1, length); System.arraycopy(value, offset, _buffer, _offset, length); _offset += length; } public void write_short_array(short[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_short(value[offset + i]); } } public void write_ushort_array(short[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_ushort(value[offset + i]); } } public void write_long_array(int[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_long(value[offset + i]); } } public void write_ulong_array(int[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_ulong(value[offset + i]); } } public void write_longlong_array(long[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_longlong(value[offset + i]); } } public void write_ulonglong_array(long[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_ulonglong(value[offset + i]); } } public void write_float_array(float[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_float(value[offset + i]); } } public void write_double_array(double[] value, int offset, int length) { for (int i = 0; i < length; i++) { write_double(value[offset + i]); } } public void write_Object(org.omg.CORBA.Object value) { if (value == null) { write_IOR(null); } else if (value instanceof ObjectRef) { ObjectRef ref = (ObjectRef)value; IOR ior = ref.$getIOR(); write_IOR(ior); } else { throw new org.omg.CORBA.MARSHAL(value.getClass().getName()); } } public void write_TypeCode(org.omg.CORBA.TypeCode tc) { write_TypeCode(tc, new java.util.HashMap()); } public void write_Any(org.omg.CORBA.Any value) { org.omg.CORBA.TypeCode tc = value.type(); write_TypeCode(tc); write_Any(value.create_input_stream(), tc); } public void write_Any(org.omg.CORBA.portable.InputStream is, org.omg.CORBA.TypeCode tc) { try { int tk = tc.kind().value(); switch (tk) { case TCKind._tk_null: case TCKind._tk_void: break; case TCKind._tk_TypeCode: write_TypeCode(is.read_TypeCode()); break; case TCKind._tk_any: write_Any(is.read_any()); break; case TCKind._tk_boolean: write_boolean(is.read_boolean()); break; case TCKind._tk_char: write_char(is.read_char()); break; case TCKind._tk_wchar: write_wchar(is.read_wchar()); break; case TCKind._tk_octet: write_octet(is.read_octet()); break; case TCKind._tk_short: write_short(is.read_short()); break; case TCKind._tk_ushort: write_ushort(is.read_ushort()); break; case TCKind._tk_long: write_long(is.read_long()); break; case TCKind._tk_ulong: case TCKind._tk_enum: write_ulong(is.read_ulong()); break; case TCKind._tk_longlong: write_longlong(is.read_longlong()); break; case TCKind._tk_ulonglong: write_ulonglong(is.read_ulonglong()); break; case TCKind._tk_float: write_float(is.read_float()); break; case TCKind._tk_double: write_double(is.read_double()); break; case TCKind._tk_string: write_string(is.read_string()); break; case TCKind._tk_wstring: write_wstring(is.read_wstring()); break; case TCKind._tk_objref: write_Object(is.read_Object()); break; case TCKind._tk_alias: write_Any(is, tc.content_type()); break; case TCKind._tk_array: { int n = tc.length(); org.omg.CORBA.TypeCode c = tc.content_type(); for (int i = 0; i < n; i++) { write_Any(is, c); } } break; case TCKind._tk_sequence: { int n = is.read_ulong(); write_ulong(n); org.omg.CORBA.TypeCode c = tc.content_type(); for (int i = 0; i < n; i++) { write_Any(is, c); } } break; case TCKind._tk_struct: case TCKind._tk_except: { int n = tc.member_count(); for (int i = 0; i < n; i++) { write_Any(is, tc.member_type(i)); } } break; case TCKind._tk_union: { org.omg.CORBA.TypeCode dt = tc.discriminator_type(); org.omg.CORBA.Any disc = read_disc(is, dt); write_Any(disc.create_input_stream(), dt); int di = tc.default_index(); int i, n = tc.member_count(); for (i = 0; i < n; i++) { org.omg.CORBA.Any label = tc.member_label(i); if (label.equal(disc)) { write_Any(is, tc.member_type(i)); } } if (i == n && di >= 0) { write_Any(is, tc.member_type(di)); } } break; case TCKind._tk_fixed: // TODO case TCKind._tk_value: // TODO default: throw new org.omg.CORBA.MARSHAL("write_Any: type = " + tc); } } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { throw new org.omg.CORBA.MARSHAL("write_Any: " + ex.toString()); } catch (org.omg.CORBA.TypeCodePackage.Bounds ex) { throw new org.omg.CORBA.MARSHAL("write_Any: " + ex.toString()); } } public void write_any(org.omg.CORBA.Any value) { throw new org.omg.CORBA.NO_IMPLEMENT("write_any: NOT IMPLMENTED"); } public void write_Principal(org.omg.CORBA.Principal value) { throw new org.omg.CORBA.NO_IMPLEMENT("write_Principal: NOT IMPLMENTED"); } public void write(int value) throws java.io.IOException { throw new org.omg.CORBA.NO_IMPLEMENT("write: NOT IMPLMENTED"); } public void write_fixed(java.math.BigDecimal value) { throw new org.omg.CORBA.NO_IMPLEMENT("write_fixed: NOT IMPLMENTED"); } public void write_Context(org.omg.CORBA.Context context, org.omg.CORBA.ContextList list) { throw new org.omg.CORBA.NO_IMPLEMENT("write_Context: NOT IMPLMENTED"); } public org.omg.CORBA.ORB orb() { throw new org.omg.CORBA.NO_IMPLEMENT("orb: NOT IMPLMENTED"); } // ----------------------------------------------------------------------- // public methods from org.omg.CORBA_2_3.portable.OutputStream // ----------------------------------------------------------------------- public void write_value(java.io.Serializable value) { throw new org.omg.CORBA.NO_IMPLEMENT("write_value: NOT IMPLMENTED"); } public void write_value(java.io.Serializable value, Class _class) { throw new org.omg.CORBA.NO_IMPLEMENT("write_value: NOT IMPLMENTED"); } public void write_value(java.io.Serializable value, String id) { throw new org.omg.CORBA.NO_IMPLEMENT("write_value: NOT IMPLMENTED"); } public void write_value(java.io.Serializable value, org.omg.CORBA.portable.BoxedValueHelper helper) { throw new org.omg.CORBA.NO_IMPLEMENT("write_value: NOT IMPLMENTED"); } public void write_abstract_interface(java.lang.Object value) { throw new org.omg.CORBA.NO_IMPLEMENT("write_abstract_interface: NOT IMPLMENTED"); } // doing this specifically to handle Any. This implementation // could be worng but will work for us public org.omg.CORBA.portable.InputStream create_input_stream() { CdrInputStream is = CdrInputStream.getInstance(); is._buffer = new byte[_buffer.length]; System.arraycopy(_buffer,0,is._buffer,0,_buffer.length); is._length = _buffer.length; is._offset = 0; return is; } // ----------------------------------------------------------------------- // protected methods // ----------------------------------------------------------------------- protected void pool(byte[] oldBuffer) { if (oldBuffer.length <= MAXIMUM_POOLED_BUFFER_LENGTH) { _pooledBuffer = oldBuffer; } } protected final void write_ushort_no_align_big_endian(int value) { int oldOffset = _offset; _offset += 2; BigEndian.setShort(_buffer, oldOffset, (short)value); } protected void write_IOR(IOR ior) { if (ior == null) { ior = NULL_IOR; } IORHelper.write(this, ior); } public int begin() { write_ulong(0); int saveOffset = _offset; write_boolean(false); return saveOffset; } public void end(int saveOffset) { int endOffset = _offset; _offset = saveOffset - 4; write_ulong(endOffset - saveOffset); _offset = endOffset; } private void write_TypeCode(org.omg.CORBA.TypeCode tc, java.util.HashMap table) { try { int tk = tc.kind().value(); // Check if we need to write an indirection switch (tk) { case TCKind._tk_struct: case TCKind._tk_union: case TCKind._tk_value: String id = tc.id(); if (! id.equals("")) { Integer key = (Integer)table.get(id); if (key != null) { write_ulong(0xffffffff); write_long(key.intValue() - _offset); return; } table.put(id, new Integer(_offset)); } } write_ulong(tk); switch (tk) { case TCKind._tk_null: case TCKind._tk_void: case TCKind._tk_TypeCode: case TCKind._tk_any: case TCKind._tk_boolean: case TCKind._tk_char: case TCKind._tk_wchar: case TCKind._tk_octet: case TCKind._tk_short: case TCKind._tk_ushort: case TCKind._tk_long: case TCKind._tk_ulong: case TCKind._tk_longlong: case TCKind._tk_ulonglong: case TCKind._tk_float: case TCKind._tk_double: case TCKind._tk_longdouble: // All these require only a TCKind. break; case TCKind._tk_fixed: write_ushort(tc.fixed_digits()); write_short(tc.fixed_scale()); break; case TCKind._tk_string: case TCKind._tk_wstring: write_ulong(tc.length()); break; case TCKind._tk_objref: case TCKind._tk_native: case TCKind._tk_abstract_interface: { int saveOffset = begin(); write_string(tc.id()); write_string(tc.name()); end(saveOffset); } break; case TCKind._tk_alias: case TCKind._tk_value_box: { int saveOffset = begin(); write_string(tc.id()); write_string(tc.name()); write_TypeCode(tc.content_type(), table); end(saveOffset); } break; case TCKind._tk_sequence: case TCKind._tk_array: { int saveOffset = begin(); write_TypeCode(tc.content_type(), table); write_ulong(tc.length()); end(saveOffset); } break; case TCKind._tk_enum: { int saveOffset = begin(); write_string(tc.id()); write_string(tc.name()); int count = tc.member_count(); write_ulong(count); for (int i = 0; i < count; i++) { write_string(tc.member_name(i)); } end(saveOffset); } break; case TCKind._tk_struct: case TCKind._tk_except: { int saveOffset = begin(); write_string(tc.id()); write_string(tc.name()); int count = tc.member_count(); write_ulong(count); for (int i = 0; i < count; i++) { write_string(tc.member_name(i)); write_TypeCode(tc.member_type(i), table); } end(saveOffset); } break; case TCKind._tk_union: { int saveOffset = begin(); write_string(tc.id()); write_string(tc.name()); org.omg.CORBA.TypeCode dt = tc.discriminator_type(); write_TypeCode(dt, table); int di = tc.default_index(); write_ulong(di); int count = tc.member_count(); write_ulong(count); for (int i = 0; i < count; i++) { write_Any(tc.member_label(i).create_input_stream(), dt); write_string(tc.member_name(i)); write_TypeCode(tc.member_type(i), table); } end(saveOffset); } break; case TCKind._tk_value: { int saveOffset = begin(); write_string(tc.id()); write_string(tc.name()); write_short(tc.type_modifier()); write_TypeCode(tc.concrete_base_type(), table); int count = tc.member_count(); write_ulong(count); for (int i = 0; i < count; i++) { write_string(tc.member_name(i)); write_TypeCode(tc.member_type(i), table); write_short(tc.member_visibility(i)); } end(saveOffset); } break; default: throw new org.omg.CORBA.MARSHAL("write_TypeCode: kind = " + tk); } } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { throw new org.omg.CORBA.MARSHAL(ex.toString()); } catch (org.omg.CORBA.TypeCodePackage.Bounds ex) { throw new org.omg.CORBA.MARSHAL(ex.toString()); } } private org.omg.CORBA.Any read_disc(org.omg.CORBA.portable.InputStream is, org.omg.CORBA.TypeCode dt) { int tk = dt.kind().value(); if (tk == TCKind._tk_alias) { try { return read_disc(is, dt.content_type()); } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { throw new org.omg.CORBA.MARSHAL("read_disc: " + ex.toString()); } } org.omg.CORBA.Any disc = new org.apache.geronimo.interop.rmi.iiop.Any(); switch (tk) { case TCKind._tk_boolean: disc.insert_boolean(is.read_boolean()); break; case TCKind._tk_octet: disc.insert_octet(is.read_octet()); break; case TCKind._tk_short: disc.insert_short(is.read_short()); break; case TCKind._tk_ushort: disc.insert_ushort(is.read_ushort()); break; case TCKind._tk_long: disc.insert_long(is.read_long()); break; case TCKind._tk_ulong: case TCKind._tk_enum: disc.insert_ulong(is.read_ulong()); break; case TCKind._tk_longlong: disc.insert_longlong(is.read_longlong()); break; case TCKind._tk_ulonglong: disc.insert_ulonglong(is.read_ulonglong()); break; default: throw new org.omg.CORBA.MARSHAL("read_disc: type = " + dt); } return disc; } }