0001: /*
0002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003: *
0004: * This file is part of Resin(R) Open Source
0005: *
0006: * Each copy or derived work must preserve the copyright notice and this
0007: * notice unmodified.
0008: *
0009: * Resin Open Source is free software; you can redistribute it and/or modify
0010: * it under the terms of the GNU General Public License as published by
0011: * the Free Software Foundation; either version 2 of the License, or
0012: * (at your option) any later version.
0013: *
0014: * Resin Open Source is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017: * of NON-INFRINGEMENT. See the GNU General Public License for more
0018: * details.
0019: *
0020: * You should have received a copy of the GNU General Public License
0021: * along with Resin Open Source; if not, write to the
0022: *
0023: * Free Software Foundation, Inc.
0024: * 59 Temple Place, Suite 330
0025: * Boston, MA 02111-1307 USA
0026: *
0027: * @author Scott Ferguson
0028: */
0029:
0030: package com.caucho.iiop;
0031:
0032: import com.caucho.iiop.orb.*;
0033: import com.caucho.iiop.any.*;
0034: import com.caucho.server.util.CauchoSystem;
0035: import com.caucho.util.ByteBuffer;
0036: import com.caucho.util.CharBuffer;
0037: import com.caucho.util.IntArray;
0038: import com.caucho.util.L10N;
0039: import com.caucho.transaction.*;
0040: import com.caucho.vfs.*;
0041:
0042: import org.omg.CORBA.Principal;
0043: import org.omg.CORBA.TCKind;
0044: import org.omg.CORBA.TypeCode;
0045: import org.omg.CORBA.portable.IndirectionException;
0046: import org.omg.SendingContext.RunTime;
0047:
0048: import javax.rmi.CORBA.Util;
0049: import javax.rmi.CORBA.ValueHandler;
0050: import java.io.EOFException;
0051: import java.io.IOException;
0052: import java.io.Serializable;
0053: import java.lang.reflect.Proxy;
0054: import java.util.ArrayList;
0055: import java.util.HashMap;
0056: import java.util.logging.Logger;
0057:
0058: public class IiopReader extends org.omg.CORBA_2_3.portable.InputStream {
0059: protected static final L10N L = new L10N(IiopReader.class);
0060: protected static final Logger log = Logger
0061: .getLogger(IiopReader.class.getName());
0062:
0063: public static final int MSG_REQUEST = 0;
0064: public static final int MSG_REPLY = 1;
0065: public static final int MSG_CANCEL_REQUEST = 2;
0066: public static final int MSG_LOCATE_REQUEST = 3;
0067: public static final int MSG_LOCATE_REPLY = 4;
0068: public static final int MSG_CLOSE_CONNECTION = 5;
0069: public static final int MSG_ERROR = 6;
0070: public static final int MSG_FRAGMENT = 7;
0071:
0072: public static final int SERVICE_TRANSACTION = 0;
0073: public static final int SERVICE_CODE_SET = 1;
0074: public static final int SERVICE_CHAIN_BYPASS_CHECK = 2;
0075: public static final int SERVICE_CHAIN_BYPASS_INFO = 3;
0076: public static final int SERVICE_LOGICAL_THREAD_ID = 4;
0077: public static final int SERVICE_BI_DIR_IIOP = 5;
0078: public static final int SERVICE_SENDING_CONTEXT_RUN_TIME = 6;
0079: public static final int SERVICE_INVOCATION_POLICIES = 7;
0080: public static final int SERVICE_FORWARDED_IDENTITY = 8;
0081: public static final int SERVICE_UNKNOWN_EXCEPTION_INFO = 9;
0082: public static final int SERVICE_RT_CORBA_PRIORITY = 10;
0083: public static final int SERVICE_RT_CORBA_PRIORITY_RANGE = 11;
0084: public static final int SERVICE_FT_GROUP_VERSION = 12;
0085: public static final int SERVICE_FT_REQUEST = 13;
0086: public static final int SERVICE_EXCEPTION_DETAIL_MESSAGE = 14;
0087: public static final int SERVICE_SECURITY_ATTRIBUTE_SERVICE = 15;
0088: public static final int SERVICE_ACTIVITY_SERVICE = 16;
0089: public static final int SERVICE_RMI_CUSTOM_MAX_STREAM_FORMAT = 17;
0090:
0091: public static final int STATUS_NO_EXCEPTION = 0;
0092: public static final int STATUS_USER_EXCEPTION = 1;
0093: public static final int STATUS_SYSTEM_EXCEPTION = 2;
0094: public static final int STATUS_LOCATION_FORWARD = 3;
0095:
0096: private IiopSocketPool _pool;
0097: private ReadWritePair _pair;
0098: private ReadStream _rs;
0099: private byte[] _header = new byte[8];
0100: private byte[] buf = new byte[16];
0101:
0102: private ReaderContext _context;
0103: /*
0104: private IntArray _refOffsets = new IntArray();
0105: private ArrayList<String> _refIds = new ArrayList<String>();
0106: private ArrayList<Class> _refClasses = new ArrayList<Class>();
0107: private ArrayList<Serializable> _refValues = new ArrayList<Serializable>();
0108:
0109: private HashMap<Integer,String> _savedStrings = new HashMap<Integer,String>();
0110: */
0111:
0112: private MessageReader _in;
0113:
0114: private int _major;
0115: private int _minor;
0116: private boolean _isBigEndian;
0117: private boolean _hasMoreFragments;
0118: private int _flags;
0119:
0120: private int _type;
0121:
0122: private int _fragmentOffset;
0123:
0124: private int _chunkEnd = -1;
0125: private int _chunkDepth = 0;
0126:
0127: private int requestId;
0128: private boolean responseExpected;
0129: private ByteBuffer _objectKey = new ByteBuffer();
0130: private CharBuffer _operation = new CharBuffer();
0131: private ByteBuffer principal = new ByteBuffer();
0132:
0133: private XidImpl _xid;
0134:
0135: private char[] _cb = new char[256];
0136:
0137: private ValueHandler _valueHandler = Util.createValueHandler();
0138: private RunTime runTime = _valueHandler.getRunTimeCodeBase();
0139:
0140: private Throwable _unknownExn;
0141:
0142: private ORBImpl _orb;
0143:
0144: public IiopReader() {
0145: }
0146:
0147: public IiopReader(ReadStream rs) {
0148: init(rs);
0149: }
0150:
0151: public IiopReader(IiopSocketPool pool, ReadWritePair pair) {
0152: _pool = pool;
0153: _pair = pair;
0154:
0155: init(pair.getReadStream());
0156: }
0157:
0158: public void setOrb(ORBImpl orb) {
0159: _orb = orb;
0160: }
0161:
0162: /**
0163: * Initialize the reader with a new underlying stream.
0164: *
0165: * @param rs the underlying input stream.
0166: */
0167: public void init(ReadStream rs) {
0168: _rs = rs;
0169: _major = 0;
0170: _minor = 0;
0171: _type = 0;
0172: requestId = 0;
0173: _objectKey.clear();
0174: _operation.clear();
0175: _fragmentOffset = 0;
0176:
0177: _context = new ReaderContext();
0178: }
0179:
0180: public ValueHandler getValueHandler() {
0181: return _valueHandler;
0182: }
0183:
0184: public int getMajorVersion() {
0185: return _major;
0186: }
0187:
0188: public int getMinorVersion() {
0189: return _minor;
0190: }
0191:
0192: public int getRequestType() {
0193: return _type;
0194: }
0195:
0196: public int getRequestId() {
0197: return requestId;
0198: }
0199:
0200: public boolean isBigEndian() {
0201: return _isBigEndian;
0202: }
0203:
0204: public int getOffset() {
0205: return _in.getOffset();
0206: }
0207:
0208: public boolean isResponseExpected() {
0209: return responseExpected;
0210: }
0211:
0212: public ByteBuffer getObjectKey() {
0213: return _objectKey;
0214: }
0215:
0216: public CharBuffer getOperation() {
0217: return _operation;
0218: }
0219:
0220: public XidImpl getXid() {
0221: return _xid;
0222: }
0223:
0224: public boolean readRequest() throws IOException {
0225: int len = _rs.readAll(_header, 0, _header.length);
0226:
0227: if (len < 0)
0228: return false;
0229:
0230: if (_header[0] != 'G' || _header[1] != 'I' || _header[2] != 'O'
0231: || _header[3] != 'P') {
0232: throw new IOException(L.l(
0233: "unknown request {0}, {1}, {2}, {3}", ""
0234: + toCh(_header[0]), "" + toCh(_header[1]),
0235: "" + toCh(_header[2]), "" + toCh(_header[3])));
0236: }
0237:
0238: _major = _header[4];
0239: _minor = _header[5];
0240:
0241: if (_major != 1)
0242: throw new IOException("unknown major");
0243:
0244: _flags = _header[6];
0245: _isBigEndian = (_flags & 1) == 0;
0246: _hasMoreFragments = (_flags & 2) == 2;
0247:
0248: _type = _header[7];
0249:
0250: _in = new InputStreamMessageReader(_rs, !_hasMoreFragments, 0);
0251:
0252: // debug
0253: //System.out.println("---");
0254: //writeHexGroup(_buffer, 0, _length);
0255:
0256: if (_minor == 0) {
0257: switch (_type) {
0258: case MSG_REQUEST:
0259: readRequest10();
0260: break;
0261: case MSG_REPLY:
0262: readReply10();
0263: break;
0264: case MSG_CLOSE_CONNECTION:
0265: return false;
0266: case MSG_ERROR:
0267: throw new RuntimeException(
0268: "MSG_ERROR: unknown protocol error");
0269: default:
0270: throw new RuntimeException();
0271: }
0272: } else if (_minor == 1) {
0273: switch (_type) {
0274: case MSG_REQUEST:
0275: readRequest10();
0276: break;
0277: case MSG_REPLY:
0278: readReply10();
0279: break;
0280: case MSG_CLOSE_CONNECTION:
0281: return false;
0282: case MSG_ERROR:
0283: throw new RuntimeException(
0284: "MSG_ERROR: unknown protocol error");
0285: default:
0286: throw new RuntimeException();
0287: }
0288: } else if (_minor == 2) {
0289: switch (_type) {
0290: case MSG_REQUEST:
0291: readRequest12();
0292: break;
0293: case MSG_REPLY:
0294: readReply12();
0295: break;
0296: case MSG_CLOSE_CONNECTION:
0297: return false;
0298: case MSG_ERROR:
0299: throw new RuntimeException(
0300: "MSG_ERROR: unknown protocol error");
0301: default:
0302: throw new RuntimeException("unknown type: " + _type);
0303: }
0304: } else
0305: throw new IOException("unknown minor");
0306:
0307: return true;
0308: }
0309:
0310: private void readRequest10() throws IOException {
0311: readServiceContextList();
0312: requestId = _in.read_long();
0313: responseExpected = _in.read() != 0;
0314:
0315: readOctetSequence(_objectKey);
0316:
0317: readString(_operation);
0318:
0319: readOctetSequence(principal);
0320: }
0321:
0322: private void readReply10() throws IOException {
0323: readServiceContextList();
0324:
0325: int requestId = _in.read_long();
0326: int status = _in.read_long();
0327:
0328: switch (status) {
0329: case STATUS_NO_EXCEPTION:
0330: //debugTail();
0331: return;
0332:
0333: case STATUS_SYSTEM_EXCEPTION:
0334: String exceptionId = readString();
0335: int minorStatus = _in.read_long();
0336: int completionStatus = _in.read_long();
0337:
0338: if (_unknownExn instanceof RuntimeException)
0339: throw (RuntimeException) _unknownExn;
0340: else if (_unknownExn instanceof Throwable)
0341: throw new RemoteUserException((Throwable) _unknownExn);
0342:
0343: throw new RuntimeException("exception: " + exceptionId);
0344:
0345: case STATUS_USER_EXCEPTION:
0346: String type = read_string();
0347: Object value = read_value();
0348:
0349: if (value instanceof RuntimeException)
0350: throw (RuntimeException) value;
0351: else if (value instanceof Throwable)
0352: throw new RemoteUserException((Throwable) value);
0353:
0354: throw new IOException("user exception: " + value);
0355:
0356: default:
0357: throw new IOException("unknown status: " + status);
0358: }
0359: }
0360:
0361: private void readRequest12() throws IOException {
0362: requestId = _in.read_long();
0363: int flags = read_octet();
0364: responseExpected = flags != 0;
0365:
0366: int disposition = read_long();
0367: readOctetSequence(_objectKey);
0368: readString(_operation);
0369:
0370: readServiceContextList();
0371:
0372: // align(8) is required for IIOP 1.2, in combination of the
0373: // initial offset of 12 to align the data after the 12byte header.
0374: // ejb/1410 vs ejb/1230, ejb/1141 (??)
0375: //_in.align(8);
0376: }
0377:
0378: private void readReply12() throws IOException {
0379: int requestId = _in.read_long();
0380: int status = _in.read_long();
0381: readServiceContextList();
0382:
0383: switch (status) {
0384: case STATUS_NO_EXCEPTION:
0385: //debugTail();
0386: return;
0387:
0388: case STATUS_SYSTEM_EXCEPTION:
0389: String exceptionId = readString();
0390: int minorStatus = _in.read_long();
0391: int completionStatus = _in.read_long();
0392:
0393: // ejb/0fbc, TCK: ejb30/bb/session/stateful/interceptor/method/annotated/runtimeExceptionTest
0394: if (_unknownExn != null) {
0395: if (_unknownExn instanceof java.rmi.RemoteException) {
0396: Throwable cause = _unknownExn.getCause();
0397:
0398: if (cause instanceof RuntimeException) {
0399: throw (RuntimeException) cause;
0400: }
0401: }
0402:
0403: throw new RemoteUserException(_unknownExn);
0404: }
0405:
0406: throw new IOException("exception: " + exceptionId);
0407:
0408: case STATUS_USER_EXCEPTION:
0409: Object value = read_value();
0410:
0411: if (value instanceof RuntimeException)
0412: throw (RuntimeException) value;
0413: else if (value instanceof Throwable)
0414: throw new RemoteUserException((Throwable) value);
0415:
0416: if (value != null)
0417: throw new IOException("user exception: " + value + " "
0418: + value.getClass().getName());
0419: else
0420: throw new IOException("null user exception");
0421:
0422: default:
0423: throw new IOException("unknown status: " + status);
0424: }
0425: }
0426:
0427: private void readServiceContextList() throws IOException {
0428: _xid = null;
0429:
0430: int length = _in.read_long();
0431:
0432: for (int i = 0; i < length; i++) {
0433: int serviceId = _in.read_long();
0434: int dataLength = _in.read_long();
0435:
0436: int startOffset = _in.setOffset(0);
0437:
0438: if (serviceId == SERVICE_CODE_SET) {
0439: int endian = _in.read();
0440: int charSet = _in.read_long();
0441: int wcharSet = _in.read_long();
0442: } else if (serviceId == SERVICE_UNKNOWN_EXCEPTION_INFO) {
0443: int endian = _in.read();
0444:
0445: _unknownExn = (Throwable) read_value();
0446: } else if (serviceId == SERVICE_TRANSACTION) {
0447: int endian = _in.read();
0448:
0449: int timeout = _in.read_long();
0450: int coord = _in.read_long();
0451: int term = _in.read_long();
0452: int format = _in.read_long();
0453: int bqualLength = _in.read_long();
0454: int xidLength = _in.read_long();
0455: byte[] local = new byte[bqualLength];
0456: byte[] global = new byte[xidLength - bqualLength];
0457: _in.read(global, 0, global.length);
0458: _in.read(local, 0, local.length);
0459: int parents = _in.read_long();
0460:
0461: XidImpl xid = new XidImpl(global, local);
0462:
0463: _xid = xid;
0464: } else {
0465: _in.skip(dataLength);
0466: }
0467:
0468: _in.addOffset(startOffset);
0469: }
0470: }
0471:
0472: public IOR readIOR() throws IOException {
0473: IOR ior = new IOR();
0474:
0475: return ior.read(this );
0476: }
0477:
0478: public Object readObject(Class cl) throws IOException {
0479: IOR ior = readIOR();
0480: return null;
0481: }
0482:
0483: public String readWideString() throws IOException {
0484: // XXX: assume ucs-16
0485: CharBuffer cb = CharBuffer.allocate();
0486: int len = _in.read_long();
0487: for (; len > 0; len--) {
0488: cb.append((char) read_short());
0489: }
0490:
0491: return cb.close();
0492: }
0493:
0494: public Serializable read_value() {
0495: return read_value((Class) null);
0496: }
0497:
0498: public Serializable read_value(Class type) {
0499: try {
0500: // ejb/114o tests for chunking
0501: int oldChunkEnd = _chunkEnd;
0502:
0503: // writeHexGroup(16);
0504:
0505: _chunkEnd = -1;
0506: _in.align(4);
0507: int startOffset = _in.getOffset();
0508:
0509: int code = read_long();
0510:
0511: String repId = "";
0512: boolean isChunked = false;
0513: Serializable value = null;
0514:
0515: if (code == 0)
0516: return null;
0517: else if (code == 0xffffffff) {
0518: _chunkEnd = oldChunkEnd;
0519:
0520: int start = _in.getOffset();
0521: int delta = read_long();
0522: int target = start + delta;
0523:
0524: log.fine("INDIRECT:" + delta);
0525:
0526: value = _context.getRef(target);
0527:
0528: if (value != null)
0529: return value;
0530:
0531: throw new IndirectionException(target);
0532: } else if ((code & 0x7fffff00) != 0x7fffff00) {
0533: repId = readString(code);
0534: } else {
0535: isChunked = (code & 8) == 8;
0536: boolean hasCodeBase = (code & 1) == 1;
0537: int repository = (code & 6);
0538:
0539: if (hasCodeBase) {
0540: readCodeBase();
0541: }
0542:
0543: if (repository == 2) {
0544: repId = read_string();
0545: } else {
0546: throw new RuntimeException(
0547: "Can't cope with repository=" + repository);
0548: }
0549: }
0550:
0551: try {
0552: if (isChunked) {
0553: // writeHexGroup(16);
0554:
0555: int chunkLength = _in.read_long();
0556:
0557: _chunkEnd = chunkLength + _in.getOffset();
0558: _chunkDepth++;
0559: }
0560:
0561: // XXX: assume ucs-16
0562: if (repId.equals("IDL:omg.org/CORBA/WStringValue:1.0")) {
0563: value = read_wstring();
0564: } else if (!repId.startsWith("RMI:")
0565: && !repId.startsWith("IDL:")) {
0566: log.warning("unknown rep: " + repId + " "
0567: + Integer.toHexString(code));
0568: throw new UnsupportedOperationException(
0569: "problem parsing repid: '" + repId + "'");
0570: } else {
0571: int p = repId.indexOf(':', 4);
0572: if (p < 0)
0573: throw new RuntimeException("unknown RMI: "
0574: + repId);
0575:
0576: String className;
0577:
0578: if (repId.startsWith("IDL:omg.org")) {
0579: className = "org.omg"
0580: + repId.substring(11, p).replace('/',
0581: '.');
0582:
0583: int tail = className.lastIndexOf('.');
0584: className = (className.substring(0, tail)
0585: + "Package" + className.substring(tail));
0586: } else
0587: className = repId.substring(4, p);
0588:
0589: // log.fine("CLASS-NAME: " + className);
0590: if (className.equals("javax.rmi.CORBA.ClassDesc")) {
0591: return readClass();
0592: } else {
0593: Class cl = null;
0594:
0595: try {
0596: cl = CauchoSystem.loadClass(className);
0597: } catch (ClassNotFoundException e) {
0598: e.printStackTrace();
0599: throw new RuntimeException(e);
0600: }
0601:
0602: value = _valueHandler.readValue(this ,
0603: startOffset, cl, repId, runTime);
0604: }
0605: }
0606:
0607: _context.addRef(startOffset, value);
0608:
0609: return value;
0610: } finally {
0611: if (_chunkDepth > 0) {
0612: _chunkDepth--;
0613:
0614: int delta = _chunkEnd - _in.getOffset();
0615: _chunkEnd = -1;
0616:
0617: if (delta > 0) {
0618: _in.skip(delta);
0619: }
0620:
0621: int newChunk = _in.read_long();
0622:
0623: if (newChunk >= 0)
0624: throw new IllegalStateException(L.l(
0625: "{0}: expected end of chunk {1}",
0626: getOffset(), newChunk));
0627:
0628: _chunkDepth = -(newChunk + 1);
0629:
0630: if (_chunkDepth > 0) {
0631: newChunk = _in.read_long();
0632: //System.out.println("REDO:" + newChunk + " D:" + _chunkDepth);
0633: _chunkEnd = _in.getOffset() + newChunk;
0634: }
0635: }
0636: }
0637: } catch (IOException e) {
0638: throw new RuntimeException(e);
0639: }
0640: }
0641:
0642: private Class readClass() throws IOException {
0643: String codebase = (String) read_value(String.class);
0644: String repId = (String) read_value(String.class);
0645:
0646: log.fine("CODE: " + codebase);
0647: log.fine("REP-ID: " + repId);
0648:
0649: if (codebase != null && codebase.startsWith("RMI:")) {
0650: String temp = repId;
0651: repId = codebase;
0652: codebase = temp;
0653: }
0654:
0655: return loadClass(repId);
0656: }
0657:
0658: private Class loadClass(String repId) throws RuntimeException {
0659: if (!repId.startsWith("RMI:"))
0660: throw new RuntimeException("unknown RMI: " + repId);
0661:
0662: int p = repId.indexOf(':', 4);
0663: if (p < 0)
0664: throw new RuntimeException("unknown RMI: " + repId);
0665:
0666: String className = repId.substring(4, p);
0667:
0668: if ("javax.rmi.CORBA.ClassDesc".equals(className))
0669: return Class.class;
0670:
0671: Class cl = null;
0672:
0673: try {
0674: Thread thread = Thread.currentThread();
0675:
0676: return Class.forName(className, false, thread
0677: .getContextClassLoader());
0678: } catch (ClassNotFoundException e) {
0679: throw new RuntimeException(e);
0680: }
0681: }
0682:
0683: private String readCodeBase() {
0684: String codeBase = read_string();
0685: return codeBase;
0686: }
0687:
0688: public Object read_fault() {
0689: int startOffset = _in.getOffset();
0690: int originalOffset = startOffset;
0691:
0692: String repId = read_string();
0693:
0694: // XXX: assume ucs-16
0695: if (repId.equals("IDL:omg.org/CORBA/WStringValue:1.0"))
0696: return read_wstring();
0697:
0698: Class cl = null;
0699:
0700: if (repId.startsWith("RMI:")) {
0701: int p = repId.indexOf(':', 4);
0702: if (p < 0)
0703: throw new RuntimeException("unknown RMI: " + repId);
0704:
0705: String className = repId.substring(4, p);
0706:
0707: try {
0708: cl = CauchoSystem.loadClass(className);
0709: } catch (ClassNotFoundException e) {
0710: throw new RuntimeException(e);
0711: }
0712:
0713: return _valueHandler.readValue(this , _in.getOffset(), cl,
0714: repId, runTime);
0715: }
0716:
0717: String className = null;
0718:
0719: if (repId.startsWith("IDL:")) {
0720: String tail = repId.substring(4);
0721: int p = tail.indexOf(':');
0722: if (p > 0)
0723: tail = tail.substring(0, p);
0724:
0725: if (tail.startsWith("omg.org/"))
0726: tail = "org.omg." + tail.substring("omg.org/".length());
0727:
0728: className = tail.replace('/', '.');
0729: } else
0730: className = repId;
0731:
0732: String handler = className + "Handler";
0733:
0734: Class handlerClass = null;
0735: try {
0736: cl = CauchoSystem.loadClass(className);
0737: handlerClass = CauchoSystem.loadClass(handler);
0738: } catch (ClassNotFoundException e) {
0739: }
0740:
0741: if (cl == null) {
0742: int p = className.lastIndexOf('.');
0743: className = className.substring(0, p) + "Package"
0744: + className.substring(p);
0745: handler = className + "Helper";
0746:
0747: try {
0748: cl = CauchoSystem.loadClass(className);
0749: handlerClass = CauchoSystem.loadClass(handler);
0750: } catch (ClassNotFoundException e) {
0751: }
0752: }
0753:
0754: if (cl != null && handlerClass != null) {
0755: java.lang.reflect.Method readHelper = null;
0756:
0757: try {
0758: readHelper = handlerClass
0759: .getMethod(
0760: "read",
0761: new Class[] { org.omg.CORBA.portable.InputStream.class });
0762: } catch (Exception e) {
0763: }
0764:
0765: if (readHelper != null) {
0766: try {
0767: _in.setOffset(startOffset);
0768: _rs.setOffset(originalOffset);
0769:
0770: return readHelper.invoke(null,
0771: new Object[] { this });
0772: } catch (java.lang.reflect.InvocationTargetException e) {
0773: e.printStackTrace();
0774: } catch (Exception e) {
0775: throw new RuntimeException(String.valueOf(e));
0776: }
0777: }
0778: }
0779:
0780: return new IOException("unknown fault: " + repId);
0781: }
0782:
0783: /**
0784: * Reads a boolean from the input stream.
0785: */
0786: public boolean read_boolean() {
0787: return _in.read() != 0;
0788: }
0789:
0790: /**
0791: * Reads an 8-bit char from the input stream.
0792: */
0793: public char read_char() {
0794: return (char) _in.read();
0795: }
0796:
0797: /**
0798: * Reads an 16-bit char from the input stream.
0799: */
0800: public char read_wchar() {
0801: if (_minor == 2) {
0802: _in.read();
0803:
0804: return (char) _in.read_short();
0805: } else
0806: return (char) read_short();
0807: }
0808:
0809: /**
0810: * Reads an 16-bit short from the input stream.
0811: */
0812: public short read_ushort() {
0813: return read_short();
0814: }
0815:
0816: /**
0817: * Reads a 32-bit integer from the input stream.
0818: */
0819: public int read_long() {
0820: return _in.read_long();
0821: }
0822:
0823: /**
0824: * Reads a 32-bit integer from the input stream.
0825: */
0826: public int read_ulong() {
0827: return read_long();
0828: }
0829:
0830: /**
0831: * Reads a 64-bit integer from the input stream.
0832: */
0833: public long read_longlong() {
0834: return readLong();
0835: }
0836:
0837: /**
0838: * Reads a 64-bit integer from the input stream.
0839: */
0840: public long read_ulonglong() {
0841: return read_longlong();
0842: }
0843:
0844: /**
0845: * Reads an 8-bit byte from the input stream.
0846: */
0847: public byte read_octet() {
0848: return (byte) _in.read();
0849: }
0850:
0851: /**
0852: * Reads a 32-bit float from the input stream.
0853: */
0854: public float read_float() {
0855: int v = read_long();
0856:
0857: return Float.intBitsToFloat(v);
0858: }
0859:
0860: /**
0861: * Reads a 64-bit double from the input stream.
0862: */
0863: public double read_double() {
0864: long v = read_longlong();
0865:
0866: return Double.longBitsToDouble(v);
0867: }
0868:
0869: /**
0870: * Reads a boolean array from the input stream.
0871: */
0872: public void read_boolean_array(boolean[] v, int offset, int length) {
0873: for (int i = 0; i < length; i++)
0874: v[i + offset] = read_boolean();
0875: }
0876:
0877: /**
0878: * Reads a char array from the input stream.
0879: */
0880: public void read_char_array(char[] v, int offset, int length) {
0881: for (int i = 0; i < length; i++)
0882: v[i + offset] = read_char();
0883: }
0884:
0885: /**
0886: * Reads a string from the input stream.
0887: */
0888: public String read_string() {
0889: int len = read_long();
0890: int offset = _in.getOffset();
0891:
0892: if (len < 0) {
0893: // ejb/114o
0894:
0895: int delta = read_long();
0896:
0897: String v = _context.getString(offset + delta);
0898:
0899: return v;
0900: }
0901:
0902: char[] cb = _cb;
0903: if (cb.length < len) {
0904: _cb = new char[len + (1024 - len % 1024) % 1024];
0905: cb = _cb;
0906: }
0907: for (int i = 0; i < len - 1; i++)
0908: cb[i] = read_char();
0909:
0910: read_octet(); // null
0911:
0912: String v = new String(cb, 0, len - 1);
0913:
0914: _context.putString(offset, v);
0915:
0916: return v;
0917: }
0918:
0919: /**
0920: * Reads a string from the input stream.
0921: */
0922: public String readString(int len) {
0923: char[] cb = _cb;
0924:
0925: if (cb.length < len) {
0926: _cb = new char[len + (1024 - len % 1024) % 1024];
0927: cb = _cb;
0928: }
0929:
0930: for (int i = 0; i < len - 1; i++)
0931: cb[i] = read_char();
0932:
0933: read_octet(); // null
0934:
0935: return new String(cb, 0, len - 1);
0936: }
0937:
0938: /**
0939: * Reads a wchar array from the input stream.
0940: */
0941: public void read_wchar_array(char[] v, int offset, int length) {
0942: for (int i = 0; i < length; i++) {
0943: v[i + offset] = read_wchar();
0944: }
0945: }
0946:
0947: /**
0948: * Reads a string from the input stream.
0949: */
0950: public String read_wstring() {
0951: return read_wstring(read_long());
0952: }
0953:
0954: /**
0955: * Reads a string from the input stream.
0956: */
0957: public String read_wstring(int len) {
0958: char[] cb = _cb;
0959:
0960: if (_minor >= 2) {
0961: int sublen = len / 2;
0962: if (cb.length < sublen) {
0963: _cb = new char[sublen + (1024 - sublen % 1024) % 1024];
0964: cb = _cb;
0965: }
0966:
0967: for (int i = 0; i < sublen; i++) {
0968: cb[i] = (char) read_short();
0969: }
0970:
0971: String v = new String(cb, 0, sublen);
0972:
0973: return v;
0974: } else {
0975: if (cb.length < len) {
0976: _cb = new char[len + (1024 - len % 1024) % 1024];
0977: cb = _cb;
0978: }
0979:
0980: for (int i = 0; i < len - 1; i++) {
0981: cb[i] = (char) read_short();
0982: }
0983: read_short();
0984:
0985: return new String(cb, 0, len - 1);
0986: }
0987: }
0988:
0989: /**
0990: * Reads a byte array from the input stream.
0991: */
0992: public void read_octet_array(byte[] v, int offset, int length) {
0993: for (int i = 0; i < length; i++)
0994: v[i + offset] = read_octet();
0995: }
0996:
0997: /**
0998: * Reads a short array from the input stream.
0999: */
1000: public void read_short_array(short[] v, int offset, int length) {
1001: for (int i = 0; i < length; i++)
1002: v[i + offset] = read_short();
1003: }
1004:
1005: /**
1006: * Reads a ushort array from the input stream.
1007: */
1008: public void read_ushort_array(short[] v, int offset, int length) {
1009: for (int i = 0; i < length; i++)
1010: v[i + offset] = read_ushort();
1011: }
1012:
1013: /**
1014: * Reads an int array from the input stream.
1015: */
1016: public void read_long_array(int[] v, int offset, int length) {
1017: for (int i = 0; i < length; i++)
1018: v[i + offset] = _in.read_long();
1019: }
1020:
1021: /**
1022: * Reads an int array from the input stream.
1023: */
1024: public void read_ulong_array(int[] v, int offset, int length) {
1025: for (int i = 0; i < length; i++)
1026: v[i + offset] = read_ulong();
1027: }
1028:
1029: /**
1030: * Reads a long array from the input stream.
1031: */
1032: public void read_longlong_array(long[] v, int offset, int length) {
1033: for (int i = 0; i < length; i++)
1034: v[i + offset] = read_longlong();
1035: }
1036:
1037: /**
1038: * Reads a long array from the input stream.
1039: */
1040: public void read_ulonglong_array(long[] v, int offset, int length) {
1041: for (int i = 0; i < length; i++)
1042: v[i + offset] = read_ulonglong();
1043: }
1044:
1045: /**
1046: * Reads a float array from the input stream.
1047: */
1048: public void read_float_array(float[] v, int offset, int length) {
1049: for (int i = 0; i < length; i++)
1050: v[i + offset] = read_float();
1051: }
1052:
1053: /**
1054: * Reads a double array from the input stream.
1055: */
1056: public void read_double_array(double[] v, int offset, int length) {
1057: for (int i = 0; i < length; i++) {
1058: v[i + offset] = read_double();
1059: }
1060: }
1061:
1062: /**
1063: * Reads a CORBA object from the input stream.
1064: */
1065: public Object read_abstract_interface() {
1066: boolean discriminator = read_boolean();
1067:
1068: if (discriminator) {
1069: return read_Object();
1070: } else
1071: return read_value();
1072: }
1073:
1074: @Override
1075: public org.omg.CORBA.Object read_Object(Class cl) {
1076: return read_Object();
1077: }
1078:
1079: /**
1080: * Reads a CORBA object from the input stream.
1081: */
1082: @Override
1083: public org.omg.CORBA.Object read_Object() {
1084: try {
1085: IOR ior = readIOR();
1086:
1087: if (_orb != null) {
1088: return new StubImpl(_orb, ior);
1089: } else
1090: return new DummyObjectImpl(ior);
1091: } catch (IOException e) {
1092: throw new RuntimeException(e);
1093: }
1094: }
1095:
1096: /**
1097: * Reads a CORBA object from the input stream.
1098: */
1099: public org.omg.CORBA.TypeCode read_TypeCode() {
1100: int kind = read_long();
1101:
1102: //System.out.println("KIND: " + Integer.toHexString(kind) + " " + kind);
1103:
1104: try {
1105: switch (kind) {
1106: case TCKind._tk_null:
1107: return TypeCodeImpl.TK_NULL;
1108:
1109: case TCKind._tk_boolean:
1110: return BooleanTypeCode.TYPE_CODE;
1111:
1112: case TCKind._tk_wchar:
1113: return WcharTypeCode.TYPE_CODE;
1114:
1115: case TCKind._tk_octet:
1116: return OctetTypeCode.TYPE_CODE;
1117:
1118: case TCKind._tk_short:
1119: return ShortTypeCode.TYPE_CODE;
1120:
1121: case TCKind._tk_long:
1122: return LongTypeCode.TYPE_CODE;
1123:
1124: case TCKind._tk_longlong:
1125: return LongLongTypeCode.TYPE_CODE;
1126:
1127: case TCKind._tk_float:
1128: return FloatTypeCode.TYPE_CODE;
1129:
1130: case TCKind._tk_double:
1131: return DoubleTypeCode.TYPE_CODE;
1132:
1133: case TCKind._tk_string: {
1134: TypeCodeImpl typeCode = new TypeCodeImpl(
1135: TCKind.tk_string);
1136: typeCode.setLength(read_ulong());
1137:
1138: return typeCode;
1139: }
1140:
1141: case TCKind._tk_wstring: {
1142: TypeCodeImpl typeCode = new TypeCodeImpl(
1143: TCKind.tk_wstring);
1144: typeCode.setLength(read_ulong());
1145:
1146: return typeCode;
1147: }
1148:
1149: case TCKind._tk_sequence:
1150: return SequenceTypeCode.readTypeCode(this );
1151:
1152: case TCKind._tk_value:
1153: return ValueTypeCode.readTypeCode(this );
1154:
1155: case TCKind._tk_value_box:
1156: return ValueBoxTypeCode.readTypeCode(this );
1157:
1158: case TCKind._tk_abstract_interface:
1159: return AbstractInterfaceTypeCode.readTypeCode(this );
1160:
1161: default:
1162: System.out.println("UNKNOWN:" + kind);
1163: throw new UnsupportedOperationException(
1164: "unknown typecode kind: " + kind);
1165: }
1166: } finally {
1167: //System.out.println("DONE:" + kind);
1168: }
1169: }
1170:
1171: /**
1172: * Reads a CORBA object from the input stream.
1173: */
1174: public org.omg.CORBA.Any read_any() {
1175: try {
1176: TypeCode typeCode = read_TypeCode();
1177:
1178: AnyImpl any = new AnyImpl();
1179:
1180: any.read_value(this , typeCode);
1181:
1182: return any;
1183: } catch (RuntimeException e) {
1184: throw e;
1185: } catch (Exception e) {
1186: throw new RuntimeException(e);
1187: }
1188: }
1189:
1190: /**
1191: * Reads a CORBA object from the input stream.
1192: */
1193: public Principal read_Principal() {
1194: throw new UnsupportedOperationException();
1195: }
1196:
1197: public int read_sequence_length() {
1198: int length = read_long();
1199:
1200: if (length < 0 || length > 65536)
1201: throw new RuntimeException("sequence too long:" + length);
1202:
1203: return length;
1204: }
1205:
1206: public void readOctetSequence(ByteBuffer bb) throws IOException {
1207: int len = _in.read_long();
1208:
1209: if (len > 65536)
1210: throw new IOException("too large chunk " + len);
1211:
1212: bb.ensureCapacity(len);
1213: _in.read(bb.getBuffer(), 0, len);
1214: bb.setLength(len);
1215: }
1216:
1217: public String readString() {
1218: int len = _in.read_long();
1219:
1220: if (len < 1 || len > 65536)
1221: throw new IllegalStateException("string length problems: "
1222: + len);
1223:
1224: char[] cb = _cb;
1225:
1226: if (cb.length < len) {
1227: _cb = new char[len + (1024 - len % 1024) % 1024];
1228: cb = _cb;
1229: }
1230:
1231: for (int i = 0; i < len - 1; i++) {
1232: cb[i] = (char) read_octet();
1233: }
1234: int ch = read_octet();
1235:
1236: return new String(cb, 0, len - 1);
1237: }
1238:
1239: public void readString(CharBuffer cb) throws IOException {
1240: int len = _in.read_long();
1241:
1242: if (len > 65536)
1243: throw new IOException("too large chunk " + len);
1244:
1245: cb.clear();
1246: for (int i = 0; i < len - 1; i++) {
1247: int ch = read();
1248: cb.append((char) ch);
1249: }
1250:
1251: int ch = read();
1252: }
1253:
1254: /**
1255: * Reads an 16-bit short from the input stream.
1256: */
1257: public short read_short() {
1258: return (short) _in.read_short();
1259: }
1260:
1261: /**
1262: * Reads a 32-bit integer from the input stream.
1263: */
1264: public int readInt() {
1265: return _in.read_long();
1266: }
1267:
1268: /**
1269: * Reads a 32-bit integer from the input stream.
1270: */
1271: public int readInt(byte[] buffer, int offset) {
1272: int ch1 = buffer[offset++];
1273: int ch2 = buffer[offset++];
1274: int ch3 = buffer[offset++];
1275: int ch4 = buffer[offset++];
1276:
1277: return (((ch1 & 0xff) << 24) + ((ch2 & 0xff) << 16)
1278: + ((ch3 & 0xff) << 8) + ((ch4 & 0xff)));
1279: }
1280:
1281: /**
1282: * Reads a 64-bit integer from the input stream.
1283: */
1284: public long readLong() {
1285: return _in.read_longlong();
1286: }
1287:
1288: private void align4() {
1289: _in.align(4);
1290: }
1291:
1292: private void align8() throws IOException {
1293: _in.align(8);
1294: }
1295:
1296: public void alignMethodArgs() {
1297: if (_minor >= 2) {
1298: _in.align(8);
1299: }
1300: }
1301:
1302: /**
1303: * Reads the next byte.
1304: */
1305: public int read() {
1306: return _in.read();
1307: }
1308:
1309: public byte[] readBytes() throws IOException {
1310: int len = _in.read_long();
1311:
1312: if (len > 65536)
1313: throw new IOException("too large chunk " + len);
1314:
1315: byte[] buf = new byte[len];
1316: _in.read(buf, 0, len);
1317:
1318: return buf;
1319: }
1320:
1321: public void completeRead() throws IOException {
1322: // _in.completeRead();
1323: }
1324:
1325: public void close() {
1326: ReadWritePair pair = _pair;
1327: _pair = null;
1328:
1329: _rs = null;
1330:
1331: if (pair != null) {
1332: if (_pool != null) {
1333: _pool.free(pair);
1334: } else {
1335: try {
1336: pair.getWriteStream().close();
1337: } catch (IOException e) {
1338: }
1339:
1340: pair.getReadStream().close();
1341: }
1342: }
1343: }
1344:
1345: private void writeHexGroup(byte[] buffer, int offset, int length) {
1346: int end = offset + length;
1347:
1348: while (offset < end) {
1349: int chunkLength = 16;
1350:
1351: for (int j = 0; j < chunkLength; j++) {
1352: System.out.print(" ");
1353: printHex(buffer[offset + j]);
1354: }
1355:
1356: System.out.print(" ");
1357: for (int j = 0; j < chunkLength; j++) {
1358: printCh(buffer[offset + j]);
1359: }
1360:
1361: offset += chunkLength;
1362:
1363: System.out.println();
1364: }
1365: }
1366:
1367: private void printHex(int d) {
1368: int ch1 = (d >> 4) & 0xf;
1369: int ch2 = d & 0xf;
1370:
1371: if (ch1 >= 10)
1372: System.out.print((char) ('a' + ch1 - 10));
1373: else
1374: System.out.print((char) ('0' + ch1));
1375:
1376: if (ch2 >= 10)
1377: System.out.print((char) ('a' + ch2 - 10));
1378: else
1379: System.out.print((char) ('0' + ch2));
1380: }
1381:
1382: private void printCh(int d) {
1383: if (d >= 0x20 && d <= 0x7f)
1384: System.out.print("" + ((char) d));
1385: else
1386: System.out.print(".");
1387: }
1388:
1389: private String toCh(int d) {
1390: if (d >= 0x20 && d <= 0x7f)
1391: return "" + (char) d;
1392: else
1393: return "" + d;
1394: }
1395:
1396: private static String toHex(int v) {
1397: CharBuffer cb = new CharBuffer();
1398: for (int i = 28; i >= 0; i -= 4) {
1399: int h = (v >> i) & 0xf;
1400:
1401: if (h >= 10)
1402: cb.append((char) ('a' + h - 10));
1403: else
1404: cb.append(h);
1405: }
1406:
1407: return cb.toString();
1408: }
1409: }
|