1 19 package gcc.rmi.iiop; 20 21 import gcc.*; 22 import gcc.util.*; 23 import java.io.*; 24 import java.lang.reflect.*; 25 import java.util.*; 26 import org.omg.CORBA.TCKind; 27 28 public class ObjectInputStream extends java.io.ObjectInputStream 29 { 30 public static ObjectInputStream getInstance() 31 { 32 return getInstance(CdrInputStream.getInstance()); 33 } 34 35 public static ObjectInputStream getInstance(gcc.rmi.iiop.CdrInputStream cdrInput) 36 { 37 ObjectInputStream input = null; 38 try 39 { 40 input = new ObjectInputStream(); 41 } 42 catch( Exception ex ) 43 { 44 throw new SystemException( ex ); 45 } 46 47 input.init(cdrInput); 48 return input; 49 } 50 51 public static ObjectInputStream getPooledInstance() 52 { 53 ObjectInputStream input = null; if (input == null) 55 { 56 input = getInstance(); 57 } 58 return input; 59 } 60 61 65 protected static class StreamState 66 { 67 ValueType type; 68 Object value; 69 int offset; 70 71 StreamState(ValueType type, Object value, int offset) 72 { 73 this.type = type; 74 this.value = value; 75 this.offset = offset; 76 } 77 } 78 79 83 public static final int MAXIMUM_BLOCK_LENGTH = 0x7fffff00; 84 85 public CdrInputStream _cdrInput; 86 87 public Object[] thisAsObjectArray; 88 89 93 95 private int _blockLength = MAXIMUM_BLOCK_LENGTH; 96 97 private int _endLevel = 0; 98 99 private HashMap _indirection; 100 101 private boolean _isChunked = false; 102 103 private ArrayList _stack; 104 105 109 public ObjectInputStream() throws IOException 110 { 111 } 112 113 public void $reset() 114 { 115 _cdrInput.reset(); 116 if (_indirection != null) 117 { 118 _indirection.clear(); 119 } 120 if (_stack != null) 121 { 122 _stack.clear(); 123 } 124 _blockLength = MAXIMUM_BLOCK_LENGTH; 125 _endLevel = 0; 126 _isChunked = false; 127 } 128 129 public void recycle() 130 { 131 $reset(); 132 } 134 135 137 public boolean readBoolean() 138 { 139 return _cdrInput.read_boolean(); 140 } 141 142 public char readChar() 143 { 144 return _cdrInput.read_wchar(); 145 } 146 147 public byte readByte() 148 { 149 return _cdrInput.read_octet(); 150 } 151 152 public short readShort() 153 { 154 return _cdrInput.read_short(); 155 } 156 157 public int readInt() 158 { 159 return _cdrInput.read_long(); 160 } 161 162 public long readLong() 163 { 164 return _cdrInput.read_longlong(); 165 } 166 167 public float readFloat() 168 { 169 return _cdrInput.read_float(); 170 } 171 172 public double readDouble() 173 { 174 return _cdrInput.read_double(); 175 } 176 177 public Object readObjectOverride() 178 { 179 return readObject(ValueType.OBJECT_VALUE_TYPE, false); 180 } 181 182 public void defaultReadObject() throws IOException, ClassNotFoundException, NotActiveException 183 { 184 StreamState state = top(); 185 readDeclaredFields(state.type, state.value); 186 } 187 188 192 public Exception readException(ValueType type) 193 { 194 return (Exception)readObject(type, false); 195 } 196 197 public Object readObject(ValueType type) 198 { 199 return readObject(type, false); 200 } 201 202 206 protected void init(gcc.rmi.iiop.CdrInputStream cdrInput) 207 { 208 _cdrInput = cdrInput; 209 thisAsObjectArray = new Object[] { this }; 210 } 211 212 protected void putIndirection(Integer key, Object value) 213 { 214 if (_indirection == null) 215 { 216 _indirection = new HashMap(); 217 } 218 _indirection.put(key, value); 219 } 220 221 protected Object readObject(ValueType declaredType, boolean calledByCustomSerialization) 222 { 223 org.omg.CORBA.TypeCode tc = null; 224 225 int tag = _cdrInput.read_ulong(); 226 int saveOffset = _cdrInput._offset - 4; 227 Object value; 228 229 if (tag == ValueType.INDIRECTION_TAG) 230 { 231 saveOffset = _cdrInput._offset; 233 int offset = _cdrInput.read_long(); 234 Integer key = IntegerCache.get(saveOffset + offset); 235 if (_indirection != null) 236 { 237 value = _indirection.get(key); 238 if (value != null) 239 { 240 return value; 241 } 242 } 243 throw new org.omg.CORBA.MARSHAL("invalid indirection offset = " + offset); 244 } 245 else 246 { 247 _cdrInput._offset = saveOffset; 248 } 249 250 if (calledByCustomSerialization) 251 { 252 boolean isObjectRef = _cdrInput.read_boolean(); 253 if (isObjectRef) 254 { 255 org.omg.CORBA.Object ref = _cdrInput.read_Object(); 256 endBlock(); 257 if (_blockLength == MAXIMUM_BLOCK_LENGTH) 258 { 259 startBlock(); 260 } 261 return ref; 262 } 263 else 264 { 265 _cdrInput._offset = saveOffset; 266 } 267 } 268 else if (declaredType.isAnyOrObjectRefOrAbstractInterface) 269 { 270 boolean isObjectRef = false; 271 if (declaredType.isObjectRef) 272 { 273 return _cdrInput.read_Object(); 274 } 275 else if (declaredType.isAny) 276 { 277 tc = _cdrInput.read_TypeCode(); 278 int kind = tc.kind().value(); 279 if(kind == TCKind._tk_null) 280 { 281 return null; 282 } 283 if(kind == TCKind._tk_objref) 284 { 285 isObjectRef = true; 286 } 287 else if(kind == TCKind._tk_abstract_interface) 288 { 289 isObjectRef = _cdrInput.read_boolean(); 290 } 291 if(isObjectRef) 292 { 293 saveOffset = _cdrInput._offset; 294 int checkValue = _cdrInput.read_ulong(); 295 if(checkValue == 0) 296 { 297 return null; 298 } 299 300 _cdrInput._offset = saveOffset; 301 return _cdrInput.read_Object(); 302 } 303 } 304 else if (declaredType.isAbstractInterface) 305 { 306 isObjectRef = _cdrInput.read_boolean(); 307 if (isObjectRef) 308 { 309 return _cdrInput.read_Object(); 310 } 311 } 312 else 313 { 314 throw new IllegalStateException(declaredType.toString()); 315 } 316 } 317 318 saveOffset = _cdrInput._offset; 319 tag = _cdrInput.read_long(); 320 if (tag == ValueType.NULL_VALUE_TAG) 321 { 322 return null; 323 } 324 if (tag == ValueType.INDIRECTION_TAG) 325 { 326 saveOffset = _cdrInput._offset; 328 int offset = _cdrInput.read_long(); 329 Integer key = IntegerCache.get(saveOffset + offset); 330 if (_indirection != null) 331 { 332 value = _indirection.get(key); 333 if (value != null) 334 { 335 return value; 336 } 337 } 338 throw new org.omg.CORBA.MARSHAL("invalid indirection offset = " + offset); 339 } 340 ValueType actualType; 341 boolean saveIsChunked = _isChunked; 342 _isChunked = (tag & 0x00000008) != 0; 343 String codebaseURL = null; 344 if ((tag & 0x00000001) == 1) 345 { 346 codebaseURL = readMetaString(); 347 } 348 switch (tag & 0x00000006) 349 { 350 case 0: { 352 actualType = declaredType; 353 if (tc != null) 354 { 355 try 356 { 357 String id = tc.id(); 358 if (id != null) 359 { 360 int kind = tc.kind().value(); 361 if (kind == TCKind._tk_value_box) 362 { 363 kind = tc.content_type().kind().value(); 364 if (kind == TCKind._tk_wstring) 365 { 366 actualType = ValueType.STRING_VALUE_TYPE; 367 } 368 } 369 } 370 } 371 catch (Exception ex) 372 { 373 throw new SystemException(ex); 374 } 375 } 376 } 377 break; 378 case 2: { 380 String repositoryID = readMetaString(); 381 actualType = ValueType.getInstanceByID(repositoryID); 383 } 384 break; 385 case 6: { 387 int n = _cdrInput.read_ulong(); 388 if (n < 1) 389 { 390 throw new org.omg.CORBA.MARSHAL("invalid type list length = " + n); 391 } 392 String repositoryID = readMetaString(); 393 actualType = ValueType.getInstanceByID(repositoryID); 395 for (int i = 1; i < n; i++) 396 { 397 String ignore = readMetaString(); 398 } 399 } 400 break; 401 default: 402 throw new org.omg.CORBA.MARSHAL("invalid value tag = " + tag); 403 } 404 if (actualType.isObjectRef) 405 { 406 value = actualType.helper.read(this); 407 return value; 408 } 409 startBlock(); 410 if (_isChunked) 411 { 412 _endLevel--; 413 } 414 Integer key = new Integer(saveOffset); 415 switch (actualType.readWriteCase) 416 { 417 case ValueType.CASE_ARRAY: 418 value = readArray(actualType, key); 419 break; 420 case ValueType.CASE_CLASS: 421 value = readClassDesc(); 422 putIndirection(key, value); 423 break; 424 case ValueType.CASE_IDL_ENTITY: 425 value = actualType.helper.read(this); 426 putIndirection(key, value); 427 break; 428 case ValueType.CASE_STRING: 430 value = _cdrInput.read_wstring(); 431 putIndirection(key, value); 432 break; 433 default: 434 value = actualType.newInstance(); 435 putIndirection(key, value); 436 Object newValue = readObjectState(actualType, value, false); if (newValue != value) 438 { 439 value = newValue; 440 putIndirection(key, value); 441 } 442 } 443 endBlock(); 444 readEndTag(); 445 _isChunked = saveIsChunked; 446 startBlock(); 447 return value; 448 } 449 450 protected String readMetaString() 451 { 452 String id; 453 int saveOffset = _cdrInput._offset; 454 int tag = _cdrInput.read_long(); 455 if (tag == ValueType.INDIRECTION_TAG) 456 { 457 saveOffset = _cdrInput._offset; 458 int offset = _cdrInput.read_long(); 459 Integer key = IntegerCache.get(saveOffset + offset); 460 id = _indirection == null ? null : (String)_indirection.get(key); 461 if (id == null) 462 { 463 throw new org.omg.CORBA.MARSHAL("invalid indirection offset = " + offset); 464 } 465 } 466 else 467 { 468 _cdrInput._offset = saveOffset; 469 id = _cdrInput.read_string(); 470 putIndirection(IntegerCache.get(saveOffset), id); 471 } 472 return id; 473 } 474 475 protected Object readObjectState(ValueType valueType, Object value, boolean requiresCustomSerialization) 476 { 477 if (valueType.isExternalizable) 478 { 479 byte format = _cdrInput.read_octet(); 480 valueType.readExternal(value, this); 481 return value; 482 } 483 if (valueType.hasParentState) 484 { 485 value = readObjectState(valueType.parent, value, false); 486 } 487 if (valueType.hasReadObject) 488 { 489 push(new StreamState(valueType, value, _cdrInput._offset)); 490 517 { 518 if (valueType.hasWriteObject || requiresCustomSerialization) 519 { 520 byte format = _cdrInput.read_octet(); 521 boolean defaultWriteObjectCalled = _cdrInput.read_boolean(); 522 } 523 valueType.readObject(value, this); 524 } 525 pop(); 526 } 527 else 528 { 529 readDeclaredFields(valueType, value); 530 } 531 if (valueType.hasReadResolve) 532 { 533 value = valueType.readResolve(value); 534 } 535 return value; 536 } 537 538 protected void readDeclaredFields(ValueType valueType, Object value) 539 { 540 int n = valueType.fields.length; 541 for (int f = 0; f < n; f++) 542 { 543 ValueTypeField field = valueType.fields[f]; 544 int primitive = field.primitive; 545 if (primitive != 0) 546 { 547 readPrimitive(primitive, field, value); 548 } 549 else 550 { 551 field.set(value, readObject(field.type, false)); 552 } 553 } 554 } 555 556 protected Object readClassDesc() 557 { 558 String codebase = (String)readObject(ValueType.STRING_VALUE_TYPE); 559 String id = (String)readObject(ValueType.STRING_VALUE_TYPE); 560 return ValueType.getInstanceByID(id)._class; 561 } 562 563 protected Object readArray(ValueType arrayType, Integer key) 564 { 565 Object value = null; 566 int primitive = arrayType.primitiveArray; 567 int n = _cdrInput.read_ulong(); 568 if (primitive != 0) 569 { 570 value = arrayType.helper.read(this); 571 putIndirection(key, value); 572 } 573 else 574 { 575 Object[] array; 576 try 577 { 578 array = n == 0 ? ArrayUtil.EMPTY_OBJECT_ARRAY : (Object[])Array.newInstance(arrayType.element._class, n); 579 } 580 catch (Exception ex) 581 { 582 throw new SystemException(ex); 583 } 584 putIndirection(key, array); 585 for (int i = 0; i < n; i++) 586 { 587 array[i] = readObject(arrayType.element, false); 588 } 589 value = array; 590 } 591 return value; 592 } 593 594 private void readPrimitive(int primitive, ValueTypeField field, Object value) 595 { 596 switch (primitive) 597 { 598 case PrimitiveType.BOOLEAN: 599 field.setBoolean(value, _cdrInput.read_boolean()); 600 break; 601 case PrimitiveType.BYTE: 602 field.setByte(value, _cdrInput.read_octet()); 603 break; 604 case PrimitiveType.CHAR: 605 field.setChar(value, _cdrInput.read_wchar()); 606 break; 607 case PrimitiveType.DOUBLE: 608 field.setDouble(value, _cdrInput.read_double()); 609 break; 610 case PrimitiveType.FLOAT: 611 field.setFloat(value, _cdrInput.read_float()); 612 break; 613 case PrimitiveType.INT: 614 field.setInt(value, _cdrInput.read_long()); 615 break; 616 case PrimitiveType.LONG: 617 field.setLong(value, _cdrInput.read_longlong()); 618 break; 619 case PrimitiveType.SHORT: 620 field.setShort(value, _cdrInput.read_short()); 621 break; 622 default: 623 throw new IllegalStateException(); 624 } 625 } 626 627 632 protected void readEndTag() 633 { 634 if (_isChunked) 635 { 636 int anEndTag = _cdrInput.read_long(); 637 if (anEndTag != _endLevel) 638 { 639 _cdrInput._offset -= 4; 640 } 641 _endLevel++; 642 } 643 } 644 645 protected void startBlock() 646 { 647 if (! _isChunked) 648 { 649 return; 650 } 651 _blockLength = _cdrInput.read_long(); 652 if (_blockLength >= 0 653 && _blockLength < MAXIMUM_BLOCK_LENGTH) 654 { 655 _blockLength += _cdrInput._offset; 656 } 657 else 658 { 659 _blockLength = MAXIMUM_BLOCK_LENGTH; 661 _cdrInput._offset -= 4; 662 } 663 } 664 665 protected void endBlock() 666 { 667 if (_blockLength != MAXIMUM_BLOCK_LENGTH) 669 { 670 if (_blockLength == _cdrInput._offset) 671 { 672 _blockLength = MAXIMUM_BLOCK_LENGTH; 674 } 675 } 676 } 677 678 protected void push(StreamState state) 679 { 680 if (_stack == null) 681 { 682 _stack = new ArrayList(); 683 } 684 _stack.add(state); 685 } 686 687 protected void pop() 688 { 689 int n = _stack.size(); 690 if (n == 0) 691 { 692 throw new SystemException("pop: state stack empty"); 693 } 694 _stack.remove(n - 1); 695 } 696 697 protected StreamState top() 698 { 699 int n = _stack.size(); 700 if (n == 0) 701 { 702 throw new SystemException("top: state stack empty"); 703 } 704 return (StreamState)_stack.get(n - 1); 705 } 706 } 707 | Popular Tags |