1 19 package gcc.rmi.iiop; 20 21 import gcc.*; 22 import gcc.rmi.*; 23 import gcc.util.*; 24 import java.io.*; 25 import java.lang.reflect.*; 26 import java.util.*; 27 28 public class ObjectOutputStream extends java.io.ObjectOutputStream 29 { 30 public static ObjectOutputStream getInstance() 31 { 32 return getInstance(CdrOutputStream.getInstance()); 33 } 34 35 public static ObjectOutputStream getInstance(CdrOutputStream cdrOutput) 36 { 37 ObjectOutputStream output = null; 38 try 39 { 40 output = new ObjectOutputStream(); 41 } 42 catch( Exception ex ) 43 { 44 throw new SystemException( ex ); 45 } 46 47 output.init(cdrOutput); 48 return output; 49 } 50 51 public static ObjectOutputStream getPooledInstance() 52 { 53 ObjectOutputStream output = null; if (output == null) 55 { 56 output = getInstance(); 57 } 58 return output; 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 CdrOutputStream _cdrOutput; 84 85 public boolean _hasException; 86 87 public Object[] thisAsObjectArray; 88 89 93 private static ValueType OBJECT_VALUE_TYPE = ValueType.getInstance(java.lang.Object.class); 94 95 private static boolean OBJECT_VALUE_TYPE_INIT = false; 96 97 99 private ArrayList _stack = null; 100 101 private SimpleIdentityHashMap _indirection; 102 103 private int _blockSizeIndex = -1; 104 105 private int _endLevel; 106 107 private int _endTagIndex; 108 109 private boolean _inBlock = false; 110 111 private boolean _isChunked = false; 112 113 private int _booleanIndex = -1; 114 115 119 public ObjectOutputStream() throws IOException 120 { 121 super(); 122 } 123 124 public void $reset() 125 { 126 _cdrOutput.reset(); 127 if (_indirection != null) 128 { 129 _indirection.clear(); 130 } 131 if (_stack != null) 132 { 133 _stack.clear(); 134 } 135 _blockSizeIndex = -1; 136 _endLevel = 0; 137 _endTagIndex = 0; 138 _inBlock = false; 139 _isChunked = false; 140 _booleanIndex = -1; 141 } 142 143 public void recycle() 144 { 145 $reset(); 146 } 148 149 153 public void writeBoolean(boolean value) 154 { 155 _cdrOutput.write_boolean(value); 156 } 157 158 public void writeChar(char value) 159 { 160 _cdrOutput.write_wchar(value); 161 } 162 163 public void writeByte(byte value) 164 { 165 _cdrOutput.write_octet(value); 166 } 167 168 public void writeShort(short value) 169 { 170 _cdrOutput.write_short(value); 171 } 172 173 public void writeInt(int value) 174 { 175 _cdrOutput.write_long(value); 176 } 177 178 public void writeLong(long value) 179 { 180 _cdrOutput.write_longlong(value); 181 } 182 183 public void writeFloat(float value) 184 { 185 _cdrOutput.write_float(value); 186 } 187 188 public void writeDouble(double value) 189 { 190 _cdrOutput.write_double(value); 191 } 192 193 public void writeObjectOverride(Object value) 194 { 195 writeObject(OBJECT_VALUE_TYPE, value); 196 } 197 198 public void defaultWriteObject() throws IOException 199 { 200 StreamState state = top(); 201 int saveOffset = _cdrOutput._offset; 203 _cdrOutput._offset = _booleanIndex; 204 _cdrOutput.write_boolean(true); 205 _cdrOutput._offset = saveOffset; 206 writeDeclaredFields(state.type, state.value); 207 } 208 209 213 public boolean hasException() 214 { 215 return _hasException; 216 } 217 218 public void writeException(ValueType type, Exception value) 219 { 220 writeObject(type, value); 221 _hasException = true; 222 } 223 224 public void writeObject(ValueType type, Object value) 225 { 226 writeObject(type, value, false); 227 } 228 229 233 protected void init(CdrOutputStream cdrOutput) 234 { 235 _cdrOutput = cdrOutput; 236 thisAsObjectArray = new Object[] { this }; 237 } 238 239 protected void putIndirection(Object value, Integer ref) 240 { 241 if (_indirection == null) 242 { 243 _indirection = new SimpleIdentityHashMap(8); 244 } 245 _indirection.put(value, ref); 246 } 247 248 protected void writeObject(ValueType declaredType, Object value, boolean calledFromCustomSerialization) 249 { 250 ValueType actualType = declaredType; 251 if (value != null) 252 { 253 Class vc = value.getClass(); 254 if (vc != declaredType._class) 255 { 256 actualType = ValueType.getInstance(vc); 257 } 258 if (actualType.hasWriteReplace) 259 { 260 value = actualType.writeReplace(value); 261 } 262 } 263 boolean saveIsChunked = _isChunked; 264 if (_inBlock) 265 { 266 if (actualType != null) 267 { 268 if (! (declaredType.isAny && actualType.isObjectRef)) 269 { 270 endBlock(); 271 } 272 } 273 } 274 if (value == null) 275 { 276 if (calledFromCustomSerialization) 277 { 278 _cdrOutput.write_boolean(actualType.isObjectRef); 279 if(actualType.isObjectRef) 280 { 281 _cdrOutput.write_Object((org.omg.CORBA.Object)value); 282 endBlock(); 283 } 284 else 285 { 286 _cdrOutput.write_long(ValueType.NULL_VALUE_TAG); 287 } 288 return; 289 } 290 if (declaredType.isAny) 291 { 292 _cdrOutput.write_TypeCode(ValueType.TC_ABSTRACT_BASE); 293 _cdrOutput.write_boolean(false); 294 } 295 if (declaredType.isObjectRef) 296 { 297 _cdrOutput.write_Object((org.omg.CORBA.Object)value); 298 } 299 else 300 { 301 if (declaredType.isAbstractInterface) 302 { 303 _cdrOutput.write_boolean(false); 304 } 305 _cdrOutput.write_long(ValueType.NULL_VALUE_TAG); 306 } 307 return; 308 } 309 if (declaredType.isAny && ! calledFromCustomSerialization) 310 { 311 org.omg.CORBA.TypeCode tc = actualType.tc; 312 _cdrOutput.write_TypeCode(tc); 313 } 314 else if (declaredType.isAbstractInterface || calledFromCustomSerialization) 315 { 316 _cdrOutput.write_boolean(actualType.isObjectRef); 317 if (actualType.isObjectRef) 318 { 319 _cdrOutput.write_Object((org.omg.CORBA.Object)value); 320 return; 321 } 322 } 323 if (actualType.isObjectRef) 324 { 325 if (value instanceof RemoteInterface) 326 { 327 value = ((RemoteInterface)value).$getObjectRef(); 328 } 329 _cdrOutput.write_Object((org.omg.CORBA.Object)value); 330 return; 331 } 332 Integer ref = _indirection == null ? null : (Integer)_indirection.get(value); 333 if (ref != null) 334 { 335 _cdrOutput.write_long(ValueType.INDIRECTION_TAG); 336 _cdrOutput.write_long(ref.intValue() - _cdrOutput._offset); 337 return; 338 } 339 else 340 { 341 _cdrOutput.write_align(4, 4); ref = IntegerCache.get(_cdrOutput._offset); 343 putIndirection(value, ref); 344 } 345 if (saveIsChunked || actualType.requiresCustomSerialization) 346 { 347 _cdrOutput.write_long(ValueType.TRUNCATABLE_SINGLE_TYPE_VALUE_TAG); 348 _isChunked = true; 349 } 350 else 351 { 352 _cdrOutput.write_long(ValueType.SINGLE_TYPE_VALUE_TAG); 353 _isChunked = false; 354 } 355 writeMetaString(actualType.id); 356 startBlock(); 357 switch (actualType.readWriteCase) 358 { 359 case ValueType.CASE_ARRAY: 360 writeArray(actualType, value); 361 break; 362 case ValueType.CASE_CLASS: 363 writeClassDesc((java.lang.Class)value); 364 break; 365 case ValueType.CASE_IDL_ENTITY: 366 actualType.helper.write(this, value); 367 break; 368 case ValueType.CASE_STRING: 370 _cdrOutput.write_wstring((String)value); 371 break; 372 default: 373 writeObjectState(actualType, value); 374 } 375 endBlock(); 376 writeEndTag(); 377 _isChunked = saveIsChunked; 378 } 379 380 protected void writeMetaString(String ms) 381 { 382 Integer ref = (Integer)_indirection.get(ms); 383 if (ref != null) 384 { 385 _cdrOutput.write_long(ValueType.INDIRECTION_TAG); 386 _cdrOutput.write_long(ref.intValue() - _cdrOutput._offset); 387 } 388 else 389 { 390 ref = IntegerCache.get(_cdrOutput._offset); 391 _cdrOutput.write_string(ms); 392 putIndirection(ms, ref); 393 } 394 } 395 396 protected void writeObjectState(ValueType type, Object value) 397 { 398 if (type.isExternalizable) 399 { 400 _cdrOutput.write_octet((byte)1); 401 type.writeExternal(value, this); 402 return; 403 } 404 if (type.hasParentState) 405 { 406 writeObjectState(type.parent, value); 407 } 408 if (type.hasWriteObject && type.hasReadObject) 409 { 410 push(new StreamState(type, value, _cdrOutput._offset)); 411 if (type.skipCustomFlags) 412 { 413 _booleanIndex = _cdrOutput._offset; 414 } 415 else 416 { 417 _cdrOutput.write_octet((byte)1); 418 _cdrOutput.write_boolean(false); 419 _booleanIndex = _cdrOutput._offset - 1; 420 } 421 type.writeObject(value, this); 422 pop(); 423 } 424 else 425 { 426 writeDeclaredFields(type, value); 427 } 428 } 429 430 protected void writeDeclaredFields(ValueType type, Object value) 431 { 432 int n = type.fields.length; 433 for (int f = 0; f < n; f++) 434 { 435 ValueTypeField field = type.fields[f]; 436 int primitive = field.primitive; 437 if (primitive != 0) 438 { 439 writePrimitive(primitive, field, value); 440 } 441 else 442 { 443 writeObject(field.type, field.get(value), false); 444 } 445 } 446 } 447 448 protected void writeClassDesc(Class theClass) 449 { 450 writeObject(ValueType.STRING_VALUE_TYPE, null); writeObject(ValueType.STRING_VALUE_TYPE, ValueType.getInstance(theClass).id); 452 } 453 454 protected void writeArray(ValueType arrayType, Object value) 455 { 456 int primitive = arrayType.primitiveArray; 457 if (primitive != 0) 458 { 459 arrayType.helper.write(this, value); 460 } 461 else 462 { 463 Object[] array = (Object[])value; 464 int n = array.length; 465 _cdrOutput.write_ulong(n); 466 for (int i = 0; i < n; i++) 467 { 468 writeObject(arrayType.element, array[i], false); 469 } 470 } 471 } 472 473 protected void writePrimitive(int primitive, ValueTypeField field, Object value) 474 { 475 switch (primitive) 476 { 477 case PrimitiveType.BOOLEAN: 478 _cdrOutput.write_boolean(field.getBoolean(value)); 479 break; 480 case PrimitiveType.BYTE: 481 _cdrOutput.write_octet(field.getByte(value)); 482 break; 483 case PrimitiveType.CHAR: 484 _cdrOutput.write_wchar(field.getChar(value)); 485 break; 486 case PrimitiveType.DOUBLE: 487 _cdrOutput.write_double(field.getDouble(value)); 488 break; 489 case PrimitiveType.FLOAT: 490 _cdrOutput.write_float(field.getFloat(value)); 491 break; 492 case PrimitiveType.INT: 493 _cdrOutput.write_long(field.getInt(value)); 494 break; 495 case PrimitiveType.LONG: 496 _cdrOutput.write_longlong(field.getLong(value)); 497 break; 498 case PrimitiveType.SHORT: 499 _cdrOutput.write_short(field.getShort(value)); 500 break; 501 default: 502 throw new IllegalStateException(); 503 } 504 } 505 506 public void startBlock() 507 { 508 if (! _isChunked) 509 { 510 return; 511 } 512 _endLevel--; 513 _cdrOutput.write_long(0); 514 _inBlock = true; 515 _blockSizeIndex = _cdrOutput._offset - 4; 516 } 517 518 public void endBlock() 519 { 520 if (! _inBlock) 521 { 522 return; 523 } 524 _inBlock = false; 525 int oldSize = _cdrOutput._offset; 526 _cdrOutput._offset = _blockSizeIndex; 527 _cdrOutput.write_long(oldSize - _blockSizeIndex - 4); 528 _cdrOutput._offset = oldSize; 529 _blockSizeIndex = -1; 530 } 531 532 protected void writeEndTag() 533 { 534 if (_isChunked) 535 { 536 if (_endTagIndex == _cdrOutput._offset - 8) 537 { 538 _cdrOutput._offset -= 8; 539 } 540 _cdrOutput.write_long(_endLevel); 541 _endTagIndex = _cdrOutput._offset - 4; 542 if (_endLevel != -1) 543 { 544 _cdrOutput.write_long(1); 545 } 546 else { 548 _cdrOutput._offset -=4; 549 _cdrOutput.write_long(-1); 550 _isChunked = false; 551 } 552 _endLevel++; 553 } 554 } 555 556 588 589 protected void push(StreamState state) 590 { 591 if (_stack == null) 592 { 593 _stack = new ArrayList(); 594 } 595 _stack.add(state); 596 } 597 598 protected void pop() 599 { 600 int n = _stack.size(); 601 if (n == 0) 602 { 603 throw new SystemException("pop: state stack empty"); 604 } 605 _stack.remove(n - 1); 606 } 607 608 private StreamState top() 609 { 610 int n = _stack.size(); 611 if (n == 0) 612 { 613 throw new SystemException("top: state stack empty"); 614 } 615 return (StreamState)_stack.get(n - 1); 616 } 617 } 618 | Popular Tags |