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 }