CDRInputStream_1_0.java revision 608:7e06bf1dcb09
1130803Smarcel/* 2130803Smarcel * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3130803Smarcel * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4130803Smarcel * 5130803Smarcel * This code is free software; you can redistribute it and/or modify it 6130803Smarcel * under the terms of the GNU General Public License version 2 only, as 7130803Smarcel * published by the Free Software Foundation. Oracle designates this 8130803Smarcel * particular file as subject to the "Classpath" exception as provided 9130803Smarcel * by Oracle in the LICENSE file that accompanied this code. 10130803Smarcel * 11130803Smarcel * This code is distributed in the hope that it will be useful, but WITHOUT 12130803Smarcel * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13130803Smarcel * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14130803Smarcel * version 2 for more details (a copy is included in the LICENSE file that 15130803Smarcel * accompanied this code). 16130803Smarcel * 17130803Smarcel * You should have received a copy of the GNU General Public License version 18130803Smarcel * 2 along with this work; if not, write to the Free Software Foundation, 19130803Smarcel * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20130803Smarcel * 21130803Smarcel * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22130803Smarcel * or visit www.oracle.com if you need additional information or have any 23130803Smarcel * questions. 24130803Smarcel */ 25130803Smarcel 26130803Smarcel/* 27130803Smarcel * Licensed Materials - Property of IBM 28130803Smarcel * RMI-IIOP v1.0 29130803Smarcel * Copyright IBM Corp. 1998 1999 All Rights Reserved 30130803Smarcel * 31130803Smarcel */ 32130803Smarcel 33130803Smarcelpackage com.sun.corba.se.impl.encoding; 34130803Smarcel 35130803Smarcelimport java.io.IOException; 36130803Smarcelimport java.io.Serializable; 37130803Smarcelimport java.io.ByteArrayInputStream; 38130803Smarcelimport java.io.ObjectInputStream; 39130803Smarcelimport java.io.IOException; 40130803Smarcelimport java.io.StreamCorruptedException; 41130803Smarcelimport java.io.OptionalDataException; 42130803Smarcelimport java.io.IOException; 43130803Smarcel 44130803Smarcelimport java.util.Stack; 45130803Smarcel 46130803Smarcelimport java.net.URL; 47130803Smarcelimport java.net.MalformedURLException; 48130803Smarcel 49130803Smarcelimport java.nio.ByteBuffer; 50130803Smarcel 51130803Smarcelimport java.lang.reflect.InvocationTargetException; 52130803Smarcelimport java.lang.reflect.Method; 53130803Smarcel 54130803Smarcelimport java.math.BigDecimal; 55130803Smarcel 56130803Smarcelimport java.rmi.Remote; 57130803Smarcelimport java.rmi.StubNotFoundException; 58130803Smarcel 59130803Smarcelimport java.security.AccessController; 60130803Smarcelimport java.security.PrivilegedExceptionAction; 61130803Smarcelimport java.security.PrivilegedActionException; 62130803Smarcel 63130803Smarcelimport org.omg.CORBA.SystemException; 64130803Smarcelimport org.omg.CORBA.Object; 65130803Smarcelimport org.omg.CORBA.Principal; 66130803Smarcelimport org.omg.CORBA.TypeCode; 67130803Smarcelimport org.omg.CORBA.Any; 68130803Smarcelimport org.omg.CORBA.portable.Delegate; 69130803Smarcelimport org.omg.CORBA.portable.ValueBase; 70130803Smarcelimport org.omg.CORBA.portable.IndirectionException; 71130803Smarcelimport org.omg.CORBA.CompletionStatus; 72130803Smarcelimport org.omg.CORBA.TCKind; 73130803Smarcelimport org.omg.CORBA.TypeCodePackage.BadKind; 74130803Smarcelimport org.omg.CORBA.CustomMarshal; 75130803Smarcelimport org.omg.CORBA.TypeCode; 76130803Smarcelimport org.omg.CORBA.Principal; 77130803Smarcelimport org.omg.CORBA.Any; 78130803Smarcelimport org.omg.CORBA.portable.BoxedValueHelper; 79130803Smarcelimport org.omg.CORBA.portable.ValueFactory; 80130803Smarcelimport org.omg.CORBA.portable.CustomValue; 81130803Smarcelimport org.omg.CORBA.portable.StreamableValue; 82130803Smarcelimport org.omg.CORBA.MARSHAL; 83130803Smarcelimport org.omg.CORBA.portable.IDLEntity; 84130803Smarcel 85130803Smarcelimport javax.rmi.PortableRemoteObject; 86130803Smarcelimport javax.rmi.CORBA.Tie; 87130803Smarcelimport javax.rmi.CORBA.Util; 88130803Smarcelimport javax.rmi.CORBA.ValueHandler; 89130803Smarcel 90130803Smarcelimport com.sun.corba.se.pept.protocol.MessageMediator; 91130803Smarcelimport com.sun.corba.se.pept.transport.ByteBufferPool; 92130803Smarcel 93130803Smarcelimport com.sun.corba.se.spi.protocol.RequestDispatcherRegistry; 94130803Smarcelimport com.sun.corba.se.spi.protocol.CorbaClientDelegate; 95130803Smarcel 96130803Smarcelimport com.sun.corba.se.spi.ior.IOR; 97130803Smarcelimport com.sun.corba.se.spi.ior.IORFactories; 98130803Smarcelimport com.sun.corba.se.spi.ior.iiop.GIOPVersion; 99130803Smarcel 100130803Smarcelimport com.sun.corba.se.spi.orb.ORB; 101130803Smarcelimport com.sun.corba.se.spi.orb.ORBVersionFactory; 102130803Smarcelimport com.sun.corba.se.spi.orb.ORBVersion; 103130803Smarcel 104130803Smarcelimport com.sun.corba.se.spi.protocol.CorbaMessageMediator; 105130803Smarcel 106130803Smarcelimport com.sun.corba.se.spi.logging.CORBALogDomains; 107130803Smarcelimport com.sun.corba.se.spi.presentation.rmi.PresentationManager; 108130803Smarcelimport com.sun.corba.se.spi.presentation.rmi.StubAdapter; 109130803Smarcelimport com.sun.corba.se.spi.presentation.rmi.PresentationDefaults; 110130803Smarcel 111130803Smarcelimport com.sun.corba.se.impl.logging.ORBUtilSystemException; 112130803Smarcelimport com.sun.corba.se.impl.logging.OMGSystemException; 113130803Smarcel 114130803Smarcelimport com.sun.corba.se.impl.corba.PrincipalImpl; 115130803Smarcelimport com.sun.corba.se.impl.corba.TypeCodeImpl; 116130803Smarcelimport com.sun.corba.se.impl.corba.CORBAObjectImpl; 117130803Smarcel 118130803Smarcelimport com.sun.corba.se.impl.encoding.CDROutputObject; 119130803Smarcelimport com.sun.corba.se.impl.encoding.CodeSetConversion; 120130803Smarcel 121130803Smarcelimport com.sun.corba.se.impl.util.Utility; 122130803Smarcelimport com.sun.corba.se.impl.util.RepositoryId; 123130803Smarcel 124130803Smarcelimport com.sun.corba.se.impl.orbutil.RepositoryIdStrings; 125130803Smarcelimport com.sun.corba.se.impl.orbutil.RepositoryIdInterface; 126130803Smarcelimport com.sun.corba.se.impl.orbutil.RepositoryIdUtility; 127130803Smarcelimport com.sun.corba.se.impl.orbutil.RepositoryIdFactory; 128130803Smarcel 129130803Smarcelimport com.sun.corba.se.impl.orbutil.ORBUtility; 130130803Smarcelimport com.sun.corba.se.impl.orbutil.CacheTable; 131130803Smarcel 132130803Smarcel 133130803Smarcelimport com.sun.org.omg.CORBA.portable.ValueHelper; 134130803Smarcel 135130803Smarcelimport com.sun.org.omg.SendingContext.CodeBase; 136130803Smarcel 137130803Smarcelpublic class CDRInputStream_1_0 extends CDRInputStreamBase 138130803Smarcel implements RestorableInputStream 139130803Smarcel{ 140130803Smarcel private static final String kReadMethod = "read"; 141130803Smarcel private static final int maxBlockLength = 0x7fffff00; 142130803Smarcel 143130803Smarcel protected BufferManagerRead bufferManagerRead; 144130803Smarcel protected ByteBufferWithInfo bbwi; 145130803Smarcel 146130803Smarcel // Set to the ORB's transportDebugFlag value. This value is 147130803Smarcel // used if the ORB is null. 148130803Smarcel private boolean debug = false; 149130803Smarcel 150130803Smarcel protected boolean littleEndian; 151130803Smarcel protected ORB orb; 152130803Smarcel protected ORBUtilSystemException wrapper ; 153130803Smarcel protected OMGSystemException omgWrapper ; 154130803Smarcel protected ValueHandler valueHandler = null; 155130803Smarcel 156130803Smarcel // Value cache 157130803Smarcel private CacheTable valueCache = null; 158130803Smarcel 159130803Smarcel // Repository ID cache 160130803Smarcel private CacheTable repositoryIdCache = null; 161130803Smarcel 162130803Smarcel // codebase cache 163130803Smarcel private CacheTable codebaseCache = null; 164130803Smarcel 165130803Smarcel // Current Class Stack (repository Ids of current class being read) 166130803Smarcel // private Stack currentStack = null; 167130803Smarcel 168130803Smarcel // Length of current chunk, or a large positive number if not in a chunk 169130803Smarcel protected int blockLength = maxBlockLength; 170130803Smarcel 171130803Smarcel // Read end flag (value nesting depth) 172130803Smarcel protected int end_flag = 0; 173130803Smarcel 174130803Smarcel // Beginning with the resolution to interop issue 3526 (4328?), 175130803Smarcel // only enclosing chunked valuetypes are taken into account 176130803Smarcel // when computing the nesting level. However, we still need 177130803Smarcel // the old computation around for interoperability with our 178130803Smarcel // older ORBs. 179130803Smarcel private int chunkedValueNestingLevel = 0; 180130803Smarcel 181130803Smarcel // Flag used to determine whether blocksize was zero 182130803Smarcel // private int checkForNullBlock = -1; 183130803Smarcel 184130803Smarcel // In block flag 185130803Smarcel // private boolean inBlock = false; 186130803Smarcel 187130803Smarcel // Indicates whether we are inside a value 188130803Smarcel // private boolean outerValueDone = true; 189130803Smarcel 190130803Smarcel // Int used by read_value(Serializable) that is set by this class 191130803Smarcel // before calling ValueFactory.read_value 192130803Smarcel protected int valueIndirection = 0; 193130803Smarcel 194130803Smarcel // Int set by readStringOrIndirection to communicate the actual 195130803Smarcel // offset of the string length field back to the caller 196130803Smarcel protected int stringIndirection = 0; 197130803Smarcel 198130803Smarcel // Flag indicating whether we are unmarshalling a chunked value 199130803Smarcel protected boolean isChunked = false; 200130803Smarcel 201130803Smarcel // Repository ID handlers 202130803Smarcel private RepositoryIdUtility repIdUtil; 203130803Smarcel private RepositoryIdStrings repIdStrs; 204130803Smarcel 205130803Smarcel // Code set converters (created when first needed) 206130803Smarcel private CodeSetConversion.BTCConverter charConverter; 207130803Smarcel private CodeSetConversion.BTCConverter wcharConverter; 208130803Smarcel 209130803Smarcel // RMI-IIOP stream format version 2 case in which we know 210130803Smarcel // that there is no more optional data available. If the 211130803Smarcel // Serializable's readObject method tries to read anything, 212130803Smarcel // we must throw a MARSHAL with the special minor code 213130803Smarcel // so that the ValueHandler can give the correct exception 214130803Smarcel // to readObject. The state is cleared when the ValueHandler 215130803Smarcel // calls end_value after the readObject method exits. 216130803Smarcel private boolean specialNoOptionalDataState = false; 217130803Smarcel 218130803Smarcel // Template method 219130803Smarcel public CDRInputStreamBase dup() 220130803Smarcel { 221130803Smarcel CDRInputStreamBase result = null ; 222130803Smarcel 223130803Smarcel try { 224130803Smarcel result = (CDRInputStreamBase)this.getClass().newInstance(); 225130803Smarcel } catch (Exception e) { 226130803Smarcel throw wrapper.couldNotDuplicateCdrInputStream( e ) ; 227130803Smarcel } 228130803Smarcel result.init(this.orb, 229130803Smarcel this.bbwi.byteBuffer, 230130803Smarcel this.bbwi.buflen, 231130803Smarcel this.littleEndian, 232130803Smarcel this.bufferManagerRead); 233130803Smarcel 234130803Smarcel ((CDRInputStream_1_0)result).bbwi.position(this.bbwi.position()); 235130803Smarcel // To ensure we keep bbwi.byteBuffer.limit in sync with bbwi.buflen. 236130803Smarcel ((CDRInputStream_1_0)result).bbwi.byteBuffer.limit(this.bbwi.buflen); 237130803Smarcel 238130803Smarcel return result; 239130803Smarcel } 240130803Smarcel 241130803Smarcel /** 242130803Smarcel * NOTE: size passed to init means buffer size 243130803Smarcel */ 244130803Smarcel public void init(org.omg.CORBA.ORB orb, 245130803Smarcel ByteBuffer byteBuffer, 246130803Smarcel int size, 247130803Smarcel boolean littleEndian, 248130803Smarcel BufferManagerRead bufferManager) 249130803Smarcel { 250130803Smarcel this.orb = (ORB)orb; 251130803Smarcel this.wrapper = ORBUtilSystemException.get( (ORB)orb, 252130803Smarcel CORBALogDomains.RPC_ENCODING ) ; 253130803Smarcel this.omgWrapper = OMGSystemException.get( (ORB)orb, 254130803Smarcel CORBALogDomains.RPC_ENCODING ) ; 255130803Smarcel this.littleEndian = littleEndian; 256130803Smarcel this.bufferManagerRead = bufferManager; 257130803Smarcel this.bbwi = new ByteBufferWithInfo(orb,byteBuffer,0); 258130803Smarcel this.bbwi.buflen = size; 259130803Smarcel this.bbwi.byteBuffer.limit(bbwi.buflen); 260130803Smarcel this.markAndResetHandler = bufferManagerRead.getMarkAndResetHandler(); 261130803Smarcel 262130803Smarcel debug = ((ORB)orb).transportDebugFlag; 263130803Smarcel } 264130803Smarcel 265130803Smarcel // See description in CDRInputStream 266130803Smarcel void performORBVersionSpecificInit() { 267130803Smarcel createRepositoryIdHandlers(); 268130803Smarcel } 269130803Smarcel 270130803Smarcel private final void createRepositoryIdHandlers() 271130803Smarcel { 272130803Smarcel repIdUtil = RepositoryIdFactory.getRepIdUtility(); 273130803Smarcel repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(); 274130803Smarcel } 275130803Smarcel 276130803Smarcel public GIOPVersion getGIOPVersion() { 277130803Smarcel return GIOPVersion.V1_0; 278130803Smarcel } 279130803Smarcel 280130803Smarcel // Called by Request and Reply message. Valid for GIOP versions >= 1.2 only. 281130803Smarcel // Illegal for GIOP versions < 1.2. 282130803Smarcel void setHeaderPadding(boolean headerPadding) { 283130803Smarcel throw wrapper.giopVersionError(); 284130803Smarcel } 285130803Smarcel 286130803Smarcel protected final int computeAlignment(int index, int align) { 287130803Smarcel if (align > 1) { 288130803Smarcel int incr = index & (align - 1); 289130803Smarcel if (incr != 0) 290130803Smarcel return align - incr; 291130803Smarcel } 292130803Smarcel 293130803Smarcel return 0; 294130803Smarcel } 295130803Smarcel 296130803Smarcel public int getSize() 297130803Smarcel { 298130803Smarcel return bbwi.position(); 299130803Smarcel } 300130803Smarcel 301130803Smarcel protected void checkBlockLength(int align, int dataSize) { 302130803Smarcel // Since chunks can end at arbitrary points (though not within 303130803Smarcel // primitive CDR types, arrays of primitives, strings, wstrings, 304130803Smarcel // or indirections), 305130803Smarcel // we must check here for termination of the current chunk. 306130803Smarcel if (!isChunked) 307130803Smarcel return; 308130803Smarcel 309130803Smarcel // RMI-IIOP stream format version 2 case in which we know 310130803Smarcel // that there is no more optional data available. If the 311130803Smarcel // Serializable's readObject method tries to read anything, 312130803Smarcel // we must throw a MARSHAL exception with the special minor code 313130803Smarcel // so that the ValueHandler can give the correct exception 314130803Smarcel // to readObject. The state is cleared when the ValueHandler 315130803Smarcel // calls end_value after the readObject method exits. 316130803Smarcel if (specialNoOptionalDataState) { 317130803Smarcel throw omgWrapper.rmiiiopOptionalDataIncompatible1() ; 318130803Smarcel } 319130803Smarcel 320130803Smarcel boolean checkForEndTag = false; 321130803Smarcel 322130803Smarcel // Are we at the end of the current chunk? If so, 323130803Smarcel // try to interpret the next long as a chunk length. 324130803Smarcel // (It has to be either a chunk length, end tag, 325130803Smarcel // or valuetag.) 326130803Smarcel // 327130803Smarcel // If it isn't a chunk length, blockLength will 328130803Smarcel // remain set to maxBlockLength. 329130803Smarcel if (blockLength == get_offset()) { 330130803Smarcel 331130803Smarcel blockLength = maxBlockLength; 332130803Smarcel start_block(); 333130803Smarcel 334130803Smarcel // What's next is either a valuetag or 335130803Smarcel // an end tag. If it's a valuetag, we're 336130803Smarcel // probably being called as part of the process 337130803Smarcel // to read the valuetag. If it's an end tag, 338130803Smarcel // then there isn't enough data left in 339130803Smarcel // this valuetype to read! 340130803Smarcel if (blockLength == maxBlockLength) 341130803Smarcel checkForEndTag = true; 342130803Smarcel 343130803Smarcel } else 344130803Smarcel if (blockLength < get_offset()) { 345130803Smarcel // Are we already past the end of the current chunk? 346130803Smarcel // This is always an error. 347130803Smarcel throw wrapper.chunkOverflow() ; 348130803Smarcel } 349130803Smarcel 350130803Smarcel // If what's next on the wire isn't a chunk length or 351130803Smarcel // what we want to read (which can't be split across chunks) 352130803Smarcel // won't fit in the current chunk, throw this exception. 353130803Smarcel // This probably means that we're in an RMI-IIOP 354130803Smarcel // Serializable's readObject method or a custom marshaled 355130803Smarcel // IDL type is reading too much/in an incorrect order 356130803Smarcel int requiredNumBytes = 357130803Smarcel computeAlignment(bbwi.position(), align) + dataSize; 358130803Smarcel 359130803Smarcel if (blockLength != maxBlockLength && 360130803Smarcel blockLength < get_offset() + requiredNumBytes) { 361130803Smarcel throw omgWrapper.rmiiiopOptionalDataIncompatible2() ; 362130803Smarcel } 363130803Smarcel 364130803Smarcel // REVISIT - We should look at using the built in advancement 365130803Smarcel // of using ByteBuffer.get() rather than explicitly 366130803Smarcel // advancing the ByteBuffer's position. 367130803Smarcel // This is true for anywhere we are incrementing 368130803Smarcel // the ByteBuffer's position. 369130803Smarcel if (checkForEndTag) { 370130803Smarcel int nextLong = read_long(); 371130803Smarcel bbwi.position(bbwi.position() - 4); 372130803Smarcel 373130803Smarcel // It was an end tag, so there wasn't enough data 374130803Smarcel // left in the valuetype's encoding on the wire 375130803Smarcel // to read what we wanted 376130803Smarcel if (nextLong < 0) 377130803Smarcel throw omgWrapper.rmiiiopOptionalDataIncompatible3() ; 378130803Smarcel } 379130803Smarcel } 380130803Smarcel 381130803Smarcel protected void alignAndCheck(int align, int n) { 382130803Smarcel 383130803Smarcel checkBlockLength(align, n); 384130803Smarcel 385130803Smarcel // WARNING: Must compute real alignment after calling 386130803Smarcel // checkBlockLength since it may move the position 387130803Smarcel int alignResult = computeAlignment(bbwi.position(), align); 388130803Smarcel bbwi.position(bbwi.position() + alignResult); 389130803Smarcel 390130803Smarcel if (bbwi.position() + n > bbwi.buflen) 391130803Smarcel grow(align, n); 392130803Smarcel } 393130803Smarcel 394130803Smarcel // 395130803Smarcel // This can be overridden.... 396130803Smarcel // 397130803Smarcel protected void grow(int align, int n) { 398130803Smarcel 399130803Smarcel bbwi.needed = n; 400130803Smarcel 401130803Smarcel bbwi = bufferManagerRead.underflow(bbwi); 402130803Smarcel 403130803Smarcel } 404130803Smarcel 405130803Smarcel // 406130803Smarcel // Marshal primitives. 407130803Smarcel // 408130803Smarcel 409130803Smarcel public final void consumeEndian() { 410130803Smarcel littleEndian = read_boolean(); 411130803Smarcel } 412130803Smarcel 413130803Smarcel // No such type in java 414130803Smarcel public final double read_longdouble() { 415130803Smarcel throw wrapper.longDoubleNotImplemented( CompletionStatus.COMPLETED_MAYBE); 416130803Smarcel } 417130803Smarcel 418130803Smarcel public final boolean read_boolean() { 419130803Smarcel return (read_octet() != 0); 420130803Smarcel } 421130803Smarcel 422130803Smarcel public final char read_char() { 423130803Smarcel alignAndCheck(1, 1); 424130803Smarcel 425130803Smarcel return getConvertedChars(1, getCharConverter())[0]; 426130803Smarcel } 427130803Smarcel 428130803Smarcel public char read_wchar() { 429130803Smarcel 430130803Smarcel // Don't allow transmission of wchar/wstring data with 431130803Smarcel // foreign ORBs since it's against the spec. 432130803Smarcel if (ORBUtility.isForeignORB((ORB)orb)) { 433130803Smarcel throw wrapper.wcharDataInGiop10( CompletionStatus.COMPLETED_MAYBE); 434130803Smarcel } 435130803Smarcel 436130803Smarcel // If we're talking to one of our legacy ORBs, do what 437130803Smarcel // they did: 438130803Smarcel int b1, b2; 439130803Smarcel 440130803Smarcel alignAndCheck(2, 2); 441130803Smarcel 442130803Smarcel if (littleEndian) { 443130803Smarcel b2 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF; 444130803Smarcel bbwi.position(bbwi.position() + 1); 445130803Smarcel b1 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF; 446130803Smarcel bbwi.position(bbwi.position() + 1); 447130803Smarcel } else { 448130803Smarcel b1 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF; 449130803Smarcel bbwi.position(bbwi.position() + 1); 450130803Smarcel b2 = bbwi.byteBuffer.get(bbwi.position()) & 0x00FF; 451130803Smarcel bbwi.position(bbwi.position() + 1); 452130803Smarcel } 453130803Smarcel 454130803Smarcel return (char)((b1 << 8) + (b2 << 0)); 455130803Smarcel } 456130803Smarcel 457130803Smarcel public final byte read_octet() { 458130803Smarcel 459130803Smarcel alignAndCheck(1, 1); 460130803Smarcel 461130803Smarcel byte b = bbwi.byteBuffer.get(bbwi.position()); 462130803Smarcel bbwi.position(bbwi.position() + 1); 463130803Smarcel 464130803Smarcel return b; 465130803Smarcel } 466130803Smarcel 467130803Smarcel public final short read_short() { 468130803Smarcel int b1, b2; 469130803Smarcel 470130803Smarcel alignAndCheck(2, 2); 471130803Smarcel 472130803Smarcel if (littleEndian) { 473130803Smarcel b2 = (bbwi.byteBuffer.get(bbwi.position()) << 0) & 0x000000FF; 474130803Smarcel bbwi.position(bbwi.position() + 1); 475130803Smarcel b1 = (bbwi.byteBuffer.get(bbwi.position()) << 8) & 0x0000FF00; 476130803Smarcel bbwi.position(bbwi.position() + 1); 477130803Smarcel } else { 478130803Smarcel b1 = (bbwi.byteBuffer.get(bbwi.position()) << 8) & 0x0000FF00; 479130803Smarcel bbwi.position(bbwi.position() + 1); 480130803Smarcel b2 = (bbwi.byteBuffer.get(bbwi.position()) << 0) & 0x000000FF; 481130803Smarcel bbwi.position(bbwi.position() + 1); 482130803Smarcel } 483130803Smarcel 484130803Smarcel return (short)(b1 | b2); 485130803Smarcel } 486130803Smarcel 487130803Smarcel public final short read_ushort() { 488130803Smarcel return read_short(); 489130803Smarcel } 490130803Smarcel 491130803Smarcel public final int read_long() { 492130803Smarcel int b1, b2, b3, b4; 493130803Smarcel 494130803Smarcel alignAndCheck(4, 4); 495130803Smarcel 496130803Smarcel int bufPos = bbwi.position(); 497130803Smarcel if (littleEndian) { 498130803Smarcel b4 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 499130803Smarcel b3 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 500130803Smarcel b2 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 501130803Smarcel b1 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 502130803Smarcel } else { 503130803Smarcel b1 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 504130803Smarcel b2 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 505130803Smarcel b3 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 506130803Smarcel b4 = bbwi.byteBuffer.get(bufPos++) & 0xFF; 507130803Smarcel } 508130803Smarcel bbwi.position(bufPos); 509130803Smarcel 510130803Smarcel return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; 511130803Smarcel } 512130803Smarcel 513130803Smarcel public final int read_ulong() { 514130803Smarcel return read_long(); 515130803Smarcel } 516130803Smarcel 517130803Smarcel public final long read_longlong() { 518130803Smarcel long i1, i2; 519130803Smarcel 520130803Smarcel alignAndCheck(8, 8); 521130803Smarcel 522130803Smarcel if (littleEndian) { 523130803Smarcel i2 = read_long() & 0xFFFFFFFFL; 524130803Smarcel i1 = (long)read_long() << 32; 525130803Smarcel } else { 526130803Smarcel i1 = (long)read_long() << 32; 527130803Smarcel i2 = read_long() & 0xFFFFFFFFL; 528130803Smarcel } 529130803Smarcel 530130803Smarcel return (i1 | i2); 531130803Smarcel } 532130803Smarcel 533130803Smarcel public final long read_ulonglong() { 534130803Smarcel return read_longlong(); 535130803Smarcel } 536130803Smarcel 537130803Smarcel public final float read_float() { 538130803Smarcel return Float.intBitsToFloat(read_long()); 539130803Smarcel } 540130803Smarcel 541130803Smarcel public final double read_double() { 542130803Smarcel return Double.longBitsToDouble(read_longlong()); 543130803Smarcel } 544130803Smarcel 545130803Smarcel protected final void checkForNegativeLength(int length) { 546130803Smarcel if (length < 0) 547130803Smarcel throw wrapper.negativeStringLength( CompletionStatus.COMPLETED_MAYBE, 548130803Smarcel new Integer(length) ) ; 549130803Smarcel } 550130803Smarcel 551130803Smarcel protected final String readStringOrIndirection(boolean allowIndirection) { 552130803Smarcel 553130803Smarcel int len = read_long(); 554130803Smarcel 555130803Smarcel // 556130803Smarcel // Check for indirection 557130803Smarcel // 558130803Smarcel if (allowIndirection) { 559130803Smarcel if (len == 0xffffffff) 560130803Smarcel return null; 561130803Smarcel else 562130803Smarcel stringIndirection = get_offset() - 4; 563130803Smarcel } 564130803Smarcel 565130803Smarcel checkForNegativeLength(len); 566130803Smarcel 567130803Smarcel return internalReadString(len); 568130803Smarcel } 569130803Smarcel 570130803Smarcel private final String internalReadString(int len) { 571130803Smarcel // Workaround for ORBs which send string lengths of 572130803Smarcel // zero to mean empty string. 573130803Smarcel // 574130803Smarcel // IMPORTANT: Do not replace 'new String("")' with "", it may result 575130803Smarcel // in a Serialization bug (See serialization.zerolengthstring) and 576130803Smarcel // bug id: 4728756 for details 577130803Smarcel if (len == 0) 578130803Smarcel return new String(""); 579130803Smarcel 580130803Smarcel char[] result = getConvertedChars(len - 1, getCharConverter()); 581130803Smarcel 582130803Smarcel // Skip over the 1 byte null 583130803Smarcel read_octet(); 584130803Smarcel 585130803Smarcel return new String(result, 0, getCharConverter().getNumChars()); 586130803Smarcel } 587130803Smarcel 588130803Smarcel public final String read_string() { 589130803Smarcel return readStringOrIndirection(false); 590130803Smarcel } 591130803Smarcel 592130803Smarcel public String read_wstring() { 593130803Smarcel // Don't allow transmission of wchar/wstring data with 594130803Smarcel // foreign ORBs since it's against the spec. 595130803Smarcel if (ORBUtility.isForeignORB((ORB)orb)) { 596130803Smarcel throw wrapper.wcharDataInGiop10( CompletionStatus.COMPLETED_MAYBE); 597130803Smarcel } 598130803Smarcel 599130803Smarcel int len = read_long(); 600130803Smarcel 601130803Smarcel // 602130803Smarcel // Workaround for ORBs which send string lengths of 603130803Smarcel // zero to mean empty string. 604130803Smarcel // 605130803Smarcel // 606130803Smarcel // IMPORTANT: Do not replace 'new String("")' with "", it may result 607130803Smarcel // in a Serialization bug (See serialization.zerolengthstring) and 608130803Smarcel // bug id: 4728756 for details 609130803Smarcel if (len == 0) 610130803Smarcel return new String(""); 611130803Smarcel 612130803Smarcel checkForNegativeLength(len); 613130803Smarcel 614130803Smarcel len--; 615130803Smarcel char[] c = new char[len]; 616130803Smarcel 617130803Smarcel for (int i = 0; i < len; i++) 618130803Smarcel c[i] = read_wchar(); 619130803Smarcel 620130803Smarcel // skip the two null terminator bytes 621130803Smarcel read_wchar(); 622130803Smarcel // bbwi.position(bbwi.position() + 2); 623130803Smarcel 624130803Smarcel return new String(c); 625130803Smarcel } 626130803Smarcel 627130803Smarcel public final void read_octet_array(byte[] b, int offset, int length) { 628130803Smarcel if ( b == null ) 629130803Smarcel throw wrapper.nullParam() ; 630130803Smarcel 631130803Smarcel // Must call alignAndCheck at least once to ensure 632130803Smarcel // we aren't at the end of a chunk. Of course, we 633130803Smarcel // should only call it if we actually need to read 634130803Smarcel // something, otherwise we might end up with an 635130803Smarcel // exception at the end of the stream. 636130803Smarcel if (length == 0) 637130803Smarcel return; 638130803Smarcel 639130803Smarcel alignAndCheck(1, 1); 640130803Smarcel 641130803Smarcel int n = offset; 642130803Smarcel while (n < length+offset) { 643130803Smarcel int avail; 644130803Smarcel int bytes; 645130803Smarcel int wanted; 646130803Smarcel 647130803Smarcel avail = bbwi.buflen - bbwi.position(); 648130803Smarcel if (avail <= 0) { 649130803Smarcel grow(1, 1); 650130803Smarcel avail = bbwi.buflen - bbwi.position(); 651130803Smarcel } 652130803Smarcel wanted = (length + offset) - n; 653130803Smarcel bytes = (wanted < avail) ? wanted : avail; 654130803Smarcel // Microbenchmarks are showing a loop of ByteBuffer.get(int) being 655130803Smarcel // faster than ByteBuffer.get(byte[], int, int). 656130803Smarcel for (int i = 0; i < bytes; i++) { 657130803Smarcel b[n+i] = bbwi.byteBuffer.get(bbwi.position() + i); 658130803Smarcel } 659130803Smarcel 660130803Smarcel bbwi.position(bbwi.position() + bytes); 661130803Smarcel 662130803Smarcel n += bytes; 663130803Smarcel } 664130803Smarcel } 665130803Smarcel 666130803Smarcel public Principal read_Principal() { 667130803Smarcel int len = read_long(); 668130803Smarcel byte[] pvalue = new byte[len]; 669130803Smarcel read_octet_array(pvalue,0,len); 670130803Smarcel 671130803Smarcel Principal p = new PrincipalImpl(); 672130803Smarcel p.name(pvalue); 673130803Smarcel return p; 674130803Smarcel } 675130803Smarcel 676130803Smarcel public TypeCode read_TypeCode() { 677130803Smarcel TypeCodeImpl tc = new TypeCodeImpl(orb); 678130803Smarcel tc.read_value(parent); 679130803Smarcel return tc; 680130803Smarcel } 681130803Smarcel 682130803Smarcel public Any read_any() { 683130803Smarcel Any any = orb.create_any(); 684130803Smarcel TypeCodeImpl tc = new TypeCodeImpl(orb); 685130803Smarcel 686130803Smarcel // read off the typecode 687130803Smarcel 688130803Smarcel // REVISIT We could avoid this try-catch if we could peek the typecode 689130803Smarcel // kind off this stream and see if it is a tk_value. Looking at the 690130803Smarcel // code we know that for tk_value the Any.read_value() below 691130803Smarcel // ignores the tc argument anyway (except for the kind field). 692130803Smarcel // But still we would need to make sure that the whole typecode, 693130803Smarcel // including encapsulations, is read off. 694130803Smarcel try { 695130803Smarcel tc.read_value(parent); 696130803Smarcel } catch (MARSHAL ex) { 697130803Smarcel if (tc.kind().value() != TCKind._tk_value) 698130803Smarcel throw ex; 699130803Smarcel // We can be sure that the whole typecode encapsulation has been 700130803Smarcel // read off. 701130803Smarcel dprintThrowable(ex); 702130803Smarcel } 703130803Smarcel // read off the value of the any 704130803Smarcel any.read_value(parent, tc); 705130803Smarcel 706130803Smarcel return any; 707130803Smarcel } 708130803Smarcel 709130803Smarcel public org.omg.CORBA.Object read_Object() { 710130803Smarcel return read_Object(null); 711130803Smarcel } 712130803Smarcel 713130803Smarcel // ------------ RMI related methods -------------------------- 714130803Smarcel 715130803Smarcel // IDL to Java ptc-00-01-08 1.21.4.1 716130803Smarcel // 717130803Smarcel // The clz argument to read_Object can be either a stub 718130803Smarcel // Class or the "Class object for the RMI/IDL interface type 719130803Smarcel // that is statically expected." 720130803Smarcel // This functions as follows: 721130803Smarcel // 1. If clz==null, just use the repository ID from the stub 722130803Smarcel // 2. If clz is a stub class, just use it as a static factory. 723130803Smarcel // clz is a stub class iff StubAdapter.isStubClass( clz ). 724130803Smarcel // In addition, clz is a IDL stub class iff 725130803Smarcel // IDLEntity.class.isAssignableFrom( clz ). 726130803Smarcel // 3. If clz is an interface, use it to create the appropriate 727130803Smarcel // stub factory. 728130803Smarcel public org.omg.CORBA.Object read_Object(Class clz) 729130803Smarcel { 730130803Smarcel // In any case, we must first read the IOR. 731130803Smarcel IOR ior = IORFactories.makeIOR(parent) ; 732130803Smarcel if (ior.isNil()) 733130803Smarcel return null ; 734130803Smarcel 735130803Smarcel PresentationManager.StubFactoryFactory sff = ORB.getStubFactoryFactory() ; 736130803Smarcel String codeBase = ior.getProfile().getCodebase() ; 737130803Smarcel PresentationManager.StubFactory stubFactory = null ; 738130803Smarcel 739130803Smarcel if (clz == null) { 740130803Smarcel RepositoryId rid = RepositoryId.cache.getId( ior.getTypeId() ) ; 741130803Smarcel String className = rid.getClassName() ; 742130803Smarcel boolean isIDLInterface = rid.isIDLType() ; 743130803Smarcel 744130803Smarcel if (className == null || className.equals( "" )) 745130803Smarcel stubFactory = null ; 746130803Smarcel else 747130803Smarcel try { 748130803Smarcel stubFactory = sff.createStubFactory( className, 749130803Smarcel isIDLInterface, codeBase, (Class)null, 750130803Smarcel (ClassLoader)null ); 751130803Smarcel } catch (Exception exc) { 752130803Smarcel // Could not create stubFactory, so use null. 753130803Smarcel // XXX stubFactory handling is still too complex: 754130803Smarcel // Can we resolve the stubFactory question once in 755130803Smarcel // a single place? 756130803Smarcel stubFactory = null ; 757130803Smarcel } 758130803Smarcel } else if (StubAdapter.isStubClass( clz )) { 759130803Smarcel stubFactory = PresentationDefaults.makeStaticStubFactory( 760130803Smarcel clz ) ; 761130803Smarcel } else { 762130803Smarcel // clz is an interface class 763130803Smarcel boolean isIDL = IDLEntity.class.isAssignableFrom( clz ) ; 764130803Smarcel 765130803Smarcel stubFactory = sff.createStubFactory( clz.getName(), 766130803Smarcel isIDL, codeBase, clz, clz.getClassLoader() ) ; 767130803Smarcel } 768130803Smarcel 769130803Smarcel return internalIORToObject( ior, stubFactory, orb ) ; 770130803Smarcel } 771130803Smarcel 772130803Smarcel /* 773130803Smarcel * This is used as a general utility (e.g., the PortableInterceptor 774130803Smarcel * implementation uses it. If stubFactory is null, the ior's 775130803Smarcel * IIOPProfile must support getServant. 776130803Smarcel */ 777130803Smarcel public static org.omg.CORBA.Object internalIORToObject( 778130803Smarcel IOR ior, PresentationManager.StubFactory stubFactory, ORB orb) 779130803Smarcel { 780130803Smarcel ORBUtilSystemException wrapper = ORBUtilSystemException.get( 781130803Smarcel (ORB)orb, CORBALogDomains.RPC_ENCODING ) ; 782130803Smarcel 783130803Smarcel java.lang.Object servant = ior.getProfile().getServant() ; 784130803Smarcel if (servant != null ) { 785130803Smarcel if (servant instanceof Tie) { 786130803Smarcel String codebase = ior.getProfile().getCodebase(); 787130803Smarcel org.omg.CORBA.Object objref = (org.omg.CORBA.Object) 788130803Smarcel Utility.loadStub( (Tie)servant, stubFactory, codebase, 789130803Smarcel false); 790130803Smarcel 791130803Smarcel // If we managed to load a stub, return it, otherwise we 792130803Smarcel // must fail... 793130803Smarcel if (objref != null) { 794130803Smarcel return objref; 795130803Smarcel } else { 796130803Smarcel throw wrapper.readObjectException() ; 797130803Smarcel } 798130803Smarcel } else if (servant instanceof org.omg.CORBA.Object) { 799130803Smarcel if (!(servant instanceof 800130803Smarcel org.omg.CORBA.portable.InvokeHandler)) { 801130803Smarcel return (org.omg.CORBA.Object) servant; 802130803Smarcel } 803130803Smarcel } else 804130803Smarcel throw wrapper.badServantReadObject() ; 805130803Smarcel } 806130803Smarcel 807130803Smarcel CorbaClientDelegate del = ORBUtility.makeClientDelegate( ior ) ; 808130803Smarcel org.omg.CORBA.Object objref = null ; 809130803Smarcel try { 810130803Smarcel objref = stubFactory.makeStub() ; 811130803Smarcel } catch (Throwable e) { 812130803Smarcel wrapper.stubCreateError( e ) ; 813130803Smarcel 814130803Smarcel if (e instanceof ThreadDeath) { 815130803Smarcel throw (ThreadDeath) e; 816130803Smarcel } 817130803Smarcel 818130803Smarcel // Return the "default" stub... 819130803Smarcel objref = new CORBAObjectImpl() ; 820130803Smarcel } 821130803Smarcel 822130803Smarcel StubAdapter.setDelegate( objref, del ) ; 823130803Smarcel return objref; 824130803Smarcel } 825130803Smarcel 826130803Smarcel public java.lang.Object read_abstract_interface() 827130803Smarcel { 828130803Smarcel return read_abstract_interface(null); 829130803Smarcel } 830130803Smarcel 831130803Smarcel public java.lang.Object read_abstract_interface(java.lang.Class clz) 832130803Smarcel { 833130803Smarcel boolean object = read_boolean(); 834130803Smarcel 835130803Smarcel if (object) { 836130803Smarcel return read_Object(clz); 837130803Smarcel } else { 838130803Smarcel return read_value(); 839130803Smarcel } 840130803Smarcel } 841130803Smarcel 842130803Smarcel public Serializable read_value() 843130803Smarcel { 844130803Smarcel return read_value((Class)null); 845130803Smarcel } 846130803Smarcel 847130803Smarcel private Serializable handleIndirection() { 848130803Smarcel int indirection = read_long() + get_offset() - 4; 849130803Smarcel if (valueCache != null && valueCache.containsVal(indirection)) { 850130803Smarcel 851130803Smarcel java.io.Serializable cachedValue 852130803Smarcel = (java.io.Serializable)valueCache.getKey(indirection); 853130803Smarcel return cachedValue; 854130803Smarcel } else { 855130803Smarcel // In RMI-IIOP the ValueHandler will recognize this 856130803Smarcel // exception and use the provided indirection value 857130803Smarcel // to lookup a possible indirection to an object 858130803Smarcel // currently on the deserialization stack. 859130803Smarcel throw new IndirectionException(indirection); 860130803Smarcel } 861130803Smarcel } 862130803Smarcel 863130803Smarcel private String readRepositoryIds(int valueTag, 864130803Smarcel Class expectedType, 865130803Smarcel String expectedTypeRepId) { 866130803Smarcel return readRepositoryIds(valueTag, expectedType, 867130803Smarcel expectedTypeRepId, null); 868130803Smarcel } 869130803Smarcel 870130803Smarcel /** 871130803Smarcel * Examines the valuetag to see how many (if any) repository IDs 872130803Smarcel * are present on the wire. If no repository ID information 873130803Smarcel * is on the wire but the expectedType or expectedTypeRepId 874130803Smarcel * is known, it will return one of those (favoring the 875130803Smarcel * expectedType's repId). Failing that, it uses the supplied 876130803Smarcel * BoxedValueHelper to obtain the repository ID, as a last resort. 877130803Smarcel */ 878130803Smarcel private String readRepositoryIds(int valueTag, 879130803Smarcel Class expectedType, 880130803Smarcel String expectedTypeRepId, 881130803Smarcel BoxedValueHelper factory) { 882130803Smarcel switch(repIdUtil.getTypeInfo(valueTag)) { 883130803Smarcel case RepositoryIdUtility.NO_TYPE_INFO : 884130803Smarcel // Throw an exception if we have no repository ID info and 885130803Smarcel // no expectedType to work with. Otherwise, how would we 886130803Smarcel // know what to unmarshal? 887130803Smarcel if (expectedType == null) { 888130803Smarcel if (expectedTypeRepId != null) { 889130803Smarcel return expectedTypeRepId; 890130803Smarcel } else if (factory != null) { 891130803Smarcel return factory.get_id(); 892130803Smarcel } else { 893130803Smarcel throw wrapper.expectedTypeNullAndNoRepId( 894130803Smarcel CompletionStatus.COMPLETED_MAYBE); 895130803Smarcel } 896130803Smarcel } 897130803Smarcel return repIdStrs.createForAnyType(expectedType); 898130803Smarcel case RepositoryIdUtility.SINGLE_REP_TYPE_INFO : 899130803Smarcel return read_repositoryId(); 900130803Smarcel case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO : 901130803Smarcel return read_repositoryIds(); 902130803Smarcel default: 903130803Smarcel throw wrapper.badValueTag( CompletionStatus.COMPLETED_MAYBE, 904130803Smarcel Integer.toHexString(valueTag) ) ; 905130803Smarcel } 906130803Smarcel } 907130803Smarcel 908130803Smarcel public Serializable read_value(Class expectedType) { 909130803Smarcel 910130803Smarcel // Read value tag 911130803Smarcel int vType = readValueTag(); 912130803Smarcel 913130803Smarcel // Is value null? 914130803Smarcel if (vType == 0) 915130803Smarcel return null; 916130803Smarcel 917130803Smarcel // Is this an indirection to a previously 918130803Smarcel // read valuetype? 919130803Smarcel if (vType == 0xffffffff) 920130803Smarcel return handleIndirection(); 921130803Smarcel 922130803Smarcel // Save where this valuetype started so we 923130803Smarcel // can put it in the indirection valueCache 924130803Smarcel // later 925130803Smarcel int indirection = get_offset() - 4; 926130803Smarcel 927130803Smarcel // Need to save this special marker variable 928130803Smarcel // to restore its value during recursion 929130803Smarcel boolean saveIsChunked = isChunked; 930130803Smarcel 931130803Smarcel isChunked = repIdUtil.isChunkedEncoding(vType); 932130803Smarcel 933130803Smarcel java.lang.Object value = null; 934130803Smarcel 935130803Smarcel String codebase_URL = null; 936130803Smarcel if (repIdUtil.isCodeBasePresent(vType)) { 937130803Smarcel codebase_URL = read_codebase_URL(); 938130803Smarcel } 939130803Smarcel 940130803Smarcel // Read repository id(s) 941130803Smarcel String repositoryIDString 942130803Smarcel = readRepositoryIds(vType, expectedType, null); 943130803Smarcel 944130803Smarcel // If isChunked was determined to be true based 945130803Smarcel // on the valuetag, this will read a chunk length 946130803Smarcel start_block(); 947130803Smarcel 948130803Smarcel // Remember that end_flag keeps track of all nested 949130803Smarcel // valuetypes and is used for older ORBs 950130803Smarcel end_flag--; 951130803Smarcel if (isChunked) 952130803Smarcel chunkedValueNestingLevel--; 953130803Smarcel 954130803Smarcel if (repositoryIDString.equals(repIdStrs.getWStringValueRepId())) { 955130803Smarcel value = read_wstring(); 956130803Smarcel } else 957130803Smarcel if (repositoryIDString.equals(repIdStrs.getClassDescValueRepId())) { 958130803Smarcel // read in the class whether with the old ClassDesc or the 959130803Smarcel // new one 960130803Smarcel value = readClass(); 961130803Smarcel } else { 962130803Smarcel 963130803Smarcel Class valueClass = expectedType; 964130803Smarcel 965130803Smarcel // By this point, either the expectedType or repositoryIDString 966130803Smarcel // is guaranteed to be non-null. 967130803Smarcel if (expectedType == null || 968130803Smarcel !repositoryIDString.equals(repIdStrs.createForAnyType(expectedType))) { 969130803Smarcel 970130803Smarcel valueClass = getClassFromString(repositoryIDString, 971130803Smarcel codebase_URL, 972130803Smarcel expectedType); 973130803Smarcel } 974130803Smarcel 975130803Smarcel if (valueClass == null) { 976130803Smarcel // No point attempting to use value handler below, since the 977130803Smarcel // class information is not available. 978130803Smarcel throw wrapper.couldNotFindClass( 979130803Smarcel CompletionStatus.COMPLETED_MAYBE, 980130803Smarcel new ClassNotFoundException()); 981130803Smarcel } 982130803Smarcel 983130803Smarcel if (valueClass != null && 984130803Smarcel org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(valueClass)) { 985130803Smarcel 986130803Smarcel value = readIDLValue(indirection, 987130803Smarcel repositoryIDString, 988130803Smarcel valueClass, 989130803Smarcel codebase_URL); 990130803Smarcel 991130803Smarcel } else { 992130803Smarcel 993130803Smarcel // Must be some form of RMI-IIOP valuetype 994130803Smarcel 995130803Smarcel try { 996130803Smarcel if (valueHandler == null) 997130803Smarcel valueHandler = ORBUtility.createValueHandler(); 998130803Smarcel 999130803Smarcel value = valueHandler.readValue(parent, 1000130803Smarcel indirection, 1001130803Smarcel valueClass, 1002130803Smarcel repositoryIDString, 1003130803Smarcel getCodeBase()); 1004130803Smarcel 1005130803Smarcel } catch(SystemException sysEx) { 1006130803Smarcel // Just rethrow any CORBA system exceptions 1007130803Smarcel // that come out of the ValueHandler 1008130803Smarcel throw sysEx; 1009130803Smarcel } catch(Exception ex) { 1010130803Smarcel throw wrapper.valuehandlerReadException( 1011130803Smarcel CompletionStatus.COMPLETED_MAYBE, ex ) ; 1012130803Smarcel } catch(Error e) { 1013130803Smarcel throw wrapper.valuehandlerReadError( 1014130803Smarcel CompletionStatus.COMPLETED_MAYBE, e ) ; 1015130803Smarcel } 1016130803Smarcel } 1017130803Smarcel } 1018130803Smarcel 1019130803Smarcel // Skip any remaining chunks until we get to 1020130803Smarcel // an end tag or a valuetag. If we see a valuetag, 1021130803Smarcel // that means there was another valuetype in the sender's 1022130803Smarcel // version of this class that we need to skip over. 1023130803Smarcel handleEndOfValue(); 1024130803Smarcel 1025130803Smarcel // Read and process the end tag if we're chunking. 1026130803Smarcel // Assumes that we're at the position of the end tag 1027130803Smarcel // (handleEndOfValue should assure this) 1028130803Smarcel readEndTag(); 1029130803Smarcel 1030130803Smarcel // Cache the valuetype that we read 1031130803Smarcel if (valueCache == null) 1032130803Smarcel valueCache = new CacheTable(orb,false); 1033130803Smarcel valueCache.put(value, indirection); 1034130803Smarcel 1035130803Smarcel // Allow for possible continuation chunk. 1036130803Smarcel // If we're a nested valuetype inside of a chunked 1037130803Smarcel // valuetype, and that enclosing valuetype has 1038130803Smarcel // more data to write, it will need to have this 1039130803Smarcel // new chunk begin after we wrote our end tag. 1040130803Smarcel isChunked = saveIsChunked; 1041130803Smarcel start_block(); 1042130803Smarcel 1043130803Smarcel return (java.io.Serializable)value; 1044130803Smarcel } 1045130803Smarcel 1046130803Smarcel public Serializable read_value(BoxedValueHelper factory) { 1047130803Smarcel 1048130803Smarcel // Read value tag 1049130803Smarcel int vType = readValueTag(); 1050130803Smarcel 1051130803Smarcel if (vType == 0) 1052130803Smarcel return null; // value is null 1053130803Smarcel else if (vType == 0xffffffff) { // Indirection tag 1054130803Smarcel int indirection = read_long() + get_offset() - 4; 1055130803Smarcel if (valueCache != null && valueCache.containsVal(indirection)) 1056130803Smarcel { 1057130803Smarcel java.io.Serializable cachedValue = 1058130803Smarcel (java.io.Serializable)valueCache.getKey(indirection); 1059130803Smarcel return cachedValue; 1060130803Smarcel } 1061130803Smarcel else { 1062130803Smarcel throw new IndirectionException(indirection); 1063130803Smarcel } 1064130803Smarcel } 1065130803Smarcel else { 1066130803Smarcel int indirection = get_offset() - 4; 1067130803Smarcel 1068130803Smarcel // end_block(); 1069130803Smarcel 1070130803Smarcel boolean saveIsChunked = isChunked; 1071130803Smarcel isChunked = repIdUtil.isChunkedEncoding(vType); 1072130803Smarcel 1073130803Smarcel java.lang.Object value = null; 1074130803Smarcel 1075130803Smarcel String codebase_URL = null; 1076130803Smarcel if (repIdUtil.isCodeBasePresent(vType)){ 1077130803Smarcel codebase_URL = read_codebase_URL(); 1078130803Smarcel } 1079130803Smarcel 1080130803Smarcel // Read repository id 1081130803Smarcel String repositoryIDString 1082130803Smarcel = readRepositoryIds(vType, null, null, factory); 1083130803Smarcel 1084130803Smarcel // Compare rep. ids to see if we should use passed helper 1085130803Smarcel if (!repositoryIDString.equals(factory.get_id())) 1086130803Smarcel factory = Utility.getHelper(null, codebase_URL, repositoryIDString); 1087130803Smarcel 1088130803Smarcel start_block(); 1089130803Smarcel end_flag--; 1090130803Smarcel if (isChunked) 1091130803Smarcel chunkedValueNestingLevel--; 1092130803Smarcel 1093130803Smarcel if (factory instanceof ValueHelper) { 1094130803Smarcel value = readIDLValueWithHelper((ValueHelper)factory, indirection); 1095130803Smarcel } else { 1096130803Smarcel valueIndirection = indirection; // for callback 1097130803Smarcel value = factory.read_value(parent); 1098130803Smarcel } 1099130803Smarcel 1100130803Smarcel handleEndOfValue(); 1101130803Smarcel readEndTag(); 1102130803Smarcel 1103130803Smarcel // Put into valueCache 1104130803Smarcel if (valueCache == null) 1105130803Smarcel valueCache = new CacheTable(orb,false); 1106130803Smarcel valueCache.put(value, indirection); 1107130803Smarcel 1108130803Smarcel // allow for possible continuation chunk 1109130803Smarcel isChunked = saveIsChunked; 1110130803Smarcel start_block(); 1111130803Smarcel 1112130803Smarcel return (java.io.Serializable)value; 1113130803Smarcel } 1114130803Smarcel } 1115130803Smarcel 1116130803Smarcel private boolean isCustomType(ValueHelper helper) { 1117130803Smarcel try{ 1118130803Smarcel TypeCode tc = helper.get_type(); 1119130803Smarcel int kind = tc.kind().value(); 1120130803Smarcel if (kind == TCKind._tk_value) { 1121130803Smarcel return (tc.type_modifier() == org.omg.CORBA.VM_CUSTOM.value); 1122130803Smarcel } 1123130803Smarcel } catch(BadKind ex) { 1124130803Smarcel throw wrapper.badKind(ex) ; 1125130803Smarcel } 1126130803Smarcel 1127130803Smarcel return false; 1128130803Smarcel } 1129130803Smarcel 1130130803Smarcel // This method is actually called indirectly by 1131130803Smarcel // read_value(String repositoryId). 1132130803Smarcel // Therefore, it is not a truly independent read call that handles 1133130803Smarcel // header information itself. 1134130803Smarcel public java.io.Serializable read_value(java.io.Serializable value) { 1135130803Smarcel 1136130803Smarcel // Put into valueCache using valueIndirection 1137130803Smarcel if (valueCache == null) 1138130803Smarcel valueCache = new CacheTable(orb,false); 1139130803Smarcel valueCache.put(value, valueIndirection); 1140130803Smarcel 1141130803Smarcel if (value instanceof StreamableValue) 1142130803Smarcel ((StreamableValue)value)._read(parent); 1143130803Smarcel else if (value instanceof CustomValue) 1144130803Smarcel ((CustomValue)value).unmarshal(parent); 1145130803Smarcel 1146130803Smarcel return value; 1147130803Smarcel } 1148130803Smarcel 1149130803Smarcel public java.io.Serializable read_value(java.lang.String repositoryId) { 1150130803Smarcel 1151130803Smarcel // if (inBlock) 1152130803Smarcel // end_block(); 1153130803Smarcel 1154130803Smarcel // Read value tag 1155130803Smarcel int vType = readValueTag(); 1156130803Smarcel 1157130803Smarcel if (vType == 0) 1158130803Smarcel return null; // value is null 1159130803Smarcel else if (vType == 0xffffffff) { // Indirection tag 1160130803Smarcel int indirection = read_long() + get_offset() - 4; 1161130803Smarcel if (valueCache != null && valueCache.containsVal(indirection)) 1162130803Smarcel { 1163130803Smarcel java.io.Serializable cachedValue = 1164130803Smarcel (java.io.Serializable)valueCache.getKey(indirection); 1165130803Smarcel return cachedValue; 1166130803Smarcel } 1167130803Smarcel else { 1168130803Smarcel throw new IndirectionException(indirection); 1169130803Smarcel } 1170130803Smarcel } 1171130803Smarcel else { 1172130803Smarcel int indirection = get_offset() - 4; 1173130803Smarcel 1174130803Smarcel // end_block(); 1175130803Smarcel 1176130803Smarcel boolean saveIsChunked = isChunked; 1177130803Smarcel isChunked = repIdUtil.isChunkedEncoding(vType); 1178130803Smarcel 1179130803Smarcel java.lang.Object value = null; 1180130803Smarcel 1181130803Smarcel String codebase_URL = null; 1182130803Smarcel if (repIdUtil.isCodeBasePresent(vType)){ 1183130803Smarcel codebase_URL = read_codebase_URL(); 1184130803Smarcel } 1185130803Smarcel 1186130803Smarcel // Read repository id 1187130803Smarcel String repositoryIDString 1188130803Smarcel = readRepositoryIds(vType, null, repositoryId); 1189130803Smarcel 1190130803Smarcel ValueFactory factory = 1191130803Smarcel Utility.getFactory(null, codebase_URL, orb, repositoryIDString); 1192130803Smarcel 1193130803Smarcel start_block(); 1194130803Smarcel end_flag--; 1195130803Smarcel if (isChunked) 1196130803Smarcel chunkedValueNestingLevel--; 1197130803Smarcel 1198130803Smarcel valueIndirection = indirection; // for callback 1199130803Smarcel value = factory.read_value(parent); 1200130803Smarcel 1201130803Smarcel handleEndOfValue(); 1202130803Smarcel readEndTag(); 1203130803Smarcel 1204130803Smarcel // Put into valueCache 1205130803Smarcel if (valueCache == null) 1206130803Smarcel valueCache = new CacheTable(orb,false); 1207130803Smarcel valueCache.put(value, indirection); 1208130803Smarcel 1209130803Smarcel // allow for possible continuation chunk 1210130803Smarcel isChunked = saveIsChunked; 1211130803Smarcel start_block(); 1212130803Smarcel 1213130803Smarcel return (java.io.Serializable)value; 1214130803Smarcel } 1215130803Smarcel } 1216130803Smarcel 1217130803Smarcel private Class readClass() { 1218130803Smarcel 1219130803Smarcel String codebases = null, classRepId = null; 1220130803Smarcel 1221130803Smarcel if (orb == null || 1222130803Smarcel ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) || 1223130803Smarcel ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) { 1224130803Smarcel 1225130803Smarcel codebases = (String)read_value(java.lang.String.class); 1226130803Smarcel classRepId = (String)read_value(java.lang.String.class); 1227130803Smarcel } else { 1228130803Smarcel // Pre-Merlin/J2EE 1.3 ORBs wrote the repository ID 1229130803Smarcel // and codebase strings in the wrong order. 1230130803Smarcel classRepId = (String)read_value(java.lang.String.class); 1231130803Smarcel codebases = (String)read_value(java.lang.String.class); 1232130803Smarcel } 1233130803Smarcel 1234130803Smarcel if (debug) { 1235130803Smarcel dprint("readClass codebases: " 1236130803Smarcel + codebases 1237130803Smarcel + " rep Id: " 1238130803Smarcel + classRepId); 1239130803Smarcel } 1240130803Smarcel 1241130803Smarcel Class cl = null; 1242130803Smarcel 1243130803Smarcel RepositoryIdInterface repositoryID 1244130803Smarcel = repIdStrs.getFromString(classRepId); 1245130803Smarcel 1246130803Smarcel try { 1247130803Smarcel cl = repositoryID.getClassFromType(codebases); 1248130803Smarcel } catch(ClassNotFoundException cnfe) { 1249130803Smarcel throw wrapper.cnfeReadClass( CompletionStatus.COMPLETED_MAYBE, 1250130803Smarcel cnfe, repositoryID.getClassName() ) ; 1251130803Smarcel } catch(MalformedURLException me) { 1252130803Smarcel throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE, 1253130803Smarcel me, repositoryID.getClassName(), codebases ) ; 1254130803Smarcel } 1255130803Smarcel 1256130803Smarcel return cl; 1257130803Smarcel } 1258130803Smarcel 1259130803Smarcel private java.lang.Object readIDLValueWithHelper(ValueHelper helper, int indirection) 1260130803Smarcel { 1261130803Smarcel // look for two-argument static read method 1262130803Smarcel Method readMethod; 1263130803Smarcel try { 1264130803Smarcel Class argTypes[] = {org.omg.CORBA.portable.InputStream.class, helper.get_class()}; 1265130803Smarcel readMethod = helper.getClass().getDeclaredMethod(kReadMethod, argTypes); 1266130803Smarcel } 1267130803Smarcel catch(NoSuchMethodException nsme) { // must be boxed value helper 1268130803Smarcel java.lang.Object result = helper.read_value(parent); 1269130803Smarcel return result; 1270130803Smarcel } 1271130803Smarcel 1272130803Smarcel // found two-argument read method, so must be non-boxed value... 1273130803Smarcel // ...create a blank instance 1274130803Smarcel java.lang.Object val = null; 1275130803Smarcel try { 1276130803Smarcel val = helper.get_class().newInstance(); 1277130803Smarcel } catch(java.lang.InstantiationException ie) { 1278130803Smarcel throw wrapper.couldNotInstantiateHelper( ie, 1279130803Smarcel helper.get_class() ) ; 1280130803Smarcel } catch(IllegalAccessException iae){ 1281130803Smarcel // Value's constructor is protected or private 1282130803Smarcel // 1283130803Smarcel // So, use the helper to read the value. 1284130803Smarcel // 1285130803Smarcel // NOTE : This means that in this particular case a recursive ref. 1286130803Smarcel // would fail. 1287130803Smarcel return helper.read_value(parent); 1288130803Smarcel } 1289130803Smarcel 1290130803Smarcel // add blank instance to cache table 1291130803Smarcel if (valueCache == null) 1292130803Smarcel valueCache = new CacheTable(orb,false); 1293130803Smarcel valueCache.put(val, indirection); 1294130803Smarcel 1295130803Smarcel // if custom type, call unmarshal method 1296130803Smarcel if (val instanceof CustomMarshal && isCustomType(helper)) { 1297130803Smarcel ((CustomMarshal)val).unmarshal(parent); 1298130803Smarcel return val; 1299130803Smarcel } 1300130803Smarcel 1301130803Smarcel // call two-argument read method using reflection 1302130803Smarcel try { 1303130803Smarcel java.lang.Object args[] = {parent, val}; 1304130803Smarcel readMethod.invoke(helper, args); 1305130803Smarcel return val; 1306130803Smarcel } catch(IllegalAccessException iae2) { 1307130803Smarcel throw wrapper.couldNotInvokeHelperReadMethod( iae2, helper.get_class() ) ; 1308130803Smarcel } catch(InvocationTargetException ite){ 1309130803Smarcel throw wrapper.couldNotInvokeHelperReadMethod( ite, helper.get_class() ) ; 1310130803Smarcel } 1311130803Smarcel } 1312130803Smarcel 1313130803Smarcel private java.lang.Object readBoxedIDLEntity(Class clazz, String codebase) 1314130803Smarcel { 1315130803Smarcel Class cls = null ; 1316130803Smarcel 1317130803Smarcel try { 1318130803Smarcel ClassLoader clazzLoader = (clazz == null ? null : clazz.getClassLoader()); 1319130803Smarcel 1320130803Smarcel cls = Utility.loadClassForClass(clazz.getName()+"Helper", codebase, 1321130803Smarcel clazzLoader, clazz, clazzLoader); 1322130803Smarcel final Class helperClass = cls ; 1323130803Smarcel 1324130803Smarcel final Class argTypes[] = {org.omg.CORBA.portable.InputStream.class}; 1325130803Smarcel 1326130803Smarcel // getDeclaredMethod requires RuntimePermission accessDeclaredMembers 1327130803Smarcel // if a different class loader is used (even though the javadoc says otherwise) 1328130803Smarcel Method readMethod = null; 1329130803Smarcel try { 1330130803Smarcel readMethod = (Method)AccessController.doPrivileged( 1331130803Smarcel new PrivilegedExceptionAction() { 1332130803Smarcel public java.lang.Object run() throws NoSuchMethodException { 1333130803Smarcel return helperClass.getDeclaredMethod(kReadMethod, argTypes); 1334130803Smarcel } 1335130803Smarcel } 1336130803Smarcel ); 1337130803Smarcel } catch (PrivilegedActionException pae) { 1338130803Smarcel // this gets caught below 1339130803Smarcel throw (NoSuchMethodException)pae.getException(); 1340130803Smarcel } 1341130803Smarcel 1342130803Smarcel java.lang.Object args[] = {parent}; 1343130803Smarcel return readMethod.invoke(null, args); 1344130803Smarcel 1345130803Smarcel } catch (ClassNotFoundException cnfe) { 1346130803Smarcel throw wrapper.couldNotInvokeHelperReadMethod( cnfe, cls ) ; 1347130803Smarcel } catch(NoSuchMethodException nsme) { 1348130803Smarcel throw wrapper.couldNotInvokeHelperReadMethod( nsme, cls ) ; 1349130803Smarcel } catch(IllegalAccessException iae) { 1350130803Smarcel throw wrapper.couldNotInvokeHelperReadMethod( iae, cls ) ; 1351130803Smarcel } catch(InvocationTargetException ite) { 1352130803Smarcel throw wrapper.couldNotInvokeHelperReadMethod( ite, cls ) ; 1353130803Smarcel } 1354130803Smarcel } 1355130803Smarcel 1356130803Smarcel private java.lang.Object readIDLValue(int indirection, String repId, 1357130803Smarcel Class clazz, String codebase) 1358130803Smarcel { 1359130803Smarcel ValueFactory factory ; 1360130803Smarcel 1361130803Smarcel // Always try to find a ValueFactory first, as required by the spec. 1362130803Smarcel // There are some complications here in the IDL 3.0 mapping (see 1.13.8), 1363130803Smarcel // but basically we must always be able to override the DefaultFactory 1364130803Smarcel // or Helper mappings that are also used. This appears to be the case 1365130803Smarcel // even in the boxed value cases. The original code only did the lookup 1366130803Smarcel // in the case of class implementing either StreamableValue or CustomValue, 1367130803Smarcel // but abstract valuetypes only implement ValueBase, and really require 1368130803Smarcel // the use of the repId to find a factory (including the DefaultFactory). 1369130803Smarcel try { 1370130803Smarcel // use new-style OBV support (factory object) 1371130803Smarcel factory = Utility.getFactory(clazz, codebase, orb, repId); 1372130803Smarcel } catch (MARSHAL marshal) { 1373130803Smarcel // XXX log marshal at one of the INFO levels 1374130803Smarcel 1375130803Smarcel // Could not get a factory, so try alternatives 1376130803Smarcel if (!StreamableValue.class.isAssignableFrom(clazz) && 1377130803Smarcel !CustomValue.class.isAssignableFrom(clazz) && 1378130803Smarcel ValueBase.class.isAssignableFrom(clazz)) { 1379130803Smarcel // use old-style OBV support (helper object) 1380130803Smarcel BoxedValueHelper helper = Utility.getHelper(clazz, codebase, repId); 1381130803Smarcel if (helper instanceof ValueHelper) 1382130803Smarcel return readIDLValueWithHelper((ValueHelper)helper, indirection); 1383130803Smarcel else 1384130803Smarcel return helper.read_value(parent); 1385130803Smarcel } else { 1386130803Smarcel // must be a boxed IDLEntity, so make a reflective call to the 1387130803Smarcel // helper's static read method... 1388130803Smarcel return readBoxedIDLEntity(clazz, codebase); 1389130803Smarcel } 1390130803Smarcel } 1391130803Smarcel 1392130803Smarcel // If there was no error in getting the factory, use it. 1393130803Smarcel valueIndirection = indirection; // for callback 1394130803Smarcel return factory.read_value(parent); 1395130803Smarcel } 1396130803Smarcel 1397130803Smarcel /** 1398130803Smarcel * End tags are only written for chunked valuetypes. 1399130803Smarcel * 1400130803Smarcel * Before Merlin, our ORBs wrote end tags which took into account 1401130803Smarcel * all enclosing valuetypes. This was changed by an interop resolution 1402130803Smarcel * (see details around chunkedValueNestingLevel) to only include 1403130803Smarcel * enclosing chunked types. 1404130803Smarcel * 1405130803Smarcel * ORB versioning and end tag compaction are handled here. 1406130803Smarcel */ 1407130803Smarcel private void readEndTag() { 1408130803Smarcel if (isChunked) { 1409130803Smarcel 1410130803Smarcel // Read the end tag 1411130803Smarcel int anEndTag = read_long(); 1412130803Smarcel 1413130803Smarcel // End tags should always be negative, and the outermost 1414130803Smarcel // enclosing chunked valuetype should have a -1 end tag. 1415130803Smarcel // 1416130803Smarcel // handleEndOfValue should have assured that we were 1417130803Smarcel // at the end tag position! 1418130803Smarcel if (anEndTag >= 0) { 1419130803Smarcel throw wrapper.positiveEndTag( CompletionStatus.COMPLETED_MAYBE, 1420130803Smarcel new Integer(anEndTag), new Integer( get_offset() - 4 ) ) ; 1421130803Smarcel } 1422130803Smarcel 1423130803Smarcel // If the ORB is null, or if we're sure we're talking to 1424130803Smarcel // a foreign ORB, Merlin, or something more recent, we 1425130803Smarcel // use the updated end tag computation, and are more strenuous 1426130803Smarcel // about the values. 1427130803Smarcel if (orb == null || 1428130803Smarcel ORBVersionFactory.getFOREIGN().equals(orb.getORBVersion()) || 1429130803Smarcel ORBVersionFactory.getNEWER().compareTo(orb.getORBVersion()) <= 0) { 1430130803Smarcel 1431130803Smarcel // If the end tag we read was less than what we were expecting, 1432130803Smarcel // then the sender must think it's sent more enclosing 1433130803Smarcel // chunked valuetypes than we have. Throw an exception. 1434130803Smarcel if (anEndTag < chunkedValueNestingLevel) 1435130803Smarcel throw wrapper.unexpectedEnclosingValuetype( 1436130803Smarcel CompletionStatus.COMPLETED_MAYBE, new Integer( anEndTag ), 1437130803Smarcel new Integer( chunkedValueNestingLevel ) ) ; 1438130803Smarcel 1439130803Smarcel // If the end tag is bigger than what we expected, but 1440130803Smarcel // still negative, then the sender has done some end tag 1441130803Smarcel // compaction. We back up the stream 4 bytes so that the 1442130803Smarcel // next time readEndTag is called, it will get down here 1443130803Smarcel // again. Even with fragmentation, we'll always be able 1444130803Smarcel // to do this. 1445130803Smarcel if (anEndTag != chunkedValueNestingLevel) { 1446130803Smarcel bbwi.position(bbwi.position() - 4); 1447130803Smarcel } 1448130803Smarcel 1449130803Smarcel } else { 1450130803Smarcel 1451130803Smarcel // When talking to Kestrel or Ladybird, we use our old 1452130803Smarcel // end tag rules and are less strict. If the end tag 1453130803Smarcel // isn't what we expected, we back up, assuming 1454130803Smarcel // compaction. 1455130803Smarcel if (anEndTag != end_flag) { 1456130803Smarcel bbwi.position(bbwi.position() - 4); 1457130803Smarcel } 1458130803Smarcel } 1459130803Smarcel 1460130803Smarcel // This only keeps track of the enclosing chunked 1461130803Smarcel // valuetypes 1462130803Smarcel chunkedValueNestingLevel++; 1463130803Smarcel } 1464130803Smarcel 1465130803Smarcel // This keeps track of all enclosing valuetypes 1466130803Smarcel end_flag++; 1467130803Smarcel } 1468130803Smarcel 1469130803Smarcel protected int get_offset() { 1470130803Smarcel return bbwi.position(); 1471130803Smarcel } 1472130803Smarcel 1473130803Smarcel private void start_block() { 1474130803Smarcel 1475130803Smarcel // if (outerValueDone) 1476130803Smarcel if (!isChunked) 1477130803Smarcel return; 1478130803Smarcel 1479130803Smarcel // if called from alignAndCheck, need to reset blockLength 1480130803Smarcel // to avoid an infinite recursion loop on read_long() call 1481130803Smarcel blockLength = maxBlockLength; 1482130803Smarcel 1483130803Smarcel blockLength = read_long(); 1484130803Smarcel 1485130803Smarcel // Must remember where we began the chunk to calculate how far 1486130803Smarcel // along we are. See notes above about chunkBeginPos. 1487130803Smarcel 1488130803Smarcel if (blockLength > 0 && blockLength < maxBlockLength) { 1489130803Smarcel blockLength += get_offset(); // _REVISIT_ unsafe, should use a Java long 1490130803Smarcel 1491130803Smarcel // inBlock = true; 1492130803Smarcel } else { 1493130803Smarcel 1494130803Smarcel // System.out.println("start_block snooped a " + Integer.toHexString(blockLength)); 1495130803Smarcel 1496130803Smarcel // not a chunk length field 1497130803Smarcel blockLength = maxBlockLength; 1498130803Smarcel 1499130803Smarcel bbwi.position(bbwi.position() - 4); 1500130803Smarcel } 1501130803Smarcel } 1502130803Smarcel 1503130803Smarcel // Makes sure that if we were reading a chunked value, we end up 1504130803Smarcel // at the right place in the stream, no matter how little the 1505130803Smarcel // unmarshalling code read. 1506130803Smarcel // 1507130803Smarcel // After calling this method, if we are chunking, we should be 1508130803Smarcel // in position to read the end tag. 1509130803Smarcel private void handleEndOfValue() { 1510130803Smarcel 1511130803Smarcel // If we're not chunking, we don't have to worry about 1512130803Smarcel // skipping remaining chunks or finding end tags 1513130803Smarcel if (!isChunked) 1514130803Smarcel return; 1515130803Smarcel 1516130803Smarcel // Skip any remaining chunks 1517130803Smarcel while (blockLength != maxBlockLength) { 1518130803Smarcel end_block(); 1519130803Smarcel start_block(); 1520130803Smarcel } 1521130803Smarcel 1522130803Smarcel // Now look for the end tag 1523130803Smarcel 1524130803Smarcel // This is a little wasteful since we're reading 1525130803Smarcel // this long up to 3 times in the worst cases (once 1526130803Smarcel // in start_block, once here, and once in readEndTag 1527130803Smarcel // 1528130803Smarcel // Peek next long 1529130803Smarcel int nextLong = read_long(); 1530130803Smarcel bbwi.position(bbwi.position() - 4); 1531130803Smarcel 1532130803Smarcel // We did find an end tag, so we're done. readEndTag 1533130803Smarcel // should take care of making sure it's the correct 1534130803Smarcel // end tag, etc. Remember that since end tags, 1535130803Smarcel // chunk lengths, and valuetags have non overlapping 1536130803Smarcel // ranges, we can tell by the value what the longs are. 1537130803Smarcel if (nextLong < 0) 1538130803Smarcel return; 1539130803Smarcel 1540130803Smarcel if (nextLong == 0 || nextLong >= maxBlockLength) { 1541130803Smarcel 1542130803Smarcel // A custom marshaled valuetype left extra data 1543130803Smarcel // on the wire, and that data had another 1544130803Smarcel // nested value inside of it. We've just 1545130803Smarcel // read the value tag or null of that nested value. 1546130803Smarcel // 1547130803Smarcel // In an attempt to get by it, we'll try to call 1548130803Smarcel // read_value() to get the nested value off of 1549130803Smarcel // the wire. Afterwards, we must call handleEndOfValue 1550130803Smarcel // recursively to read any further chunks that the containing 1551130803Smarcel // valuetype might still have after the nested 1552130803Smarcel // value. 1553130803Smarcel read_value(); 1554130803Smarcel handleEndOfValue(); 1555130803Smarcel } else { 1556130803Smarcel // This probably means that the code to skip chunks has 1557130803Smarcel // an error, and ended up setting blockLength to something 1558130803Smarcel // other than maxBlockLength even though we weren't 1559130803Smarcel // starting a new chunk. 1560130803Smarcel throw wrapper.couldNotSkipBytes( CompletionStatus.COMPLETED_MAYBE, 1561130803Smarcel new Integer( nextLong ), new Integer( get_offset() ) ) ; 1562130803Smarcel } 1563130803Smarcel } 1564130803Smarcel 1565130803Smarcel private void end_block() { 1566130803Smarcel 1567130803Smarcel // if in a chunk, check for underflow or overflow 1568130803Smarcel if (blockLength != maxBlockLength) { 1569130803Smarcel if (blockLength == get_offset()) { 1570130803Smarcel // Chunk ended correctly 1571130803Smarcel blockLength = maxBlockLength; 1572130803Smarcel } else { 1573130803Smarcel // Skip over anything left by bad unmarshaling code (ex: 1574130803Smarcel // a buggy custom unmarshaler). See handleEndOfValue. 1575130803Smarcel if (blockLength > get_offset()) { 1576130803Smarcel skipToOffset(blockLength); 1577130803Smarcel } else { 1578130803Smarcel throw wrapper.badChunkLength( new Integer( blockLength ), 1579130803Smarcel new Integer( get_offset() ) ) ; 1580130803Smarcel } 1581130803Smarcel } 1582130803Smarcel } 1583130803Smarcel } 1584130803Smarcel 1585130803Smarcel private int readValueTag(){ 1586130803Smarcel // outerValueDone = false; 1587130803Smarcel return read_long(); 1588130803Smarcel } 1589130803Smarcel 1590130803Smarcel public org.omg.CORBA.ORB orb() { 1591130803Smarcel return orb; 1592130803Smarcel } 1593130803Smarcel 1594130803Smarcel // ------------ End RMI related methods -------------------------- 1595130803Smarcel 1596130803Smarcel public final void read_boolean_array(boolean[] value, int offset, int length) { 1597130803Smarcel for(int i=0; i < length; i++) { 1598130803Smarcel value[i+offset] = read_boolean(); 1599130803Smarcel } 1600130803Smarcel } 1601130803Smarcel 1602130803Smarcel public final void read_char_array(char[] value, int offset, int length) { 1603130803Smarcel for(int i=0; i < length; i++) { 1604130803Smarcel value[i+offset] = read_char(); 1605130803Smarcel } 1606130803Smarcel } 1607130803Smarcel 1608130803Smarcel public final void read_wchar_array(char[] value, int offset, int length) { 1609130803Smarcel for(int i=0; i < length; i++) { 1610130803Smarcel value[i+offset] = read_wchar(); 1611130803Smarcel } 1612130803Smarcel } 1613130803Smarcel 1614130803Smarcel public final void read_short_array(short[] value, int offset, int length) { 1615130803Smarcel for(int i=0; i < length; i++) { 1616130803Smarcel value[i+offset] = read_short(); 1617130803Smarcel } 1618130803Smarcel } 1619130803Smarcel 1620130803Smarcel public final void read_ushort_array(short[] value, int offset, int length) { 1621130803Smarcel read_short_array(value, offset, length); 1622130803Smarcel } 1623130803Smarcel 1624130803Smarcel public final void read_long_array(int[] value, int offset, int length) { 1625130803Smarcel for(int i=0; i < length; i++) { 1626130803Smarcel value[i+offset] = read_long(); 1627130803Smarcel } 1628130803Smarcel } 1629130803Smarcel 1630130803Smarcel public final void read_ulong_array(int[] value, int offset, int length) { 1631130803Smarcel read_long_array(value, offset, length); 1632130803Smarcel } 1633130803Smarcel 1634130803Smarcel public final void read_longlong_array(long[] value, int offset, int length) { 1635130803Smarcel for(int i=0; i < length; i++) { 1636130803Smarcel value[i+offset] = read_longlong(); 1637130803Smarcel } 1638130803Smarcel } 1639130803Smarcel 1640130803Smarcel public final void read_ulonglong_array(long[] value, int offset, int length) { 1641130803Smarcel read_longlong_array(value, offset, length); 1642130803Smarcel } 1643130803Smarcel 1644130803Smarcel public final void read_float_array(float[] value, int offset, int length) { 1645130803Smarcel for(int i=0; i < length; i++) { 1646130803Smarcel value[i+offset] = read_float(); 1647130803Smarcel } 1648130803Smarcel } 1649130803Smarcel 1650130803Smarcel public final void read_double_array(double[] value, int offset, int length) { 1651130803Smarcel for(int i=0; i < length; i++) { 1652130803Smarcel value[i+offset] = read_double(); 1653130803Smarcel } 1654130803Smarcel } 1655130803Smarcel 1656130803Smarcel public final void read_any_array(org.omg.CORBA.Any[] value, int offset, int length) { 1657130803Smarcel for(int i=0; i < length; i++) { 1658130803Smarcel value[i+offset] = read_any(); 1659130803Smarcel } 1660130803Smarcel } 1661130803Smarcel 1662130803Smarcel //--------------------------------------------------------------------// 1663130803Smarcel // CDRInputStream state management. 1664130803Smarcel // 1665130803Smarcel 1666130803Smarcel /** 1667130803Smarcel * Are we at the end of the input stream? 1668130803Smarcel */ 1669130803Smarcel// public final boolean isAtEnd() { 1670130803Smarcel// return bbwi.position() == bbwi.buflen; 1671130803Smarcel// } 1672130803Smarcel 1673130803Smarcel// public int available() throws IOException { 1674130803Smarcel// return bbwi.buflen - bbwi.position(); 1675130803Smarcel// } 1676130803Smarcel 1677130803Smarcel private String read_repositoryIds() { 1678130803Smarcel 1679130803Smarcel // Read # of repository ids 1680130803Smarcel int numRepIds = read_long(); 1681130803Smarcel if (numRepIds == 0xffffffff) { 1682130803Smarcel int indirection = read_long() + get_offset() - 4; 1683130803Smarcel if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection)) 1684130803Smarcel return (String)repositoryIdCache.getKey(indirection); 1685130803Smarcel else 1686130803Smarcel throw wrapper.unableToLocateRepIdArray( new Integer( indirection ) ) ; 1687130803Smarcel } else { 1688130803Smarcel 1689130803Smarcel // read first array element and store it as an indirection to the whole array 1690130803Smarcel int indirection = get_offset(); 1691130803Smarcel String repID = read_repositoryId(); 1692130803Smarcel if (repositoryIdCache == null) 1693130803Smarcel repositoryIdCache = new CacheTable(orb,false); 1694130803Smarcel repositoryIdCache.put(repID, indirection); 1695130803Smarcel 1696130803Smarcel // read and ignore the subsequent array elements, but put them in the 1697130803Smarcel // indirection table in case there are later indirections back to them 1698130803Smarcel for (int i = 1; i < numRepIds; i++) { 1699130803Smarcel read_repositoryId(); 1700130803Smarcel } 1701130803Smarcel 1702130803Smarcel return repID; 1703130803Smarcel } 1704130803Smarcel } 1705130803Smarcel 1706130803Smarcel private final String read_repositoryId() 1707130803Smarcel { 1708130803Smarcel String result = readStringOrIndirection(true); 1709130803Smarcel 1710130803Smarcel if (result == null) { // Indirection 1711130803Smarcel int indirection = read_long() + get_offset() - 4; 1712130803Smarcel 1713130803Smarcel if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection)) 1714130803Smarcel return (String)repositoryIdCache.getKey(indirection); 1715130803Smarcel else 1716130803Smarcel throw wrapper.badRepIdIndirection( CompletionStatus.COMPLETED_MAYBE, 1717130803Smarcel new Integer(bbwi.position()) ) ; 1718130803Smarcel } else { 1719130803Smarcel if (repositoryIdCache == null) 1720130803Smarcel repositoryIdCache = new CacheTable(orb,false); 1721130803Smarcel repositoryIdCache.put(result, stringIndirection); 1722130803Smarcel } 1723130803Smarcel 1724130803Smarcel return result ; 1725130803Smarcel } 1726130803Smarcel 1727130803Smarcel private final String read_codebase_URL() 1728130803Smarcel { 1729130803Smarcel String result = readStringOrIndirection(true); 1730130803Smarcel 1731130803Smarcel if (result == null) { // Indirection 1732130803Smarcel int indirection = read_long() + get_offset() - 4; 1733130803Smarcel 1734130803Smarcel if (codebaseCache != null && codebaseCache.containsVal(indirection)) 1735130803Smarcel return (String)codebaseCache.getKey(indirection); 1736130803Smarcel else 1737130803Smarcel throw wrapper.badCodebaseIndirection( 1738130803Smarcel CompletionStatus.COMPLETED_MAYBE, 1739130803Smarcel new Integer(bbwi.position()) ) ; 1740130803Smarcel } else { 1741130803Smarcel if (codebaseCache == null) 1742130803Smarcel codebaseCache = new CacheTable(orb,false); 1743130803Smarcel codebaseCache.put(result, stringIndirection); 1744130803Smarcel } 1745130803Smarcel 1746130803Smarcel return result; 1747130803Smarcel } 1748130803Smarcel 1749130803Smarcel /* DataInputStream methods */ 1750130803Smarcel 1751130803Smarcel public java.lang.Object read_Abstract () { 1752130803Smarcel return read_abstract_interface(); 1753130803Smarcel } 1754130803Smarcel 1755130803Smarcel public java.io.Serializable read_Value () { 1756130803Smarcel return read_value(); 1757130803Smarcel } 1758130803Smarcel 1759130803Smarcel public void read_any_array (org.omg.CORBA.AnySeqHolder seq, int offset, int length) { 1760130803Smarcel read_any_array(seq.value, offset, length); 1761130803Smarcel } 1762130803Smarcel 1763130803Smarcel public void read_boolean_array (org.omg.CORBA.BooleanSeqHolder seq, int offset, int length) { 1764130803Smarcel read_boolean_array(seq.value, offset, length); 1765130803Smarcel } 1766130803Smarcel 1767130803Smarcel public void read_char_array (org.omg.CORBA.CharSeqHolder seq, int offset, int length) { 1768130803Smarcel read_char_array(seq.value, offset, length); 1769130803Smarcel } 1770130803Smarcel 1771130803Smarcel public void read_wchar_array (org.omg.CORBA.WCharSeqHolder seq, int offset, int length) { 1772130803Smarcel read_wchar_array(seq.value, offset, length); 1773130803Smarcel } 1774130803Smarcel 1775130803Smarcel public void read_octet_array (org.omg.CORBA.OctetSeqHolder seq, int offset, int length) { 1776130803Smarcel read_octet_array(seq.value, offset, length); 1777130803Smarcel } 1778130803Smarcel 1779130803Smarcel public void read_short_array (org.omg.CORBA.ShortSeqHolder seq, int offset, int length) { 1780130803Smarcel read_short_array(seq.value, offset, length); 1781130803Smarcel } 1782130803Smarcel 1783130803Smarcel public void read_ushort_array (org.omg.CORBA.UShortSeqHolder seq, int offset, int length) { 1784130803Smarcel read_ushort_array(seq.value, offset, length); 1785130803Smarcel } 1786130803Smarcel 1787130803Smarcel public void read_long_array (org.omg.CORBA.LongSeqHolder seq, int offset, int length) { 1788130803Smarcel read_long_array(seq.value, offset, length); 1789130803Smarcel } 1790130803Smarcel 1791130803Smarcel public void read_ulong_array (org.omg.CORBA.ULongSeqHolder seq, int offset, int length) { 1792130803Smarcel read_ulong_array(seq.value, offset, length); 1793130803Smarcel } 1794130803Smarcel 1795130803Smarcel public void read_ulonglong_array (org.omg.CORBA.ULongLongSeqHolder seq, int offset, int length) { 1796130803Smarcel read_ulonglong_array(seq.value, offset, length); 1797130803Smarcel } 1798130803Smarcel 1799130803Smarcel public void read_longlong_array (org.omg.CORBA.LongLongSeqHolder seq, int offset, int length) { 1800130803Smarcel read_longlong_array(seq.value, offset, length); 1801130803Smarcel } 1802130803Smarcel 1803130803Smarcel public void read_float_array (org.omg.CORBA.FloatSeqHolder seq, int offset, int length) { 1804130803Smarcel read_float_array(seq.value, offset, length); 1805130803Smarcel } 1806130803Smarcel 1807130803Smarcel public void read_double_array (org.omg.CORBA.DoubleSeqHolder seq, int offset, int length) { 1808130803Smarcel read_double_array(seq.value, offset, length); 1809130803Smarcel } 1810130803Smarcel 1811130803Smarcel public java.math.BigDecimal read_fixed(short digits, short scale) { 1812130803Smarcel // digits isn't really needed here 1813130803Smarcel StringBuffer buffer = read_fixed_buffer(); 1814130803Smarcel if (digits != buffer.length()) 1815130803Smarcel throw wrapper.badFixed( new Integer(digits), 1816130803Smarcel new Integer(buffer.length()) ) ; 1817130803Smarcel buffer.insert(digits - scale, '.'); 1818130803Smarcel return new BigDecimal(buffer.toString()); 1819130803Smarcel } 1820130803Smarcel 1821130803Smarcel // This method is unable to yield the correct scale. 1822130803Smarcel public java.math.BigDecimal read_fixed() { 1823130803Smarcel return new BigDecimal(read_fixed_buffer().toString()); 1824130803Smarcel } 1825130803Smarcel 1826130803Smarcel // Each octet contains (up to) two decimal digits. 1827130803Smarcel // If the fixed type has an odd number of decimal digits, then the representation 1828130803Smarcel // begins with the first (most significant) digit. 1829130803Smarcel // Otherwise, this first half-octet is all zero, and the first digit 1830130803Smarcel // is in the second half-octet. 1831130803Smarcel // The sign configuration, in the last half-octet of the representation, 1832130803Smarcel // is 0xD for negative numbers and 0xC for positive and zero values. 1833130803Smarcel private StringBuffer read_fixed_buffer() { 1834130803Smarcel StringBuffer buffer = new StringBuffer(64); 1835130803Smarcel byte doubleDigit; 1836130803Smarcel int firstDigit; 1837130803Smarcel int secondDigit; 1838130803Smarcel boolean wroteFirstDigit = false; 1839130803Smarcel boolean more = true; 1840130803Smarcel while (more) { 1841130803Smarcel doubleDigit = this.read_octet(); 1842130803Smarcel firstDigit = (int)((doubleDigit & 0xf0) >> 4); 1843130803Smarcel secondDigit = (int)(doubleDigit & 0x0f); 1844130803Smarcel if (wroteFirstDigit || firstDigit != 0) { 1845130803Smarcel buffer.append(Character.forDigit(firstDigit, 10)); 1846130803Smarcel wroteFirstDigit = true; 1847130803Smarcel } 1848130803Smarcel if (secondDigit == 12) { 1849130803Smarcel // positive number or zero 1850130803Smarcel if ( ! wroteFirstDigit) { 1851130803Smarcel // zero 1852130803Smarcel return new StringBuffer("0.0"); 1853130803Smarcel } else { 1854130803Smarcel // positive number 1855130803Smarcel // done 1856130803Smarcel } 1857130803Smarcel more = false; 1858130803Smarcel } else if (secondDigit == 13) { 1859130803Smarcel // negative number 1860130803Smarcel buffer.insert(0, '-'); 1861130803Smarcel more = false; 1862130803Smarcel } else { 1863130803Smarcel buffer.append(Character.forDigit(secondDigit, 10)); 1864130803Smarcel wroteFirstDigit = true; 1865130803Smarcel } 1866130803Smarcel } 1867130803Smarcel return buffer; 1868130803Smarcel } 1869130803Smarcel 1870130803Smarcel private final static String _id = "IDL:omg.org/CORBA/DataInputStream:1.0"; 1871130803Smarcel private final static String[] _ids = { _id }; 1872130803Smarcel 1873130803Smarcel public String[] _truncatable_ids() { 1874130803Smarcel if (_ids == null) 1875130803Smarcel return null; 1876130803Smarcel 1877130803Smarcel return (String[])_ids.clone(); 1878130803Smarcel } 1879130803Smarcel 1880130803Smarcel /* for debugging */ 1881130803Smarcel 1882130803Smarcel public void printBuffer() { 1883130803Smarcel CDRInputStream_1_0.printBuffer(this.bbwi); 1884130803Smarcel } 1885130803Smarcel 1886130803Smarcel public static void printBuffer(ByteBufferWithInfo bbwi) { 1887130803Smarcel 1888130803Smarcel System.out.println("----- Input Buffer -----"); 1889130803Smarcel System.out.println(); 1890130803Smarcel System.out.println("Current position: " + bbwi.position()); 1891130803Smarcel System.out.println("Total length : " + bbwi.buflen); 1892130803Smarcel System.out.println(); 1893130803Smarcel 1894130803Smarcel try { 1895130803Smarcel 1896130803Smarcel char[] charBuf = new char[16]; 1897130803Smarcel 1898130803Smarcel for (int i = 0; i < bbwi.buflen; i += 16) { 1899130803Smarcel 1900130803Smarcel int j = 0; 1901130803Smarcel 1902130803Smarcel // For every 16 bytes, there is one line 1903130803Smarcel // of output. First, the hex output of 1904130803Smarcel // the 16 bytes with each byte separated 1905130803Smarcel // by a space. 1906130803Smarcel while (j < 16 && j + i < bbwi.buflen) { 1907130803Smarcel int k = bbwi.byteBuffer.get(i + j); 1908130803Smarcel if (k < 0) 1909130803Smarcel k = 256 + k; 1910130803Smarcel String hex = Integer.toHexString(k); 1911130803Smarcel if (hex.length() == 1) 1912130803Smarcel hex = "0" + hex; 1913130803Smarcel System.out.print(hex + " "); 1914130803Smarcel j++; 1915130803Smarcel } 1916130803Smarcel 1917130803Smarcel // Add any extra spaces to align the 1918130803Smarcel // text column in case we didn't end 1919130803Smarcel // at 16 1920130803Smarcel while (j < 16) { 1921130803Smarcel System.out.print(" "); 1922130803Smarcel j++; 1923130803Smarcel } 1924130803Smarcel 1925130803Smarcel // Now output the ASCII equivalents. Non-ASCII 1926130803Smarcel // characters are shown as periods. 1927130803Smarcel int x = 0; 1928130803Smarcel while (x < 16 && x + i < bbwi.buflen) { 1929130803Smarcel if (ORBUtility.isPrintable((char)bbwi.byteBuffer.get(i + x))) 1930130803Smarcel charBuf[x] = (char)bbwi.byteBuffer.get(i + x); 1931130803Smarcel else 1932130803Smarcel charBuf[x] = '.'; 1933130803Smarcel x++; 1934130803Smarcel } 1935130803Smarcel System.out.println(new String(charBuf, 0, x)); 1936130803Smarcel } 1937130803Smarcel 1938130803Smarcel } catch (Throwable t) { 1939130803Smarcel t.printStackTrace(); 1940130803Smarcel } 1941130803Smarcel 1942130803Smarcel System.out.println("------------------------"); 1943130803Smarcel } 1944130803Smarcel 1945130803Smarcel public ByteBuffer getByteBuffer() { 1946130803Smarcel ByteBuffer result = null; 1947130803Smarcel if (bbwi != null) { 1948130803Smarcel result = bbwi.byteBuffer; 1949130803Smarcel } 1950130803Smarcel return result; 1951130803Smarcel } 1952130803Smarcel 1953130803Smarcel public int getBufferLength() { 1954130803Smarcel return bbwi.buflen; 1955130803Smarcel } 1956130803Smarcel 1957130803Smarcel public void setBufferLength(int value) { 1958130803Smarcel bbwi.buflen = value; 1959130803Smarcel bbwi.byteBuffer.limit(bbwi.buflen); 1960130803Smarcel } 1961130803Smarcel 1962130803Smarcel public void setByteBufferWithInfo(ByteBufferWithInfo bbwi) { 1963130803Smarcel this.bbwi = bbwi; 1964130803Smarcel } 1965130803Smarcel 1966130803Smarcel public void setByteBuffer(ByteBuffer byteBuffer) { 1967130803Smarcel bbwi.byteBuffer = byteBuffer; 1968130803Smarcel } 1969130803Smarcel 1970130803Smarcel public int getIndex() { 1971130803Smarcel return bbwi.position(); 1972130803Smarcel } 1973130803Smarcel 1974130803Smarcel public void setIndex(int value) { 1975130803Smarcel bbwi.position(value); 1976130803Smarcel } 1977130803Smarcel 1978130803Smarcel public boolean isLittleEndian() { 1979130803Smarcel return littleEndian; 1980130803Smarcel } 1981130803Smarcel 1982130803Smarcel public void orb(org.omg.CORBA.ORB orb) { 1983130803Smarcel this.orb = (ORB)orb; 1984130803Smarcel } 1985130803Smarcel 1986130803Smarcel public BufferManagerRead getBufferManager() { 1987130803Smarcel return bufferManagerRead; 1988130803Smarcel } 1989130803Smarcel 1990130803Smarcel private void skipToOffset(int offset) { 1991130803Smarcel 1992130803Smarcel // Number of bytes to skip 1993130803Smarcel int len = offset - get_offset(); 1994130803Smarcel 1995130803Smarcel int n = 0; 1996130803Smarcel 1997130803Smarcel while (n < len) { 1998130803Smarcel int avail; 1999130803Smarcel int bytes; 2000130803Smarcel int wanted; 2001130803Smarcel 2002130803Smarcel avail = bbwi.buflen - bbwi.position(); 2003130803Smarcel if (avail <= 0) { 2004130803Smarcel grow(1, 1); 2005130803Smarcel avail = bbwi.buflen - bbwi.position(); 2006130803Smarcel } 2007130803Smarcel 2008130803Smarcel wanted = len - n; 2009130803Smarcel bytes = (wanted < avail) ? wanted : avail; 2010130803Smarcel bbwi.position(bbwi.position() + bytes); 2011130803Smarcel n += bytes; 2012130803Smarcel } 2013130803Smarcel } 2014130803Smarcel 2015130803Smarcel 2016130803Smarcel // Mark and reset ------------------------------------------------- 2017130803Smarcel 2018130803Smarcel protected MarkAndResetHandler markAndResetHandler = null; 2019130803Smarcel 2020130803Smarcel protected class StreamMemento 2021130803Smarcel { 2022130803Smarcel // These are the fields that may change after marking 2023130803Smarcel // the stream position, so we need to save them. 2024130803Smarcel private int blockLength_; 2025130803Smarcel private int end_flag_; 2026130803Smarcel private int chunkedValueNestingLevel_; 2027130803Smarcel private int valueIndirection_; 2028130803Smarcel private int stringIndirection_; 2029130803Smarcel private boolean isChunked_; 2030130803Smarcel private javax.rmi.CORBA.ValueHandler valueHandler_; 2031130803Smarcel private ByteBufferWithInfo bbwi_; 2032130803Smarcel private boolean specialNoOptionalDataState_; 2033130803Smarcel 2034130803Smarcel public StreamMemento() 2035130803Smarcel { 2036130803Smarcel blockLength_ = blockLength; 2037130803Smarcel end_flag_ = end_flag; 2038130803Smarcel chunkedValueNestingLevel_ = chunkedValueNestingLevel; 2039130803Smarcel valueIndirection_ = valueIndirection; 2040130803Smarcel stringIndirection_ = stringIndirection; 2041130803Smarcel isChunked_ = isChunked; 2042130803Smarcel valueHandler_ = valueHandler; 2043130803Smarcel specialNoOptionalDataState_ = specialNoOptionalDataState; 2044130803Smarcel bbwi_ = new ByteBufferWithInfo(bbwi); 2045130803Smarcel } 2046130803Smarcel } 2047130803Smarcel 2048130803Smarcel public java.lang.Object createStreamMemento() { 2049130803Smarcel return new StreamMemento(); 2050130803Smarcel } 2051130803Smarcel 2052130803Smarcel public void restoreInternalState(java.lang.Object streamMemento) { 2053130803Smarcel 2054130803Smarcel StreamMemento mem = (StreamMemento)streamMemento; 2055130803Smarcel 2056130803Smarcel blockLength = mem.blockLength_; 2057130803Smarcel end_flag = mem.end_flag_; 2058130803Smarcel chunkedValueNestingLevel = mem.chunkedValueNestingLevel_; 2059130803Smarcel valueIndirection = mem.valueIndirection_; 2060130803Smarcel stringIndirection = mem.stringIndirection_; 2061130803Smarcel isChunked = mem.isChunked_; 2062130803Smarcel valueHandler = mem.valueHandler_; 2063130803Smarcel specialNoOptionalDataState = mem.specialNoOptionalDataState_; 2064130803Smarcel bbwi = mem.bbwi_; 2065130803Smarcel } 2066130803Smarcel 2067130803Smarcel public int getPosition() { 2068130803Smarcel return get_offset(); 2069130803Smarcel } 2070130803Smarcel 2071130803Smarcel public void mark(int readlimit) { 2072130803Smarcel markAndResetHandler.mark(this); 2073130803Smarcel } 2074130803Smarcel 2075130803Smarcel public void reset() { 2076130803Smarcel markAndResetHandler.reset(); 2077130803Smarcel } 2078130803Smarcel 2079130803Smarcel // ---------------------------------- end Mark and Reset 2080130803Smarcel 2081130803Smarcel // Provides a hook so subclasses of CDRInputStream can provide 2082130803Smarcel // a CodeBase. This ultimately allows us to grab a Connection 2083130803Smarcel // instance in IIOPInputStream, the only subclass where this 2084130803Smarcel // is actually used. 2085130803Smarcel CodeBase getCodeBase() { 2086130803Smarcel return parent.getCodeBase(); 2087130803Smarcel } 2088130803Smarcel 2089130803Smarcel /** 2090130803Smarcel * Attempts to find the class described by the given 2091130803Smarcel * repository ID string and expected type. The first 2092130803Smarcel * attempt is to find the class locally, falling back 2093130803Smarcel * on the URL that came with the value. The second 2094130803Smarcel * attempt is to use a URL from the remote CodeBase. 2095130803Smarcel */ 2096130803Smarcel private Class getClassFromString(String repositoryIDString, 2097130803Smarcel String codebaseURL, 2098130803Smarcel Class expectedType) 2099130803Smarcel { 2100130803Smarcel RepositoryIdInterface repositoryID 2101130803Smarcel = repIdStrs.getFromString(repositoryIDString); 2102130803Smarcel 2103130803Smarcel try { 2104130803Smarcel try { 2105130803Smarcel // First try to load the class locally, then use 2106130803Smarcel // the provided URL (if it isn't null) 2107130803Smarcel return repositoryID.getClassFromType(expectedType, 2108130803Smarcel codebaseURL); 2109130803Smarcel } catch (ClassNotFoundException cnfeOuter) { 2110130803Smarcel 2111130803Smarcel try { 2112130803Smarcel 2113130803Smarcel if (getCodeBase() == null) { 2114130803Smarcel return null; // class cannot be loaded remotely. 2115130803Smarcel } 2116130803Smarcel 2117130803Smarcel // Get a URL from the remote CodeBase and retry 2118130803Smarcel codebaseURL = getCodeBase().implementation(repositoryIDString); 2119130803Smarcel 2120130803Smarcel // Don't bother trying to find it locally again if 2121130803Smarcel // we got a null URL 2122130803Smarcel if (codebaseURL == null) 2123130803Smarcel return null; 2124130803Smarcel 2125130803Smarcel return repositoryID.getClassFromType(expectedType, 2126130803Smarcel codebaseURL); 2127130803Smarcel } catch (ClassNotFoundException cnfeInner) { 2128130803Smarcel dprintThrowable(cnfeInner); 2129130803Smarcel // Failed to load the class 2130130803Smarcel return null; 2131130803Smarcel } 2132130803Smarcel } 2133130803Smarcel } catch (MalformedURLException mue) { 2134130803Smarcel // Always report a bad URL 2135130803Smarcel throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE, 2136130803Smarcel mue, repositoryIDString, codebaseURL ) ; 2137130803Smarcel } 2138130803Smarcel } 2139130803Smarcel 2140130803Smarcel /** 2141130803Smarcel * Attempts to find the class described by the given 2142130803Smarcel * repository ID string. At most, three attempts are made: 2143130803Smarcel * Try to find it locally, through the provided URL, and 2144130803Smarcel * finally, via a URL from the remote CodeBase. 2145130803Smarcel */ 2146130803Smarcel private Class getClassFromString(String repositoryIDString, 2147130803Smarcel String codebaseURL) 2148130803Smarcel { 2149130803Smarcel RepositoryIdInterface repositoryID 2150130803Smarcel = repIdStrs.getFromString(repositoryIDString); 2151130803Smarcel 2152130803Smarcel for (int i = 0; i < 3; i++) { 2153130803Smarcel 2154130803Smarcel try { 2155130803Smarcel 2156130803Smarcel switch (i) 2157130803Smarcel { 2158130803Smarcel case 0: 2159130803Smarcel // First try to load the class locally 2160130803Smarcel return repositoryID.getClassFromType(); 2161130803Smarcel case 1: 2162130803Smarcel // Try to load the class using the provided 2163130803Smarcel // codebase URL (falls out below) 2164130803Smarcel break; 2165130803Smarcel case 2: 2166130803Smarcel // Try to load the class using a URL from the 2167130803Smarcel // remote CodeBase 2168130803Smarcel codebaseURL = getCodeBase().implementation(repositoryIDString); 2169130803Smarcel break; 2170130803Smarcel } 2171130803Smarcel 2172130803Smarcel // Don't bother if the codebaseURL is null 2173130803Smarcel if (codebaseURL == null) 2174130803Smarcel continue; 2175130803Smarcel 2176130803Smarcel return repositoryID.getClassFromType(codebaseURL); 2177130803Smarcel 2178130803Smarcel } catch(ClassNotFoundException cnfe) { 2179130803Smarcel // Will ultimately return null if all three 2180130803Smarcel // attempts fail, but don't do anything here. 2181130803Smarcel } catch (MalformedURLException mue) { 2182130803Smarcel throw wrapper.malformedUrl( CompletionStatus.COMPLETED_MAYBE, 2183130803Smarcel mue, repositoryIDString, codebaseURL ) ; 2184130803Smarcel } 2185130803Smarcel } 2186130803Smarcel 2187130803Smarcel // If we get here, we have failed to load the class 2188130803Smarcel dprint("getClassFromString failed with rep id " 2189130803Smarcel + repositoryIDString 2190130803Smarcel + " and codebase " 2191130803Smarcel + codebaseURL); 2192130803Smarcel 2193130803Smarcel return null; 2194130803Smarcel } 2195130803Smarcel 2196130803Smarcel // Utility method used to get chars from bytes 2197130803Smarcel char[] getConvertedChars(int numBytes, 2198130803Smarcel CodeSetConversion.BTCConverter converter) { 2199130803Smarcel 2200130803Smarcel // REVISIT - Look at CodeSetConversion.BTCConverter to see 2201130803Smarcel // if it can work with an NIO ByteBuffer. We should 2202130803Smarcel // avoid getting the bytes into an array if possible. 2203130803Smarcel 2204130803Smarcel // To be honest, I doubt this saves much real time 2205130803Smarcel if (bbwi.buflen - bbwi.position() >= numBytes) { 2206130803Smarcel // If the entire string is in this buffer, 2207130803Smarcel // just convert directly from the bbwi rather than 2208130803Smarcel // allocating and copying. 2209130803Smarcel byte[] tmpBuf; 2210130803Smarcel if (bbwi.byteBuffer.hasArray()) 2211130803Smarcel { 2212130803Smarcel tmpBuf = bbwi.byteBuffer.array(); 2213130803Smarcel } 2214130803Smarcel else 2215130803Smarcel { 2216130803Smarcel tmpBuf = new byte[bbwi.buflen]; 2217130803Smarcel // Microbenchmarks are showing a loop of ByteBuffer.get(int) 2218130803Smarcel // being faster than ByteBuffer.get(byte[], int, int). 2219130803Smarcel for (int i = 0; i < bbwi.buflen; i++) 2220130803Smarcel tmpBuf[i] = bbwi.byteBuffer.get(i); 2221130803Smarcel } 2222130803Smarcel char[] result = converter.getChars(tmpBuf,bbwi.position(),numBytes); 2223130803Smarcel 2224130803Smarcel bbwi.position(bbwi.position() + numBytes); 2225130803Smarcel return result; 2226130803Smarcel } else { 2227130803Smarcel // Stretches across buffers. Unless we provide an 2228130803Smarcel // incremental conversion interface, allocate and 2229130803Smarcel // copy the bytes. 2230130803Smarcel byte[] bytes = new byte[numBytes]; 2231130803Smarcel read_octet_array(bytes, 0, bytes.length); 2232130803Smarcel 2233130803Smarcel return converter.getChars(bytes, 0, numBytes); 2234130803Smarcel } 2235130803Smarcel } 2236130803Smarcel 2237130803Smarcel protected CodeSetConversion.BTCConverter getCharConverter() { 2238130803Smarcel if (charConverter == null) 2239130803Smarcel charConverter = parent.createCharBTCConverter(); 2240130803Smarcel 2241130803Smarcel return charConverter; 2242130803Smarcel } 2243130803Smarcel 2244130803Smarcel protected CodeSetConversion.BTCConverter getWCharConverter() { 2245130803Smarcel if (wcharConverter == null) 2246130803Smarcel wcharConverter = parent.createWCharBTCConverter(); 2247130803Smarcel 2248130803Smarcel return wcharConverter; 2249130803Smarcel } 2250130803Smarcel 2251130803Smarcel protected void dprintThrowable(Throwable t) { 2252130803Smarcel if (debug && t != null) 2253130803Smarcel t.printStackTrace(); 2254130803Smarcel } 2255130803Smarcel 2256130803Smarcel protected void dprint(String msg) { 2257130803Smarcel if (debug) { 2258130803Smarcel ORBUtility.dprint(this, msg); 2259130803Smarcel } 2260130803Smarcel } 2261130803Smarcel 2262130803Smarcel /** 2263130803Smarcel * Aligns the current position on the given octet boundary 2264130803Smarcel * if there are enough bytes available to do so. Otherwise, 2265130803Smarcel * it just returns. This is used for some (but not all) 2266130803Smarcel * GIOP 1.2 message headers. 2267130803Smarcel */ 2268130803Smarcel 2269130803Smarcel void alignOnBoundary(int octetBoundary) { 2270130803Smarcel int needed = computeAlignment(bbwi.position(), octetBoundary); 2271130803Smarcel 2272130803Smarcel if (bbwi.position() + needed <= bbwi.buflen) 2273130803Smarcel { 2274130803Smarcel bbwi.position(bbwi.position() + needed); 2275130803Smarcel } 2276130803Smarcel } 2277130803Smarcel 2278130803Smarcel public void resetCodeSetConverters() { 2279130803Smarcel charConverter = null; 2280130803Smarcel wcharConverter = null; 2281130803Smarcel } 2282130803Smarcel 2283130803Smarcel public void start_value() { 2284130803Smarcel // Read value tag 2285130803Smarcel int vType = readValueTag(); 2286130803Smarcel 2287130803Smarcel if (vType == 0) { 2288130803Smarcel // Stream needs to go into a state where it 2289130803Smarcel // throws standard exception until end_value 2290130803Smarcel // is called. This means the sender didn't 2291130803Smarcel // send any custom data. If the reader here 2292130803Smarcel // tries to read more, we need to throw an 2293130803Smarcel // exception before reading beyond where 2294130803Smarcel // we're supposed to 2295130803Smarcel specialNoOptionalDataState = true; 2296130803Smarcel 2297130803Smarcel return; 2298130803Smarcel } 2299130803Smarcel 2300130803Smarcel if (vType == 0xffffffff) { 2301130803Smarcel // One should never indirect to a custom wrapper 2302130803Smarcel throw wrapper.customWrapperIndirection( 2303130803Smarcel CompletionStatus.COMPLETED_MAYBE); 2304130803Smarcel } 2305130803Smarcel 2306130803Smarcel if (repIdUtil.isCodeBasePresent(vType)) { 2307130803Smarcel throw wrapper.customWrapperWithCodebase( 2308130803Smarcel CompletionStatus.COMPLETED_MAYBE); 2309130803Smarcel } 2310130803Smarcel 2311130803Smarcel if (repIdUtil.getTypeInfo(vType) 2312130803Smarcel != RepositoryIdUtility.SINGLE_REP_TYPE_INFO) { 2313130803Smarcel throw wrapper.customWrapperNotSingleRepid( 2314130803Smarcel CompletionStatus.COMPLETED_MAYBE); 2315130803Smarcel } 2316130803Smarcel 2317130803Smarcel 2318130803Smarcel // REVISIT - Could verify repository ID even though 2319130803Smarcel // it isn't used elsewhere 2320130803Smarcel read_repositoryId(); 2321130803Smarcel 2322130803Smarcel // Note: isChunked should be true here. Should have 2323130803Smarcel // been set to true in the containing value's read_value 2324130803Smarcel // method. 2325130803Smarcel 2326130803Smarcel start_block(); 2327130803Smarcel end_flag--; 2328130803Smarcel chunkedValueNestingLevel--; 2329130803Smarcel } 2330130803Smarcel 2331130803Smarcel public void end_value() { 2332130803Smarcel 2333130803Smarcel if (specialNoOptionalDataState) { 2334130803Smarcel specialNoOptionalDataState = false; 2335130803Smarcel return; 2336130803Smarcel } 2337130803Smarcel 2338130803Smarcel handleEndOfValue(); 2339130803Smarcel readEndTag(); 2340130803Smarcel 2341130803Smarcel // Note that isChunked should still be true here. 2342130803Smarcel // If the containing valuetype is the highest 2343130803Smarcel // chunked value, it will get set to false 2344130803Smarcel // at the end of read_value. 2345130803Smarcel 2346130803Smarcel // allow for possible continuation chunk 2347130803Smarcel start_block(); 2348130803Smarcel } 2349130803Smarcel 2350130803Smarcel public void close() throws IOException 2351130803Smarcel { 2352130803Smarcel 2353130803Smarcel // tell BufferManagerRead to release any ByteBuffers 2354130803Smarcel getBufferManager().close(bbwi); 2355130803Smarcel 2356130803Smarcel // It's possible bbwi.byteBuffer is shared between 2357130803Smarcel // this InputStream and an OutputStream. Thus, we check 2358130803Smarcel // if the Input/Output streams are using the same ByteBuffer. 2359130803Smarcel // If they sharing the same ByteBuffer we need to ensure only 2360130803Smarcel // one of those ByteBuffers are released to the ByteBufferPool. 2361130803Smarcel 2362130803Smarcel if (bbwi != null && getByteBuffer() != null) 2363130803Smarcel { 2364130803Smarcel MessageMediator messageMediator = parent.getMessageMediator(); 2365130803Smarcel if (messageMediator != null) 2366130803Smarcel { 2367130803Smarcel CDROutputObject outputObj = 2368130803Smarcel (CDROutputObject)messageMediator.getOutputObject(); 2369130803Smarcel if (outputObj != null) 2370130803Smarcel { 2371130803Smarcel if (outputObj.isSharing(getByteBuffer())) 2372130803Smarcel { 2373130803Smarcel // Set OutputStream's ByteBuffer and bbwi to null 2374130803Smarcel // so its ByteBuffer cannot be released to the pool 2375130803Smarcel outputObj.setByteBuffer(null); 2376130803Smarcel outputObj.setByteBufferWithInfo(null); 2377130803Smarcel } 2378130803Smarcel } 2379130803Smarcel } 2380130803Smarcel 2381130803Smarcel // release this stream's ByteBuffer to the pool 2382130803Smarcel ByteBufferPool byteBufferPool = orb.getByteBufferPool(); 2383130803Smarcel if (debug) 2384130803Smarcel { 2385130803Smarcel // print address of ByteBuffer being released 2386130803Smarcel int bbAddress = System.identityHashCode(bbwi.byteBuffer); 2387130803Smarcel StringBuffer sb = new StringBuffer(80); 2388130803Smarcel sb.append(".close - releasing ByteBuffer id ("); 2389130803Smarcel sb.append(bbAddress).append(") to ByteBufferPool."); 2390130803Smarcel String msg = sb.toString(); 2391130803Smarcel dprint(msg); 2392130803Smarcel } 2393130803Smarcel byteBufferPool.releaseByteBuffer(bbwi.byteBuffer); 2394130803Smarcel bbwi.byteBuffer = null; 2395130803Smarcel bbwi = null; 2396130803Smarcel } 2397130803Smarcel } 2398130803Smarcel} 2399130803Smarcel