1 /*
   2  * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.corba.se.impl.encoding;
  26 
  27 import java.io.Serializable;
  28 import java.io.ObjectInputStream;
  29 import java.io.ByteArrayInputStream;
  30 import java.io.IOException;
  31 import java.nio.ByteBuffer;
  32 import java.math.BigDecimal;
  33 import java.util.LinkedList;
  34 
  35 import com.sun.corba.se.spi.orb.ORB;
  36 import com.sun.corba.se.spi.ior.IOR;
  37 import com.sun.corba.se.spi.ior.IORFactories;
  38 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  39 import com.sun.corba.se.spi.logging.CORBALogDomains;
  40 import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
  41 import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
  42 import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
  43 
  44 import com.sun.corba.se.impl.util.Utility;
  45 import com.sun.corba.se.impl.orbutil.ORBUtility;
  46 import com.sun.corba.se.impl.corba.TypeCodeImpl;
  47 import com.sun.corba.se.impl.util.RepositoryId;
  48 import com.sun.corba.se.impl.orbutil.ORBConstants;
  49 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  50 import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  51 
  52 import org.omg.CORBA.Any;
  53 import org.omg.CORBA.TypeCode;
  54 import org.omg.CORBA.Principal;
  55 import org.omg.CORBA.portable.IDLEntity;
  56 
  57 /**
  58  * Implementation class that uses Java serialization for input streams.
  59  * This assumes a GIOP version 1.2 message format.
  60  *
  61  * This class uses a ByteArrayInputStream as the underlying buffer. The
  62  * first 16 bytes are directly read out of the underlying buffer. This allows
  63  * [GIOPHeader (12 bytes) + requestID (4 bytes)] to be read as bytes.
  64  * Subsequent write operations on this output stream object uses
  65  * ObjectInputStream class to read into the buffer. This allows unmarshaling
  66  * complex types and graphs using the ObjectInputStream implementation.
  67  *
  68  * Note, this class assumes a GIOP 1.2 style header. Further, the first
  69  * 12 bytes, that is, the GIOPHeader is read directly from the received
  70  * message, before this stream object is called. So, this class effectively
  71  * reads only the requestID (4 bytes) directly, and uses the
  72  * ObjectInputStream for further unmarshaling.
  73  *
  74  * @author Ram Jeyaraman
  75  */
  76 public class IDLJavaSerializationInputStream extends CDRInputStreamBase {
  77 
  78     private ORB orb;
  79     private int bufSize;
  80     private ByteBuffer buffer;
  81     private byte encodingVersion;
  82     private ObjectInputStream is;
  83     private _ByteArrayInputStream bis;
  84     private BufferManagerRead bufferManager;
  85 
  86     // [GIOPHeader(12) + requestID(4)] bytes
  87     private final int directReadLength = Message.GIOPMessageHeaderLength + 4;
  88 
  89     // Used for mark / reset operations.
  90     private boolean markOn;
  91     private int peekIndex, peekCount;
  92     private LinkedList markedItemQ = new LinkedList();
  93 
  94     protected ORBUtilSystemException wrapper;
  95 
  96     class _ByteArrayInputStream extends ByteArrayInputStream {
  97 
  98         _ByteArrayInputStream(byte[] buf) {
  99             super(buf);
 100         }
 101 
 102         int getPosition() {
 103             return this.pos;
 104         }
 105 
 106         void setPosition(int value) {
 107             if (value < 0 || value > count) {
 108                 throw new IndexOutOfBoundsException();
 109             }
 110             this.pos = value;
 111         }
 112     }
 113 
 114     class MarshalObjectInputStream extends ObjectInputStream {
 115 
 116         ORB orb;
 117 
 118         MarshalObjectInputStream(java.io.InputStream out, ORB orb)
 119                 throws IOException {
 120 
 121             super(out);
 122             this.orb = orb;
 123 
 124             java.security.AccessController.doPrivileged(
 125                 new java.security.PrivilegedAction() {
 126                     public Object run() {
 127                         // needs SerializablePermission("enableSubstitution")
 128                         enableResolveObject(true);
 129                         return null;
 130                     }
 131                 }
 132             );
 133         }
 134 
 135         /**
 136          * Connect the Stub to the ORB.
 137          */
 138         protected final Object resolveObject(Object obj) throws IOException {
 139             try {
 140                 if (StubAdapter.isStub(obj)) {
 141                     StubAdapter.connect(obj, orb);
 142                 }
 143             } catch (java.rmi.RemoteException re) {
 144                 IOException ie = new IOException("resolveObject failed");
 145                 ie.initCause(re);
 146                 throw ie;
 147             }
 148             return obj;
 149         }
 150     }
 151 
 152     public IDLJavaSerializationInputStream(byte encodingVersion) {
 153         super();
 154         this.encodingVersion = encodingVersion;
 155     }
 156 
 157     public void init(org.omg.CORBA.ORB orb,
 158                      ByteBuffer byteBuffer,
 159                      int bufSize,
 160                      boolean littleEndian,
 161                      BufferManagerRead bufferManager) {
 162         this.orb = (ORB) orb;
 163         this.bufSize = bufSize;
 164         this.bufferManager = bufferManager;
 165         buffer = byteBuffer;
 166         wrapper =
 167             ORBUtilSystemException.get((ORB)orb, CORBALogDomains.RPC_ENCODING);
 168 
 169         byte[] buf;
 170         if (buffer.hasArray()) {
 171             buf = buffer.array();
 172         } else {
 173             buf = new byte[bufSize];
 174             buffer.get(buf);
 175         }
 176         // Note: at this point, the buffer position is zero. The setIndex()
 177         // method call can be used to set a desired read index.
 178         bis = new _ByteArrayInputStream(buf);
 179     }
 180 
 181     // Called from read_octet or read_long or read_ulong method.
 182     private void initObjectInputStream() {
 183         //System.out.print(" is ");
 184         if (is != null) {
 185             throw wrapper.javaStreamInitFailed();
 186         }
 187         try {
 188             is = new MarshalObjectInputStream(bis, orb);
 189         } catch (Exception e) {
 190             throw wrapper.javaStreamInitFailed(e);
 191         }
 192     }
 193 
 194     // org.omg.CORBA.portable.InputStream
 195 
 196     // Primitive types.
 197 
 198     public boolean read_boolean() {
 199         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 200             return ((Boolean)markedItemQ.removeFirst()).booleanValue();
 201         }
 202         if (markOn && !(markedItemQ.isEmpty()) &&
 203                 (peekIndex < peekCount)) { // peek
 204             return ((Boolean)markedItemQ.get(peekIndex++)).booleanValue();
 205         }
 206         try {
 207             boolean value = is.readBoolean();
 208             if (markOn) { // enqueue
 209                 markedItemQ.addLast(Boolean.valueOf(value));
 210             }
 211             return value;
 212         } catch (Exception e) {
 213             throw wrapper.javaSerializationException(e, "read_boolean");
 214         }
 215     }
 216 
 217     public char read_char() {
 218         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 219             return ((Character)markedItemQ.removeFirst()).charValue();
 220         }
 221         if (markOn && !(markedItemQ.isEmpty()) &&
 222                 (peekIndex < peekCount)) { // peek
 223             return ((Character)markedItemQ.get(peekIndex++)).charValue();
 224         }
 225         try {
 226             char value = is.readChar();
 227             if (markOn) { // enqueue
 228                 markedItemQ.addLast(new Character(value));
 229             }
 230             return value;
 231         } catch (Exception e) {
 232             throw wrapper.javaSerializationException(e, "read_char");
 233         }
 234     }
 235 
 236     public char read_wchar() {
 237         return this.read_char();
 238     }
 239 
 240     public byte read_octet() {
 241 
 242         // check if size < [ GIOPHeader(12) + requestID(4)] bytes
 243         if (bis.getPosition() < directReadLength) {
 244             byte b = (byte) bis.read();
 245             if (bis.getPosition() == directReadLength) {
 246                 initObjectInputStream();
 247             }
 248             return b;
 249         }
 250 
 251         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 252             return ((Byte)markedItemQ.removeFirst()).byteValue();
 253         }
 254 
 255         if (markOn && !(markedItemQ.isEmpty()) &&
 256                 (peekIndex < peekCount)) { // peek
 257             return ((Byte)markedItemQ.get(peekIndex++)).byteValue();
 258         }
 259 
 260         try {
 261             byte value = is.readByte();
 262             if (markOn) { // enqueue
 263                 //markedItemQ.addLast(Byte.valueOf(value)); // only in JDK 1.5
 264                 markedItemQ.addLast(new Byte(value));
 265             }
 266             return value;
 267         } catch (Exception e) {
 268             throw wrapper.javaSerializationException(e, "read_octet");
 269         }
 270     }
 271 
 272     public short read_short() {
 273         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 274             return ((Short)markedItemQ.removeFirst()).shortValue();
 275         }
 276         if (markOn && !(markedItemQ.isEmpty()) &&
 277                 (peekIndex < peekCount)) { // peek
 278             return ((Short)markedItemQ.get(peekIndex++)).shortValue();
 279         }
 280 
 281         try {
 282             short value = is.readShort();
 283             if (markOn) { // enqueue
 284                 markedItemQ.addLast(new Short(value));
 285             }
 286             return value;
 287         } catch (Exception e) {
 288             throw wrapper.javaSerializationException(e, "read_short");
 289         }
 290     }
 291 
 292     public short read_ushort() {
 293         return this.read_short();
 294     }
 295 
 296     public int read_long() {
 297 
 298         // check if size < [ GIOPHeader(12) + requestID(4)] bytes
 299         if (bis.getPosition() < directReadLength) {
 300 
 301             // Use big endian (network byte order). This is fixed.
 302             // Both the writer and reader use the same byte order.
 303             int b1 = (bis.read() << 24) & 0xFF000000;
 304             int b2 = (bis.read() << 16) & 0x00FF0000;
 305             int b3 = (bis.read() << 8)  & 0x0000FF00;
 306             int b4 = (bis.read() << 0)  & 0x000000FF;
 307 
 308             if (bis.getPosition() == directReadLength) {
 309                 initObjectInputStream();
 310             } else if (bis.getPosition() > directReadLength) {
 311                 // Cannot happen. All direct reads are contained
 312                 // within the first 16 bytes.
 313                 wrapper.javaSerializationException("read_long");
 314             }
 315 
 316             return (b1 | b2 | b3 | b4);
 317         }
 318 
 319         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 320             return ((Integer)markedItemQ.removeFirst()).intValue();
 321         }
 322 
 323         if (markOn && !(markedItemQ.isEmpty()) &&
 324                 (peekIndex < peekCount)) { // peek
 325             return ((Integer)markedItemQ.get(peekIndex++)).intValue();
 326         }
 327 
 328         try {
 329             int value = is.readInt();
 330             if (markOn) { // enqueue
 331                 markedItemQ.addLast(new Integer(value));
 332             }
 333             return value;
 334         } catch (Exception e) {
 335             throw wrapper.javaSerializationException(e, "read_long");
 336         }
 337     }
 338 
 339     public int read_ulong() {
 340         return this.read_long();
 341     }
 342 
 343     public long read_longlong() {
 344         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 345             return ((Long)markedItemQ.removeFirst()).longValue();
 346         }
 347         if (markOn && !(markedItemQ.isEmpty()) &&
 348                 (peekIndex < peekCount)) { // peek
 349             return ((Long)markedItemQ.get(peekIndex++)).longValue();
 350         }
 351 
 352         try {
 353             long value = is.readLong();
 354             if (markOn) { // enqueue
 355                 markedItemQ.addLast(new Long(value));
 356             }
 357             return value;
 358         } catch (Exception e) {
 359             throw wrapper.javaSerializationException(e, "read_longlong");
 360         }
 361     }
 362 
 363     public long read_ulonglong() {
 364         return read_longlong();
 365     }
 366 
 367     public float read_float() {
 368         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 369             return ((Float)markedItemQ.removeFirst()).floatValue();
 370         }
 371         if (markOn && !(markedItemQ.isEmpty()) &&
 372                 (peekIndex < peekCount)) { // peek
 373             return ((Float)markedItemQ.get(peekIndex++)).floatValue();
 374         }
 375 
 376         try {
 377             float value = is.readFloat();
 378             if (markOn) { // enqueue
 379                 markedItemQ.addLast(new Float(value));
 380             }
 381             return value;
 382         } catch (Exception e) {
 383             throw wrapper.javaSerializationException(e, "read_float");
 384         }
 385     }
 386 
 387     public double read_double() {
 388         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 389             return ((Double)markedItemQ.removeFirst()).doubleValue();
 390         }
 391         if (markOn && !(markedItemQ.isEmpty()) &&
 392                 (peekIndex < peekCount)) { // peek
 393             return ((Double)markedItemQ.get(peekIndex++)).doubleValue();
 394         }
 395 
 396         try {
 397             double value = is.readDouble();
 398             if (markOn) { // enqueue
 399                 markedItemQ.addLast(new Double(value));
 400             }
 401             return value;
 402         } catch (Exception e) {
 403             throw wrapper.javaSerializationException(e, "read_double");
 404         }
 405     }
 406 
 407     // String types.
 408 
 409     public String read_string() {
 410         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 411             return (String) markedItemQ.removeFirst();
 412         }
 413         if (markOn && !(markedItemQ.isEmpty()) &&
 414             (peekIndex < peekCount)) { // peek
 415             return (String) markedItemQ.get(peekIndex++);
 416         }
 417         try {
 418             String value = is.readUTF();
 419             if (markOn) { // enqueue
 420                 markedItemQ.addLast(value);
 421             }
 422             return value;
 423         } catch (Exception e) {
 424             throw wrapper.javaSerializationException(e, "read_string");
 425         }
 426     }
 427 
 428     public String read_wstring() {
 429         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 430             return (String) markedItemQ.removeFirst();
 431         }
 432         if (markOn && !(markedItemQ.isEmpty()) &&
 433                 (peekIndex < peekCount)) { // peek
 434             return (String) markedItemQ.get(peekIndex++);
 435         }
 436         try {
 437             String value = (String) is.readObject();
 438             if (markOn) { // enqueue
 439                 markedItemQ.addLast(value);
 440             }
 441             return value;
 442         } catch (Exception e) {
 443             throw wrapper.javaSerializationException(e, "read_wstring");
 444         }
 445     }
 446 
 447     // Array types.
 448 
 449     public void read_boolean_array(boolean[] value, int offset, int length){
 450         for(int i = 0; i < length; i++) {
 451             value[i+offset] = read_boolean();
 452         }
 453     }
 454 
 455     public void read_char_array(char[] value, int offset, int length) {
 456         for(int i=0; i < length; i++) {
 457             value[i+offset] = read_char();
 458         }
 459     }
 460 
 461     public void read_wchar_array(char[] value, int offset, int length) {
 462         read_char_array(value, offset, length);
 463     }
 464 
 465     public void read_octet_array(byte[] value, int offset, int length) {
 466         for(int i=0; i < length; i++) {
 467             value[i+offset] = read_octet();
 468         }
 469         /* // Cannot use this efficient read due to mark/reset support.
 470         try {
 471             while (length > 0) {
 472                 int n = is.read(value, offset, length);
 473                 offset += n;
 474                 length -= n;
 475             }
 476         } catch (Exception e) {
 477             throw wrapper.javaSerializationException(e, "read_octet_array");
 478         }
 479         */
 480     }
 481 
 482     public void read_short_array(short[] value, int offset, int length) {
 483         for(int i=0; i < length; i++) {
 484             value[i+offset] = read_short();
 485         }
 486     }
 487 
 488     public void read_ushort_array(short[] value, int offset, int length) {
 489         read_short_array(value, offset, length);
 490     }
 491 
 492     public void read_long_array(int[] value, int offset, int length) {
 493         for(int i=0; i < length; i++) {
 494             value[i+offset] = read_long();
 495         }
 496     }
 497 
 498     public void read_ulong_array(int[] value, int offset, int length) {
 499         read_long_array(value, offset, length);
 500     }
 501 
 502     public void read_longlong_array(long[] value, int offset, int length) {
 503         for(int i=0; i < length; i++) {
 504             value[i+offset] = read_longlong();
 505         }
 506     }
 507 
 508     public void read_ulonglong_array(long[] value, int offset, int length) {
 509         read_longlong_array(value, offset, length);
 510     }
 511 
 512     public void read_float_array(float[] value, int offset, int length) {
 513         for(int i=0; i < length; i++) {
 514             value[i+offset] = read_float();
 515         }
 516     }
 517 
 518     public void read_double_array(double[] value, int offset, int length) {
 519         for(int i=0; i < length; i++) {
 520             value[i+offset] = read_double();
 521         }
 522     }
 523 
 524     // Complex types.
 525 
 526     public org.omg.CORBA.Object read_Object() {
 527         return read_Object(null);
 528     }
 529 
 530     public TypeCode read_TypeCode() {
 531         TypeCodeImpl tc = new TypeCodeImpl(orb);
 532         tc.read_value(parent);
 533         return tc;
 534     }
 535 
 536     public Any read_any() {
 537 
 538         Any any = orb.create_any();
 539         TypeCodeImpl tc = new TypeCodeImpl(orb);
 540 
 541         // read off the typecode
 542 
 543         // REVISIT We could avoid this try-catch if we could peek the typecode
 544         // kind off this stream and see if it is a tk_value.
 545         // Looking at the code we know that for tk_value the Any.read_value()
 546         // below ignores the tc argument anyway (except for the kind field).
 547         // But still we would need to make sure that the whole typecode,
 548         // including encapsulations, is read off.
 549         try {
 550             tc.read_value(parent);
 551         } catch (org.omg.CORBA.MARSHAL ex) {
 552             if (tc.kind().value() != org.omg.CORBA.TCKind._tk_value) {
 553                 throw ex;
 554             }
 555             // We can be sure that the whole typecode encapsulation has been
 556             // read off.
 557             ex.printStackTrace();
 558         }
 559 
 560         // read off the value of the any.
 561         any.read_value(parent, tc);
 562 
 563         return any;
 564     }
 565 
 566     public Principal read_Principal() {
 567         // We don't need an implementation for this method, since principal
 568         // is absent in GIOP version 1.2 or above.
 569         int len = read_long();
 570         byte[] pvalue = new byte[len];
 571         read_octet_array(pvalue,0,len);
 572         Principal p = new com.sun.corba.se.impl.corba.PrincipalImpl();
 573         p.name(pvalue);
 574         return p;
 575     }
 576 
 577     public BigDecimal read_fixed() {
 578         return new BigDecimal(read_fixed_buffer().toString());
 579     }
 580 
 581     // Each octet contains (up to) two decimal digits. If the fixed type has
 582     // an odd number of decimal digits, then the representation
 583     // begins with the first (most significant) digit.
 584     // Otherwise, this first half-octet is all zero, and the first digit
 585     // is in the second half-octet.
 586     // The sign configuration, in the last half-octet of the representation,
 587     // is 0xD for negative numbers and 0xC for positive and zero values.
 588     private StringBuffer read_fixed_buffer() {
 589         StringBuffer buffer = new StringBuffer(64);
 590         byte doubleDigit;
 591         int firstDigit;
 592         int secondDigit;
 593         boolean wroteFirstDigit = false;
 594         boolean more = true;
 595         while (more) {
 596             doubleDigit = read_octet();
 597             firstDigit = (int)((doubleDigit & 0xf0) >> 4);
 598             secondDigit = (int)(doubleDigit & 0x0f);
 599             if (wroteFirstDigit || firstDigit != 0) {
 600                 buffer.append(Character.forDigit(firstDigit, 10));
 601                 wroteFirstDigit = true;
 602             }
 603             if (secondDigit == 12) {
 604                 // positive number or zero
 605                 if ( ! wroteFirstDigit) {
 606                     // zero
 607                     return new StringBuffer("0.0");
 608                 } else {
 609                     // positive number
 610                     // done
 611                 }
 612                 more = false;
 613             } else if (secondDigit == 13) {
 614                 // negative number
 615                 buffer.insert(0, '-');
 616                 more = false;
 617             } else {
 618                 buffer.append(Character.forDigit(secondDigit, 10));
 619                 wroteFirstDigit = true;
 620             }
 621         }
 622         return buffer;
 623     }
 624 
 625     public org.omg.CORBA.Object read_Object(java.lang.Class clz) {
 626 
 627         // In any case, we must first read the IOR.
 628         IOR ior = IORFactories.makeIOR(parent) ;
 629         if (ior.isNil()) {
 630             return null;
 631         }
 632 
 633         PresentationManager.StubFactoryFactory sff =
 634             ORB.getStubFactoryFactory();
 635         String codeBase = ior.getProfile().getCodebase();
 636         PresentationManager.StubFactory stubFactory = null;
 637 
 638         if (clz == null) {
 639             RepositoryId rid = RepositoryId.cache.getId(ior.getTypeId() );
 640             String className = rid.getClassName();
 641             boolean isIDLInterface = rid.isIDLType();
 642 
 643             if (className == null || className.equals( "" )) {
 644                 stubFactory = null;
 645             } else {
 646                 try {
 647                     stubFactory = sff.createStubFactory(className,
 648                         isIDLInterface, codeBase, (Class) null,
 649                         (ClassLoader) null);
 650                 } catch (Exception exc) {
 651                     // Could not create stubFactory, so use null.
 652                     // XXX stubFactory handling is still too complex:
 653                     // Can we resolve the stubFactory question once in
 654                     // a single place?
 655                     stubFactory = null ;
 656                 }
 657             }
 658         } else if (StubAdapter.isStubClass(clz)) {
 659             stubFactory = PresentationDefaults.makeStaticStubFactory(clz);
 660         } else {
 661             // clz is an interface class
 662             boolean isIDL = IDLEntity.class.isAssignableFrom(clz);
 663 
 664             stubFactory = sff.createStubFactory(
 665                  clz.getName(), isIDL, codeBase, clz, clz.getClassLoader());
 666         }
 667 
 668         return CDRInputStream_1_0.internalIORToObject(ior, stubFactory, orb);
 669     }
 670 
 671     public org.omg.CORBA.ORB orb() {
 672         return this.orb;
 673     }
 674 
 675     // org.omg.CORBA_2_3.portable.InputStream
 676 
 677     public java.io.Serializable read_value() {
 678         if (!markOn && !(markedItemQ.isEmpty())) { // dequeue
 679             return (Serializable) markedItemQ.removeFirst();
 680         }
 681         if (markOn && !(markedItemQ.isEmpty()) &&
 682                 (peekIndex < peekCount)) { // peek
 683             return (Serializable) markedItemQ.get(peekIndex++);
 684         }
 685         try {
 686             Serializable value = (java.io.Serializable) is.readObject();
 687             if (markOn) { // enqueue
 688                 markedItemQ.addLast(value);
 689             }
 690             return value;
 691         } catch (Exception e) {
 692             throw wrapper.javaSerializationException(e, "read_value");
 693         }
 694     }
 695 
 696     public java.io.Serializable read_value(java.lang.Class clz) {
 697         return read_value();
 698     }
 699 
 700     public java.io.Serializable read_value(
 701             org.omg.CORBA.portable.BoxedValueHelper factory) {
 702         return read_value();
 703     }
 704 
 705     public java.io.Serializable read_value(java.lang.String rep_id) {
 706         return read_value();
 707     }
 708 
 709     public java.io.Serializable read_value(java.io.Serializable value) {
 710         return read_value();
 711     }
 712 
 713     public java.lang.Object read_abstract_interface() {
 714         return read_abstract_interface(null);
 715     }
 716 
 717     public java.lang.Object read_abstract_interface(java.lang.Class clz) {
 718         boolean isObject = read_boolean();
 719         if (isObject) {
 720             return read_Object(clz);
 721         } else {
 722             return read_value();
 723         }
 724     }
 725 
 726     // com.sun.corba.se.impl.encoding.MarshalInputStream
 727     public void consumeEndian() {
 728         throw wrapper.giopVersionError();
 729     }
 730 
 731     public int getPosition() {
 732         try {
 733             return bis.getPosition();
 734         } catch (Exception e) {
 735             throw wrapper.javaSerializationException(e, "getPosition");
 736         }
 737     }
 738 
 739     // org.omg.CORBA.DataInputStream
 740     public java.lang.Object read_Abstract() {
 741         return read_abstract_interface();
 742     }
 743 
 744     public java.io.Serializable read_Value() {
 745         return read_value();
 746     }
 747 
 748     public void read_any_array (org.omg.CORBA.AnySeqHolder seq,
 749                                 int offset, int length) {
 750         read_any_array(seq.value, offset, length);
 751     }
 752 
 753     private final void read_any_array(org.omg.CORBA.Any[] value,
 754                                      int offset, int length) {
 755         for(int i=0; i < length; i++) {
 756             value[i+offset] = read_any();
 757         }
 758     }
 759 
 760     public void read_boolean_array (org.omg.CORBA.BooleanSeqHolder seq,
 761                                     int offset, int length){
 762         read_boolean_array(seq.value, offset, length);
 763     }
 764 
 765     public void read_char_array (org.omg.CORBA.CharSeqHolder seq,
 766                                  int offset, int length){
 767         read_char_array(seq.value, offset, length);
 768     }
 769 
 770     public void read_wchar_array (org.omg.CORBA.WCharSeqHolder seq,
 771                                   int offset, int length){
 772         read_wchar_array(seq.value, offset, length);
 773     }
 774 
 775     public void read_octet_array (org.omg.CORBA.OctetSeqHolder seq,
 776                                   int offset, int length){
 777         read_octet_array(seq.value, offset, length);
 778     }
 779 
 780     public void read_short_array (org.omg.CORBA.ShortSeqHolder seq,
 781                                   int offset, int length){
 782         read_short_array(seq.value, offset, length);
 783     }
 784 
 785     public void read_ushort_array (org.omg.CORBA.UShortSeqHolder seq,
 786                                    int offset, int length){
 787         read_ushort_array(seq.value, offset, length);
 788     }
 789 
 790     public void read_long_array (org.omg.CORBA.LongSeqHolder seq,
 791                                  int offset, int length){
 792         read_long_array(seq.value, offset, length);
 793     }
 794 
 795     public void read_ulong_array (org.omg.CORBA.ULongSeqHolder seq,
 796                                   int offset, int length){
 797         read_ulong_array(seq.value, offset, length);
 798     }
 799 
 800     public void read_ulonglong_array (org.omg.CORBA.ULongLongSeqHolder seq,
 801                                       int offset, int length){
 802         read_ulonglong_array(seq.value, offset, length);
 803     }
 804 
 805     public void read_longlong_array (org.omg.CORBA.LongLongSeqHolder seq,
 806                                      int offset, int length){
 807         read_longlong_array(seq.value, offset, length);
 808     }
 809 
 810     public void read_float_array (org.omg.CORBA.FloatSeqHolder seq,
 811                                   int offset, int length){
 812         read_float_array(seq.value, offset, length);
 813     }
 814 
 815     public void read_double_array (org.omg.CORBA.DoubleSeqHolder seq,
 816                                    int offset, int length){
 817         read_double_array(seq.value, offset, length);
 818     }
 819 
 820     // org.omg.CORBA.portable.ValueBase
 821 
 822     public String[] _truncatable_ids() {
 823         throw wrapper.giopVersionError();
 824     }
 825 
 826     // java.io.InputStream
 827     // REVISIT - should we make these throw UnsupportedOperationExceptions?
 828     // Right now, they'll go up to the java.io versions!
 829 
 830     //     public int read(byte b[]) throws IOException;
 831     //     public int read(byte b[], int off, int len) throws IOException
 832     //     public long skip(long n) throws IOException;
 833     //     public int available() throws IOException;
 834     //     public void close() throws IOException;
 835 
 836     public void mark(int readLimit) {
 837         // Nested mark disallowed.
 838         // Further, mark is not supported until first 16 bytes are read.
 839         if (markOn || is == null) {
 840             throw wrapper.javaSerializationException("mark");
 841         }
 842         markOn = true;
 843         if (!(markedItemQ.isEmpty())) {
 844             peekIndex = 0;
 845             peekCount = markedItemQ.size();
 846         }
 847         /*
 848         // Note: only ByteArrayInputStream supports mark/reset.
 849         if (is == null || is.markSupported() == false) {
 850             throw wrapper.javaSerializationException("mark");
 851         }
 852         is.mark(readLimit);
 853         */
 854     }
 855 
 856     public void reset() {
 857         markOn = false;
 858         peekIndex = 0;
 859         peekCount = 0;
 860         /*
 861         // Note: only ByteArrayInputStream supports mark/reset.
 862         if (is == null || is.markSupported() == false) {
 863             throw wrapper.javaSerializationException("mark");
 864         }
 865         try {
 866             is.reset();
 867         } catch (Exception e) {
 868             throw wrapper.javaSerializationException(e, "reset");
 869         }
 870         */
 871     }
 872 
 873     // This should return false so that outside users (people using the JDK)
 874     // don't have any guarantees that mark/reset will work in their
 875     // custom marshaling code.  This is necessary since they could do things
 876     // like expect obj1a == obj1b in the following code:
 877     //
 878     // is.mark(10000);
 879     // Object obj1a = is.readObject();
 880     // is.reset();
 881     // Object obj1b = is.readObject();
 882     //
 883     public boolean markSupported() {
 884         return true;
 885     }
 886 
 887     // Needed by AnyImpl and ServiceContexts
 888     public CDRInputStreamBase dup() {
 889 
 890         CDRInputStreamBase result = null ;
 891 
 892         try {
 893             result = (CDRInputStreamBase) this.getClass().newInstance();
 894         } catch (Exception e) {
 895             throw wrapper.couldNotDuplicateCdrInputStream(e);
 896         }
 897 
 898         result.init(this.orb, this.buffer, this.bufSize, false, null);
 899 
 900         // Set the buffer position.
 901         ((IDLJavaSerializationInputStream)result).skipBytes(getPosition());
 902 
 903         // Set mark related data.
 904         ((IDLJavaSerializationInputStream)result).
 905             setMarkData(markOn, peekIndex, peekCount,
 906                         (LinkedList) markedItemQ.clone());
 907 
 908         return result;
 909     }
 910 
 911     // Used exclusively by the dup() method.
 912     void skipBytes(int len) {
 913         try {
 914             is.skipBytes(len);
 915         } catch (Exception e) {
 916             throw wrapper.javaSerializationException(e, "skipBytes");
 917         }
 918     }
 919 
 920     // Used exclusively by the dup() method.
 921     void setMarkData(boolean markOn, int peekIndex, int peekCount,
 922                      LinkedList markedItemQ) {
 923         this.markOn = markOn;
 924         this.peekIndex = peekIndex;
 925         this.peekCount = peekCount;
 926         this.markedItemQ = markedItemQ;
 927     }
 928 
 929     // Needed by TCUtility
 930     public java.math.BigDecimal read_fixed(short digits, short scale) {
 931         // digits isn't really needed here
 932         StringBuffer buffer = read_fixed_buffer();
 933         if (digits != buffer.length())
 934             throw wrapper.badFixed( new Integer(digits),
 935                 new Integer(buffer.length()) ) ;
 936         buffer.insert(digits - scale, '.');
 937         return new BigDecimal(buffer.toString());
 938     }
 939 
 940     // Needed by TypeCodeImpl
 941     public boolean isLittleEndian() {
 942         throw wrapper.giopVersionError();
 943     }
 944 
 945     // Needed by request and reply messages for GIOP versions >= 1.2 only.
 946     void setHeaderPadding(boolean headerPadding) {
 947         // no-op. We don't care about body alignment while using
 948         // Java serialization. What the GIOP spec states does not apply here.
 949     }
 950 
 951     // Needed by IIOPInputStream and other subclasses
 952 
 953     public ByteBuffer getByteBuffer() {
 954         throw wrapper.giopVersionError();
 955     }
 956 
 957     public void setByteBuffer(ByteBuffer byteBuffer) {
 958         throw wrapper.giopVersionError();
 959     }
 960 
 961     public void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
 962         throw wrapper.giopVersionError();
 963     }
 964 
 965     public int getBufferLength() {
 966         return bufSize;
 967     }
 968 
 969     public void setBufferLength(int value) {
 970         // this is redundant, since buffer size was already specified
 971         // as part of the init call. So, ignore.
 972     }
 973 
 974     public int getIndex() {
 975         return bis.getPosition();
 976     }
 977 
 978     public void setIndex(int value) {
 979         try {
 980             bis.setPosition(value);
 981         } catch (IndexOutOfBoundsException e) {
 982             throw wrapper.javaSerializationException(e, "setIndex");
 983         }
 984     }
 985 
 986     public void orb(org.omg.CORBA.ORB orb) {
 987         this.orb = (ORB) orb;
 988     }
 989 
 990     public BufferManagerRead getBufferManager() {
 991         return bufferManager;
 992     }
 993 
 994     public GIOPVersion getGIOPVersion() {
 995         return GIOPVersion.V1_2;
 996     }
 997 
 998     com.sun.org.omg.SendingContext.CodeBase getCodeBase() {
 999         return parent.getCodeBase();
1000     }
1001 
1002     void printBuffer() {
1003         byte[] buf = this.buffer.array();
1004 
1005         System.out.println("+++++++ Input Buffer ++++++++");
1006         System.out.println();
1007         System.out.println("Current position: " + getPosition());
1008         System.out.println("Total length : " + this.bufSize);
1009         System.out.println();
1010 
1011         char[] charBuf = new char[16];
1012 
1013         try {
1014 
1015             for (int i = 0; i < buf.length; i += 16) {
1016 
1017                 int j = 0;
1018 
1019                 // For every 16 bytes, there is one line
1020                 // of output.  First, the hex output of
1021                 // the 16 bytes with each byte separated
1022                 // by a space.
1023                 while (j < 16 && j + i < buf.length) {
1024                     int k = buf[i + j];
1025                     if (k < 0)
1026                         k = 256 + k;
1027                     String hex = Integer.toHexString(k);
1028                     if (hex.length() == 1)
1029                         hex = "0" + hex;
1030                     System.out.print(hex + " ");
1031                     j++;
1032                 }
1033 
1034                 // Add any extra spaces to align the
1035                 // text column in case we didn't end
1036                 // at 16
1037                 while (j < 16) {
1038                     System.out.print("   ");
1039                     j++;
1040                 }
1041 
1042                 // Now output the ASCII equivalents.  Non-ASCII
1043                 // characters are shown as periods.
1044                 int x = 0;
1045 
1046                 while (x < 16 && x + i < buf.length) {
1047                     if (ORBUtility.isPrintable((char)buf[i + x])) {
1048                         charBuf[x] = (char) buf[i + x];
1049                     } else {
1050                         charBuf[x] = '.';
1051                     }
1052                     x++;
1053                 }
1054                 System.out.println(new String(charBuf, 0, x));
1055             }
1056         } catch (Throwable t) {
1057             t.printStackTrace();
1058         }
1059         System.out.println("++++++++++++++++++++++++++++++");
1060     }
1061 
1062     void alignOnBoundary(int octetBoundary) {
1063         throw wrapper.giopVersionError();
1064     }
1065 
1066     void performORBVersionSpecificInit() {
1067         // No-op.
1068     }
1069 
1070     public void resetCodeSetConverters() {
1071         // No-op.
1072     }
1073 
1074     // ValueInputStream -------------------------
1075 
1076     public void start_value() {
1077         throw wrapper.giopVersionError();
1078     }
1079 
1080     public void end_value() {
1081         throw wrapper.giopVersionError();
1082     }
1083 }