/** * * 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 java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.zip.GZIPInputStream; import org.apache.geronimo.interop.SystemException; import org.apache.geronimo.interop.rmi.RmiTrace; import org.apache.geronimo.interop.rmi.iiop.client.ClientNamingContext; import org.apache.geronimo.interop.rmi.iiop.compiler.StubFactory; 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.LittleEndian; import org.apache.geronimo.interop.util.ThreadContext; import org.apache.geronimo.interop.util.UTF8; import org.apache.geronimo.interop.util.UnsignedShort; import org.omg.CORBA.TCKind; import org.omg.GIOP.LocateRequestHeader_1_0; import org.omg.GIOP.LocateRequestHeader_1_0Helper; import org.omg.GIOP.LocateRequestHeader_1_2; import org.omg.GIOP.LocateRequestHeader_1_2Helper; import org.omg.GIOP.MsgType_1_1; 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.TargetAddress; import org.omg.IOP.IOR; import org.omg.IOP.IORHelper; /** ** CORBA 2.3 / GIOP 1.2 CDR InputStream. **/ public class CdrInputStream extends org.omg.CORBA_2_3.portable.InputStream { public static CdrInputStream getInstance() { CdrInputStream input = new CdrInputStream(); input.init(new byte[64], 0, DEFAULT_BUFFER_LENGTH, false); return input; } public static CdrInputStream getInstance(byte[] buffer) { CdrInputStream input = new CdrInputStream(); input.init(buffer, 0, buffer.length, false); return input; } public static CdrInputStream getInstance(byte[] buffer, int offset, int length, boolean little) { CdrInputStream input = new CdrInputStream(); input.init(buffer, offset, length, little); return input; } public static CdrInputStream getInstanceForEncapsulation() { return getInstance(); } public static CdrInputStream getPooledInstance() { CdrInputStream input = null; if (input == null) { input = getInstance(); } return input; } // ----------------------------------------------------------------------- // private data // ----------------------------------------------------------------------- private static final int DEFAULT_BUFFER_LENGTH = 64; private static final int MAXIMUM_POOLED_BUFFER_LENGTH = 1024; private static boolean RMI_TRACE = true; private static final byte[] EMPTY_BYTE_ARRAY = {}; private GiopMessage _giopMessage; private boolean _moreFragments; private ClientNamingContext _namingContext; private boolean _unaligned; private byte[] _pooledBuffer; private boolean _gzip; // ----------------------------------------------------------------------- // package-private data // ----------------------------------------------------------------------- byte[] _buffer; int _offset; int _length; boolean _little; // ----------------------------------------------------------------------- // public methods // ----------------------------------------------------------------------- public void init(byte[] buffer, int offset, int length, boolean little) { _buffer = buffer; _offset = offset; _length = length; _little = little; } 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; _little = false; _namingContext = null; } public void setUnaligned() { _unaligned = true; } public byte[] getBytes() { return ArrayUtil.getBytes(_buffer, 0, _length); } public byte[] getBuffer() { return _buffer; } public int getOffset() { return _offset; } public int getGiopVersion() { GiopMessage message = _giopMessage; if (message == null) { throw new IllegalStateException(); } return message.giopVersion; } public void setGiopVersion(int giopVersion) { // TODO!!! } public void setLength(int length) { if (_buffer.length < length) { byte[] newBuffer = new byte[length]; System.arraycopy(_buffer, 0, newBuffer, 0, 12); pool(_buffer); _buffer = newBuffer; } _length = length; } public ClientNamingContext getNamingContext() { return _namingContext; } public void setNamingContext(ClientNamingContext namingContext) { _namingContext = namingContext; } public void setEncapsulation(byte[] data) { _buffer = data; _offset = 0; _length = data.length; _little = read_boolean(); } public boolean hasMoreData() { return _offset < _length; } /** ** Align the buffer offset so the next item is read from at an offset ** aligned according to <code>alignment</code>, which must be a ** power of 2 (and at least = 1). ** <p>Then we check if there is enough space left in the buffer for ** an item of <code>size</code> bytes; if not, we throw an ** exception. **/ public final void read_align(int alignment, int size) { if (_unaligned) { alignment = 1; } int mask = alignment - 1; _offset += (alignment - (_offset & mask)) & mask; if (_offset + size <= _length) { return; } else { throw new org.omg.CORBA.MARSHAL("offset (" + _offset + ") + size (" + size + ") > buffer length (" + _length + ")"); } } /** ** Convenience method needed in many places. **/ public byte[] read_octet_sequence() { int n = read_long(); if (n == 0) { return EMPTY_BYTE_ARRAY; } byte[] bytes = new byte[n]; read_octet_array(bytes, 0, n); return bytes; } public GiopMessage read_message() { return receive_message(null, null); } public GiopMessage receive_message(java.io.InputStream input, String url) { return receive_message(input, url, true); } public GiopMessage receive_message(java.io.InputStream input, String url, boolean readFragments) { GiopMessage message = _giopMessage; if (message == null) { message = _giopMessage = new GiopMessage(); } if (input != null) { read(input, _buffer, 0, 12); } int m1 = read_octet(); int m2 = read_octet(); int m3 = read_octet(); int m4 = read_octet(); if (m1 != 'G' || m2 != 'I' || m3 != 'O' || m4 != 'P') { if (m1 == 'G' && m2 == 'Z' && m3 == 'I' && m4 == 'P') { _gzip = true; } else if ((m1 == 'P' || m1 == 'p') && (m2 == 'O' || m2 == 'o') && (m3 == 'S' || m3 == 's') && (m4 == 'T' || m4 == 't')) { return receive_http_post_message(input, url); } else if( (m1 == 'G' || m1 == 'g') && (m2 == 'E' || m2 == 'e') && (m3 == 'T' || m3 == 't') && m4 == ' ') { return receive_http_get_message(input, url); } else { throw new BadMagicException(m1 + "," + m2 + "," + m3 + "," + m4); } } else { _gzip = false; } int v1 = read_octet(); int v2 = read_octet(); if (v1 != 1 || (v2 < 0 || v2 > 2)) // support GIOP 1.0, 1.1, 1.2 { throw new UnsupportedProtocolVersionException(v1 + "." + v2); } int giopVersion; message.giopVersion = giopVersion = v2; int flags = read_octet(); _little = (flags & 1) != 0; _moreFragments = (flags & 2) != 0; int messageType = message.type = read_octet(); int messageSize = message.size = read_ulong(); _length = 12 + messageSize; if (_moreFragments && _length % 8 != 0) { throw new org.omg.CORBA.MARSHAL("GIOP Fragment: bad message size (not divisible by 8) = " + messageSize); } if (messageSize > 0 && input != null) { if (_buffer.length < _length) { byte[] newBuffer = new byte[_length]; System.arraycopy(_buffer, 0, newBuffer, 0, 12); pool(_buffer); _buffer = newBuffer; } read(input, _buffer, 12, _length); } if (RMI_TRACE && url != null) { byte[] data = new byte[_length]; System.arraycopy(_buffer, 0, data, 0, _length); RmiTrace.receive(url, data); } if (_moreFragments && readFragments) { read_fragments(input, url); } switch (messageType) { case MsgType_1_1._Fragment: break; case MsgType_1_1._Request: switch (giopVersion) { case GiopVersion.VERSION_1_0: { RequestHeader_1_0 req10 = RequestHeader_1_0Helper.read(this); RequestHeader_1_2 req12 = new RequestHeader_1_2(); req12.service_context = req10.service_context; req12.request_id = req10.request_id; req12.response_flags = (byte)(req10.response_expected ? 3 : 0); req12.operation = req10.operation; (req12.target = new TargetAddress()).object_key(req10.object_key); message.request = req12; } break; case GiopVersion.VERSION_1_1: { RequestHeader_1_1 req11 = RequestHeader_1_1Helper.read(this); RequestHeader_1_2 req12 = new RequestHeader_1_2(); req12.service_context = req11.service_context; req12.request_id = req11.request_id; req12.response_flags = (byte)(req11.response_expected ? 3 : 0); req12.operation = req11.operation; (req12.target = new TargetAddress()).object_key(req11.object_key); message.request = req12; } break; case GiopVersion.VERSION_1_2: message.request = RequestHeader_1_2Helper.read(this); if (_length > _offset) { read_align(8, 0); // parameters are 8-byte aligned (if present) } break; } if (_gzip) { unzip(); } break; case MsgType_1_1._Reply: message.reply = ReplyHeader_1_2Helper.read(this); if (giopVersion >= GiopVersion.VERSION_1_2) { if (_length > _offset) { read_align(8, 0); // results are 8-byte aligned (if present) } } if (_gzip) { unzip(); } break; case MsgType_1_1._LocateRequest: switch (giopVersion) { case GiopVersion.VERSION_1_0: case GiopVersion.VERSION_1_1: { LocateRequestHeader_1_0 req10 = LocateRequestHeader_1_0Helper.read(this); LocateRequestHeader_1_2 req12 = new LocateRequestHeader_1_2(); req12.request_id = req10.request_id; (req12.target = new TargetAddress()).object_key(req10.object_key); message.locateRequest = req12; } break; default: message.locateRequest = LocateRequestHeader_1_2Helper.read(this); } break; case MsgType_1_1._LocateReply: // We never send LocateRequest, so this is unexpected. throw new org.omg.CORBA.MARSHAL("GIOP LocateReply: unexpected"); // TODO: CloseConnection messages etc... default: throw new org.omg.CORBA.NO_IMPLEMENT("TODO: message type = " + messageType); } return message; } private GiopMessage receive_http_post_message(java.io.InputStream input, String url) { int ver = http_read_hiop_version(input); //skip headers and read content length boolean cLenRead = false; int clen = 0, count; while( (count = http_read_line(input, 0)) != 0) { if( (_buffer[0] == 'c' || _buffer[0] == 'C')) { String str = new String(_buffer, 0, count).toLowerCase(); if(str.startsWith("content-length:")) { str = str.substring(15).trim(); try { clen = java.lang.Integer.parseInt(str); } catch(Exception e) { throw new SystemException(e.toString()); } cLenRead = true; } } } if(!cLenRead) { throw new SystemException("HTTP Post: Missing content-length"); } java.io.InputStream msgInput = input; if(ver == 1) { byte[] buffer = new byte[clen]; read(input, buffer, 0, clen); String data = new String(buffer, 8, buffer.length - 8); //skip MESSAGE= byte[] giopdata = org.apache.geronimo.interop.util.Base16Binary.fromString(data); ByteArrayInputStream bi = new ByteArrayInputStream(giopdata); msgInput = bi; } _offset = 0; GiopMessage gm = receive_message(msgInput, url, false); gm.httpTunneling = true; gm.hiopVersion = ver; return gm; } /** * Format: Get /host/port/HIOP/1.0/hex-data */ protected GiopMessage receive_http_get_message(java.io.InputStream input, String url) { //We have already read first 12 bytes ( = sizeof(GIOP header) ) int count = http_read_line(input, 12); String str = new String(_buffer, 0, count); int index = str.indexOf("/HIOP/1.0/"); if(index == -1) { throw new SystemException("HTTP Tunnelling: HIOP version error"); } index += 10; if( index >= count) { throw new SystemException("HTTP Tunneling: GET message error"); } byte[] giopdata = org.apache.geronimo.interop.util.Base16Binary.fromString(str.substring(index)); ByteArrayInputStream bi = new ByteArrayInputStream(giopdata); GiopMessage gm = receive_message(bi, url, false); gm.httpTunneling = true; gm.hiopVersion = 1; return gm; } /** * Note that we consider that the client always uses HIOP/2.0. Hence, the * iiop data is binary stream instead of base64 hex string. */ public GiopMessage receive_http_response(java.io.InputStream input, String url) { //read status: HTTP/1.1 200 OK int count = http_read_line(input, 0); String status = new String(_buffer, 0, count).toLowerCase(); if(!status.startsWith("http/1.1") && !status.startsWith("http/1.0")) { throw new SystemException("HTTP response error"); } if(status.indexOf("200") == -1 || status.indexOf("ok") == -1) { throw new SystemException("HTTP response error"); } //skip headers and read content length boolean cLenRead = false; int clen = 0; while( (count = http_read_line(input, 0)) != 0) { if( (_buffer[0] == 'c' || _buffer[0] == 'C')) { String str = new String(_buffer, 0, count).toLowerCase(); if(str.startsWith("content-length:")) { str = str.substring(15).trim(); try { clen = java.lang.Integer.parseInt(str); } catch(Exception e) { throw new SystemException(e.toString()); } cLenRead = true; } } } if(!cLenRead) { throw new SystemException("HTTP Post: Missing Content-Length"); } //now read the iiop stream GiopMessage gm = receive_message(input, url, false); gm.httpTunneling = true; gm.hiopVersion = 2; return gm; } /** * Return the HIOP version (1 or 2) */ private int http_read_hiop_version(java.io.InputStream input) throws java.lang.NumberFormatException { //We have already read first 12 bytes ( = sizeof(GIOP header) ) int count = http_read_line(input, 12); String str = new String(_buffer, 0, count); int index, ver; if((index = str.indexOf("HIOP")) == -1) { throw new SystemException("HTTP: Post Message - HIOP Version not specified"); } else { //HIOP/1.0 or HIOP/2.0 if((index + 8) > count) { throw new SystemException("HTTP: Post Message - Incorrect HIOP header"); } index += 5; if(_buffer[index + 1] != '.' && _buffer[index + 2] != '0') { throw new SystemException("HTTP: Incorrect HIOP version"); } if(_buffer[index] == '1') { ver = 1; } else if (_buffer[index] == '2') { ver = 2; } else { throw new SystemException("HTTP: Incorrect HIOP version"); } } return ver; } /** * Read the line from input stream terminated by CRLF. * CRLF is not part of the data in the buffer. Return the number of bytes in the line */ private int http_read_line(java.io.InputStream input, int offset) //offset in _buffer { try { int b; while ( (b = input.read()) != '\r' ) { if(b == -1) //EOF has been reached { throw new SystemException("HTTP: read error"); } if(_buffer.length <= offset) { byte[] newbuffer = new byte[offset*2]; System.arraycopy(_buffer, 0, newbuffer, 0, _buffer.length); _buffer = newbuffer; } _buffer[offset++] = (byte)b; } // go past the \n character b = input.read(); if ( b != '\n' ) { throw new SystemException("HTTP CRLF combination missing"); } } catch (java.io.IOException ex) { throw new SystemException(ex.toString()); } return offset; } // ----------------------------------------------------------------------- // public methods from org.omg.CORBA.portable.InputStream // ----------------------------------------------------------------------- public boolean read_boolean() { read_align(1, 1); int b = _buffer[_offset++]; if (b == 0) { return false; } else if (b == 1) { return true; } else { throw new org.omg.CORBA.MARSHAL("read_boolean: value = " + b); } } public char read_char() { read_align(1, 1); return (char)_buffer[_offset++]; } public char read_wchar() { read_align(1, 3); int size = (int)read_wchar_size(); int value = (char)read_ushort_no_align_big_endian(); _offset += 2; boolean littleEndian = ((value & 0xffff) == 0xFFFE); boolean bigEndian = ((value & 0xffff) == 0xFEFF); boolean bomPresent = (littleEndian || bigEndian); if ((bomPresent && size != 4) || (! bomPresent && size != 2)) { throw new org.omg.CORBA.MARSHAL("wchar size = " + size + (bomPresent ? " (BOM present)" : " (BOM absent)")); } if (littleEndian) { read_align(1, 2); char ch = (char)read_ushort_no_align_little_endian(); _offset += 2; return ch; } else if (bigEndian) { read_align(1, 2); char ch = (char)read_ushort_no_align_big_endian(); _offset += 2; return ch; } else { // no BOM, big endian return (char)value; } } public byte read_octet() { read_align(1, 1); return _buffer[_offset++]; } public short read_short() { read_align(2, 2); int oldOffset = _offset; _offset += 2; if (_little) { return LittleEndian.getShort(_buffer, oldOffset); } else { return BigEndian.getShort(_buffer, oldOffset); } } public short read_ushort() { return read_short(); } public int read_long() { read_align(4, 4); int oldOffset = _offset; _offset += 4; if (_little) { return LittleEndian.getInt(_buffer, oldOffset); } else { return BigEndian.getInt(_buffer, oldOffset); } } public int read_ulong() { return read_long(); } public long read_longlong() { read_align(8, 8); int oldOffset = _offset; _offset += 8; if (_little) { return LittleEndian.getLong(_buffer, oldOffset); } else { return BigEndian.getLong(_buffer, oldOffset); } } public long read_ulonglong() { return read_longlong(); } public float read_float() { return Float.intBitsToFloat(read_ulong()); } public double read_double() { return Double.longBitsToDouble(read_ulonglong()); } public java.lang.String read_string() { int size = read_ulong(); if (size < 1) // Zero or negative due to unsigned value > 2Gb { throw new org.omg.CORBA.MARSHAL("read_string: size = " + size); } read_align(1, size); size--; if (_buffer[_offset + size] != 0) { throw new org.omg.CORBA.MARSHAL("read_string: missing NUL"); } // Assume transmission code set is UTF-8 String value = size == 0 ? "" : UTF8.toString(_buffer, _offset, size); _offset += size + 1; // 1 for NUL return value; } public java.lang.String read_wstring() { int size = read_long(); if (size == 0) { return ""; } read_align(2, size); int numChars = size / 2; boolean littleEndian = false; read_align(1, 2); int firstChar = (char)read_ushort_no_align_big_endian(); _offset+=2; char[] result; int index = 0; if (firstChar == 0xFEFF) { // big endian result = new char[--numChars]; } else if (firstChar == 0xFFFE) { // little endian result = new char[--numChars]; littleEndian = true; } else { // no BOM, big endian result = new char[numChars--]; result[index++] = (char)firstChar; } read_align(1, 2 * numChars); if (littleEndian) { for (int i = 0; i < numChars; i++) { result[index++] = (char)read_ushort_no_align_little_endian(); _offset+=2; } } else { for (int i = 0; i < numChars; i++) { result[index++] = (char)read_ushort_no_align_big_endian(); _offset+=2; } } return new String(result); } public void read_boolean_array(boolean[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_boolean(); } } public void read_char_array(char[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[i] = read_char(); } } public void read_wchar_array(char[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_wchar(); } } public void read_octet_array(byte[] value, int offset, int length) { read_align(1, length); System.arraycopy(_buffer, _offset, value, offset, length); _offset += length; } public void read_short_array(short[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_short(); } } public void read_ushort_array(short[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_ushort(); } } public void read_long_array(int[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_long(); } } public void read_ulong_array(int[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_ulong(); } } public void read_longlong_array(long[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_longlong(); } } public void read_ulonglong_array(long[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_ulonglong(); } } public void read_float_array(float[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_float(); } } public void read_double_array(double[] value, int offset, int length) { for (int i = 0; i < length; i++) { value[offset + i] = read_double(); } } public org.omg.CORBA.Object read_Object() { IOR ior = IORHelper.read(this); if (ior.profiles.length == 0) { return null; } ObjectRef stub = null; if (ior.type_id.length() != 0) { String interfaceName = ""; if (ior.type_id.startsWith("RMI:") && ior.type_id.endsWith(":0000000000000000")) { interfaceName = ior.type_id.substring(4, ior.type_id.length() - 17); } else if (ior.type_id.startsWith("IDL:") && ior.type_id.endsWith(":1.0")) { interfaceName = ior.type_id.substring(4, ior.type_id.length() - 4).replace('/', '.'); } // Return instance of appropriate stub class if(interfaceName.startsWith("omg.org", 0)) { interfaceName = "org.apache.geronimo.interop" + interfaceName.substring(7); } Class remoteInterface = ThreadContext.loadClass(interfaceName); stub = StubFactory.getInstance().getStub(remoteInterface); } if (stub == null) { stub = ObjectRef._getInstance(); } stub.$setIOR(ior); stub.$setNamingContext(_namingContext); return stub; } public org.omg.CORBA.TypeCode read_TypeCode() { return read_TypeCode(new java.util.HashMap()); } private org.omg.CORBA.TypeCode read_TypeCode(java.util.HashMap table) { int beforeKindOffset = _offset; int tk = read_ulong(); int afterKindOffset = _offset; org.apache.geronimo.interop.rmi.iiop.TypeCode tc; if (tk == 0xffffffff) { // an indirection to another TypeCode we have seen. int offset = read_long(); Integer key = new Integer(afterKindOffset + offset); org.omg.CORBA.TypeCode ref = (org.omg.CORBA.TypeCode)table.get(key); if (ref == null) { throw new org.omg.CORBA.MARSHAL("read_TypeCode: bad indirection: offset = " + offset); } tc = new org.apache.geronimo.interop.rmi.iiop.TypeCode(TCKind.tk_null); tc.indirection(ref); return tc; } tc = new org.apache.geronimo.interop.rmi.iiop.TypeCode(TCKind.from_int(tk)); table.put(new Integer(beforeKindOffset), tc); 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: tc.fixed_digits(read_ushort()); tc.fixed_scale(read_short()); break; case TCKind._tk_string: case TCKind._tk_wstring: tc.length(read_ulong()); break; case TCKind._tk_objref: case TCKind._tk_native: case TCKind._tk_abstract_interface: { boolean saveLittle = begin(); tc.id(read_string()); tc.name(read_string()); end(saveLittle); } break; case TCKind._tk_alias: // Change Here case TCKind._tk_value_box: // End Change Here { boolean saveLittle = begin(); tc.id(read_string()); tc.name(read_string()); tc.content_type(read_TypeCode(table)); end(saveLittle); } break; case TCKind._tk_sequence: case TCKind._tk_array: { boolean saveLittle = begin(); tc.content_type(read_TypeCode(table)); tc.length(read_ulong()); end(saveLittle); } break; case TCKind._tk_enum: { boolean saveLittle = begin(); tc.id(read_string()); tc.name(read_string()); int count = read_ulong(); tc.member_count(count); for (int i = 0; i < count; i++) { tc.member_name(i, read_string()); } end(saveLittle); } break; case TCKind._tk_struct: case TCKind._tk_except: { boolean saveLittle = begin(); tc.id(read_string()); tc.name(read_string()); int count = read_ulong(); tc.member_count(count); for (int i = 0; i < count; i++) { tc.member_name(i, read_string()); tc.member_type(i, read_TypeCode(table)); } end(saveLittle); } break; case TCKind._tk_union: { boolean saveLittle = begin(); tc.id(read_string()); tc.name(read_string()); org.omg.CORBA.TypeCode dt = read_TypeCode(table); tc.discriminator_type(dt); int di = read_ulong(); int count = read_ulong(); tc.member_count(count); for (int i = 0; i < count; i++) { org.omg.CORBA.Any label = new org.apache.geronimo.interop.rmi.iiop.Any(); read_Any(label.create_output_stream(), dt); label.read_value(null, dt); tc.member_label(i, label); tc.member_name(i, read_string()); tc.member_type(i, read_TypeCode(table)); } tc.default_index(di); // must call after setting members end(saveLittle); } break; case TCKind._tk_value: { boolean saveLittle = begin(); tc.id(read_string()); tc.name(read_string()); tc.type_modifier(read_short()); tc.concrete_base_type(read_TypeCode(table)); int count = read_ulong(); tc.member_count(count); for (int i = 0; i < count; i++) { tc.member_name(i, read_string()); tc.member_type(i, read_TypeCode(table)); tc.member_visibility(i, read_short()); } end(saveLittle); } break; default: throw new org.omg.CORBA.MARSHAL("read_TypeCode: kind = " + tk); } return tc; } public org.omg.CORBA.Any read_Any() { org.omg.CORBA.TypeCode tc = read_TypeCode(); org.omg.CORBA.Any value = new org.apache.geronimo.interop.rmi.iiop.Any(); org.omg.CORBA.portable.OutputStream os = value.create_output_stream(); read_Any(os, tc); value.read_value(os.create_input_stream(), tc); return value; } public void read_Any(org.omg.CORBA.portable.OutputStream os, 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: os.write_TypeCode(read_TypeCode()); break; case TCKind._tk_any: os.write_any(read_Any()); break; case TCKind._tk_boolean: os.write_boolean(read_boolean()); break; case TCKind._tk_char: os.write_char(read_char()); break; case TCKind._tk_wchar: os.write_wchar(read_wchar()); break; case TCKind._tk_octet: os.write_octet(read_octet()); break; case TCKind._tk_short: os.write_short(read_short()); break; case TCKind._tk_ushort: os.write_ushort(read_ushort()); break; case TCKind._tk_long: os.write_long(read_long()); break; case TCKind._tk_ulong: case TCKind._tk_enum: os.write_ulong(read_ulong()); break; case TCKind._tk_longlong: os.write_longlong(read_longlong()); break; case TCKind._tk_ulonglong: os.write_ulonglong(read_ulonglong()); break; case TCKind._tk_float: os.write_float(read_float()); break; case TCKind._tk_double: os.write_double(read_double()); break; case TCKind._tk_string: os.write_string(read_string()); break; case TCKind._tk_wstring: os.write_wstring(read_wstring()); break; case TCKind._tk_objref: os.write_Object(read_Object()); break; case TCKind._tk_alias: read_Any(os, 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++) { read_Any(os, c); } } break; case TCKind._tk_sequence: { int n = read_ulong(); os.write_ulong(n); org.omg.CORBA.TypeCode c = tc.content_type(); for (int i = 0; i < n; i++) { read_Any(os, c); } } break; case TCKind._tk_struct: case TCKind._tk_except: { int n = tc.member_count(); for (int i = 0; i < n; i++) { read_Any(os, tc.member_type(i)); } } break; case TCKind._tk_union: { org.omg.CORBA.TypeCode dt = tc.discriminator_type(); org.omg.CORBA.Any disc = new org.apache.geronimo.interop.rmi.iiop.Any(); read_Any(disc.create_output_stream(), dt); disc.read_value(null, dt); write_disc(disc, os, 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)) { read_Any(os, tc.member_type(i)); break; } } if (i == n && di >= 0) { read_Any(os, tc.member_type(di)); } } break; case TCKind._tk_fixed: // TODO case TCKind._tk_value: // TODO default: throw new org.omg.CORBA.MARSHAL("read_Any: type = " + tc); } } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { throw new org.omg.CORBA.MARSHAL("read_Any: " + ex.toString()); } catch (org.omg.CORBA.TypeCodePackage.Bounds ex) { throw new org.omg.CORBA.MARSHAL("read_Any: " + ex.toString()); } } public org.omg.CORBA.Any read_any() { throw new org.omg.CORBA.NO_IMPLEMENT("read_any: NOT IMPLMENTED"); } public org.omg.CORBA.Principal read_Principal() { throw new org.omg.CORBA.NO_IMPLEMENT("read_Principal: NOT IMPLMENTED"); } public int read() throws java.io.IOException { throw new org.omg.CORBA.NO_IMPLEMENT("read: NOT IMPLMENTED"); } public java.math.BigDecimal read_fixed() { throw new org.omg.CORBA.NO_IMPLEMENT("read_fixed: NOT IMPLMENTED"); } public org.omg.CORBA.Context read_Context() { throw new org.omg.CORBA.NO_IMPLEMENT("read_Context: NOT IMPLMENTED"); } public org.omg.CORBA.Object read_Object(Class _class) { throw new org.omg.CORBA.NO_IMPLEMENT("read_Object: 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.InputStream // ----------------------------------------------------------------------- public java.io.Serializable read_value() { throw new org.omg.CORBA.NO_IMPLEMENT("read_value: NOT IMPLMENTED"); } public java.io.Serializable read_value(Class _class) { throw new org.omg.CORBA.NO_IMPLEMENT("read_value: NOT IMPLMENTED"); } public java.io.Serializable read_value(org.omg.CORBA.portable.BoxedValueHelper helper) { throw new org.omg.CORBA.NO_IMPLEMENT("read_value: NOT IMPLMENTED"); } public java.io.Serializable read_value(java.lang.String id) { throw new org.omg.CORBA.NO_IMPLEMENT("read_value: NOT IMPLMENTED"); } public java.io.Serializable read_value(java.io.Serializable todo) { throw new org.omg.CORBA.NO_IMPLEMENT("read_value: NOT IMPLMENTED"); } public java.lang.Object read_abstract_interface() { throw new org.omg.CORBA.NO_IMPLEMENT("read_abstract_interface: NOT IMPLMENTED"); } public java.lang.Object read_abstract_interface(Class _class) { throw new org.omg.CORBA.NO_IMPLEMENT("read_abstract_interface: NOT IMPLMENTED"); } // ----------------------------------------------------------------------- // protected methods // ----------------------------------------------------------------------- protected void pool(byte[] oldBuffer) { if (oldBuffer.length <= MAXIMUM_POOLED_BUFFER_LENGTH) { _pooledBuffer = oldBuffer; } } protected int read_ushort_no_align_big_endian() { return UnsignedShort.intValue(BigEndian.getShort(_buffer, _offset)); } protected int read_ushort_no_align_little_endian() { return UnsignedShort.intValue(LittleEndian.getShort(_buffer, _offset)); } protected int read_wchar_size() { read_align(1, 1); int size = _buffer[_offset++]; if (size < 2) { throw new org.omg.CORBA.MARSHAL("wchar size = " + size); } return size; } protected void read(java.io.InputStream input, byte[] buffer, int offset, int length) { try { while (offset < length) { int needLength = length - offset; int readLength = input.read(buffer, offset, needLength); if (readLength == -1) { throw new org.omg.CORBA.MARSHAL("read: EOF"); } offset += readLength; } } catch (java.io.IOException ex) { throw new org.omg.CORBA.COMM_FAILURE(ex.toString()); } } protected void read_fragments(java.io.InputStream input, String url) { int messageType = _giopMessage.type; int length = _giopMessage.size + 12; byte[] fullBuffer = ArrayUtil.getBytes(_buffer, 0, length); do { _offset = 0; receive_message(input, url, false); if (_giopMessage.type != MsgType_1_1._Fragment) { throw new org.omg.CORBA.MARSHAL("GIOP Fragment: bad fragment type = " + _giopMessage.type); } int addSize = _giopMessage.size - 4; //skip fragment structure int needLength = length + addSize; if (needLength > fullBuffer.length) { byte[] newBuffer = new byte[needLength * 2]; System.arraycopy(fullBuffer, 0, newBuffer, 0, length); fullBuffer = newBuffer; } System.arraycopy(_buffer, 16, fullBuffer, length, addSize); length += addSize; } while (_moreFragments); _giopMessage.type = messageType; _giopMessage.size = length - 12; _buffer = fullBuffer; _offset = 12; _length = length; } public boolean begin() { int length = read_ulong(); // encapsulation length int len2 = read_ulong(); // another chunk length? if( len2 != length - 4) { _offset -= 4; } boolean saveLittle = _little; _little = read_boolean(); return saveLittle; } public void end(boolean saveLittle) { _little = saveLittle; } private void write_disc(org.omg.CORBA.Any disc, org.omg.CORBA.portable.OutputStream os, org.omg.CORBA.TypeCode dt) { int tk = dt.kind().value(); if (tk == TCKind._tk_alias) { try { write_disc(disc, os, dt.content_type()); } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { throw new org.omg.CORBA.MARSHAL("write_disc: " + ex.toString()); } } switch (tk) { case TCKind._tk_boolean: os.write_boolean(disc.extract_boolean()); break; case TCKind._tk_octet: os.write_octet(disc.extract_octet()); break; case TCKind._tk_short: os.write_short(disc.extract_short()); break; case TCKind._tk_ushort: os.write_ushort(disc.extract_ushort()); break; case TCKind._tk_long: os.write_long(disc.extract_long()); break; case TCKind._tk_ulong: case TCKind._tk_enum: os.write_ulong(disc.extract_ulong()); break; case TCKind._tk_longlong: os.write_longlong(disc.extract_longlong()); break; case TCKind._tk_ulonglong: os.write_ulonglong(disc.extract_ulonglong()); break; default: throw new org.omg.CORBA.MARSHAL("write_disc: type = " + dt); } } protected void unzip() { try { int n = _length - _offset; ByteArrayInputStream bi = new ByteArrayInputStream(_buffer, _offset, n); ByteArrayOutputStream bo = new ByteArrayOutputStream(n * 4); GZIPInputStream gi = new GZIPInputStream(bi); int b; while ((b = gi.read()) != -1) { bo.write(b); } byte[] bytes = bo.toByteArray(); int newLength = _offset + bytes.length; if (newLength > _buffer.length) { byte[] newBuffer = new byte[newLength]; System.arraycopy(_buffer, 0, newBuffer, 0, _offset); _buffer = newBuffer; } System.arraycopy(bytes, 0, _buffer, _offset, bytes.length); _length = newLength; } catch (Exception ex) { throw new org.omg.CORBA.MARSHAL(ExceptionUtil.getStackTrace(ex)); } } }