Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.io.ObjectOutputStream

 1:  /* ObjectOutputStream.java -- Class used to write serialized objects
 2:  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 3:  Free Software Foundation, Inc.
 4: 
 5: This file is part of GNU Classpath.
 6: 
 7: GNU Classpath is free software; you can redistribute it and/or modify
 8: it under the terms of the GNU General Public License as published by
 9: the Free Software Foundation; either version 2, or (at your option)
 10: any later version.
 11: 
 12: GNU Classpath is distributed in the hope that it will be useful, but
 13: WITHOUT ANY WARRANTY; without even the implied warranty of
 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15: General Public License for more details.
 16: 
 17: You should have received a copy of the GNU General Public License
 18: along with GNU Classpath; see the file COPYING. If not, write to the
 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 20: 02110-1301 USA.
 21: 
 22: Linking this library statically or dynamically with other modules is
 23: making a combined work based on this library. Thus, the terms and
 24: conditions of the GNU General Public License cover the whole
 25: combination.
 26: 
 27: As a special exception, the copyright holders of this library give you
 28: permission to link this library with independent modules to produce an
 29: executable, regardless of the license terms of these independent
 30: modules, and to copy and distribute the resulting executable under
 31: terms of your choice, provided that you also meet, for each linked
 32: independent module, the terms and conditions of the license of that
 33: module. An independent module is a module which is not derived from
 34: or based on this library. If you modify this library, you may extend
 35: this exception to your version of the library, but you are not
 36: obligated to do so. If you do not wish to do so, delete this
 37: exception statement from your version. */
 38: 
 39: 
 40:  package java.io;
 41: 
 42:  import gnu.java.io.ObjectIdentityMap2Int;
 43:  import gnu.java.lang.reflect.TypeSignature;
 44:  import gnu.java.security.action.SetAccessibleAction;
 45: 
 46:  import java.lang.reflect.Array;
 47:  import java.lang.reflect.Field;
 48:  import java.lang.reflect.InvocationTargetException;
 49:  import java.lang.reflect.Method;
 50: 
 51: 
 52:  /**
 53:  * An <code>ObjectOutputStream</code> can be used to write objects
 54:  * as well as primitive data in a platform-independent manner to an
 55:  * <code>OutputStream</code>.
 56:  *
 57:  * The data produced by an <code>ObjectOutputStream</code> can be read
 58:  * and reconstituted by an <code>ObjectInputStream</code>.
 59:  *
 60:  * <code>writeObject (Object)</code> is used to write Objects, the
 61:  * <code>write&lt;type&gt;</code> methods are used to write primitive
 62:  * data (as in <code>DataOutputStream</code>). Strings can be written
 63:  * as objects or as primitive data.
 64:  *
 65:  * Not all objects can be written out using an
 66:  * <code>ObjectOutputStream</code>. Only those objects that are an
 67:  * instance of <code>java.io.Serializable</code> can be written.
 68:  *
 69:  * Using default serialization, information about the class of an
 70:  * object is written, all of the non-transient, non-static fields of
 71:  * the object are written, if any of these fields are objects, they are
 72:  * written out in the same manner.
 73:  *
 74:  * An object is only written out the first time it is encountered. If
 75:  * the object is encountered later, a reference to it is written to
 76:  * the underlying stream. Thus writing circular object graphs
 77:  * does not present a problem, nor are relationships between objects
 78:  * in a graph lost.
 79:  *
 80:  * Example usage:
 81:  * <pre>
 82:  * Hashtable map = new Hashtable ();
 83:  * map.put ("one", new Integer (1));
 84:  * map.put ("two", new Integer (2));
 85:  *
 86:  * ObjectOutputStream oos =
 87:  * new ObjectOutputStream (new FileOutputStream ("numbers"));
 88:  * oos.writeObject (map);
 89:  * oos.close ();
 90:  *
 91:  * ObjectInputStream ois =
 92:  * new ObjectInputStream (new FileInputStream ("numbers"));
 93:  * Hashtable newmap = (Hashtable)ois.readObject ();
 94:  *
 95:  * System.out.println (newmap);
 96:  * </pre>
 97:  *
 98:  * The default serialization can be overriden in two ways.
 99:  *
 100:  * By defining a method <code>private void
 101:  * writeObject (ObjectOutputStream)</code>, a class can dictate exactly
 102:  * how information about itself is written.
 103:  * <code>defaultWriteObject ()</code> may be called from this method to
 104:  * carry out default serialization. This method is not
 105:  * responsible for dealing with fields of super-classes or subclasses.
 106:  *
 107:  * By implementing <code>java.io.Externalizable</code>. This gives
 108:  * the class complete control over the way it is written to the
 109:  * stream. If this approach is used the burden of writing superclass
 110:  * and subclass data is transfered to the class implementing
 111:  * <code>java.io.Externalizable</code>.
 112:  *
 113:  * @see java.io.DataOutputStream
 114:  * @see java.io.Externalizable
 115:  * @see java.io.ObjectInputStream
 116:  * @see java.io.Serializable
 117:  * @author Tom Tromey (tromey@redhat.com)
 118:  * @author Jeroen Frijters (jeroen@frijters.net)
 119:  * @author Guilhem Lavaux (guilhem@kaffe.org)
 120:  * @author Michael Koch (konqueror@gmx.de)
 121:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 122:  */
 123:  public class ObjectOutputStream extends OutputStream
 124:  implements ObjectOutput, ObjectStreamConstants
 125: {
 126:  /**
 127:  * Creates a new <code>ObjectOutputStream</code> that will do all of
 128:  * its writing onto <code>out</code>. This method also initializes
 129:  * the stream by writing the header information (stream magic number
 130:  * and stream version).
 131:  *
 132:  * @exception IOException Writing stream header to underlying
 133:  * stream cannot be completed.
 134:  *
 135:  * @see #writeStreamHeader()
 136:  */
 137:  public ObjectOutputStream (OutputStream out) throws IOException
 138:  {
 139:  realOutput = new DataOutputStream(out);
 140:  blockData = new byte[ BUFFER_SIZE ];
 141:  blockDataCount = 0;
 142:  blockDataOutput = new DataOutputStream(this);
 143:  setBlockDataMode(true);
 144:  replacementEnabled = false;
 145:  isSerializing = false;
 146:  nextOID = baseWireHandle;
 147:  OIDLookupTable = new ObjectIdentityMap2Int();
 148:  protocolVersion = defaultProtocolVersion;
 149:  useSubclassMethod = false;
 150:  writeStreamHeader();
 151: 
 152:  if (DEBUG)
 153:  {
 154:  String val = System.getProperty("gcj.dumpobjects");
 155:  if (val != null && !val.equals(""))
 156:  dump = true;
 157:  }
 158:  }
 159: 
 160:  /**
 161:  * Writes a representation of <code>obj</code> to the underlying
 162:  * output stream by writing out information about its class, then
 163:  * writing out each of the objects non-transient, non-static
 164:  * fields. If any of these fields are other objects,
 165:  * they are written out in the same manner.
 166:  *
 167:  * This method can be overriden by a class by implementing
 168:  * <code>private void writeObject (ObjectOutputStream)</code>.
 169:  *
 170:  * If an exception is thrown from this method, the stream is left in
 171:  * an undefined state.
 172:  *
 173:  * @param obj the object to serialize.
 174:  * @exception NotSerializableException An attempt was made to
 175:  * serialize an <code>Object</code> that is not serializable.
 176:  *
 177:  * @exception InvalidClassException Somebody tried to serialize
 178:  * an object which is wrongly formatted.
 179:  *
 180:  * @exception IOException Exception from underlying
 181:  * <code>OutputStream</code>.
 182:  * @see #writeUnshared(Object)
 183:  */
 184:  public final void writeObject(Object obj) throws IOException
 185:  {
 186:  writeObject(obj, true);
 187:  }
 188: 
 189:  /**
 190:  * Writes an object to the stream in the same manner as
 191:  * {@link #writeObject(Object)}, but without the use of
 192:  * references. As a result, the object is always written
 193:  * to the stream in full. Likewise, if an object is written
 194:  * by this method and is then later written again by
 195:  * {@link #writeObject(Object)}, both calls will write out
 196:  * the object in full, as the later call to
 197:  * {@link #writeObject(Object)} will know nothing of the
 198:  * earlier use of {@link #writeUnshared(Object)}.
 199:  *
 200:  * @param obj the object to serialize.
 201:  * @throws NotSerializableException if the object being
 202:  * serialized does not implement
 203:  * {@link Serializable}.
 204:  * @throws InvalidClassException if a problem occurs with
 205:  * the class of the object being
 206:  * serialized.
 207:  * @throws IOException if an I/O error occurs on the underlying
 208:  * <code>OutputStream</code>.
 209:  * @since 1.4
 210:  * @see #writeObject(Object)
 211:  */
 212:  public void writeUnshared(Object obj)
 213:  throws IOException
 214:  {
 215:  writeObject(obj, false);
 216:  }
 217: 
 218:  /**
 219:  * Writes a representation of <code>obj</code> to the underlying
 220:  * output stream by writing out information about its class, then
 221:  * writing out each of the objects non-transient, non-static
 222:  * fields. If any of these fields are other objects,
 223:  * they are written out in the same manner.
 224:  *
 225:  * This method can be overriden by a class by implementing
 226:  * <code>private void writeObject (ObjectOutputStream)</code>.
 227:  *
 228:  * If an exception is thrown from this method, the stream is left in
 229:  * an undefined state.
 230:  *
 231:  * @param obj the object to serialize.
 232:  * @param shared true if the serialized object should be
 233:  * shared with later calls.
 234:  * @exception NotSerializableException An attempt was made to
 235:  * serialize an <code>Object</code> that is not serializable.
 236:  *
 237:  * @exception InvalidClassException Somebody tried to serialize
 238:  * an object which is wrongly formatted.
 239:  *
 240:  * @exception IOException Exception from underlying
 241:  * <code>OutputStream</code>.
 242:  * @see #writeUnshared(Object)
 243:  */
 244:  private final void writeObject(Object obj, boolean shared)
 245:  throws IOException
 246:  {
 247:  if (useSubclassMethod)
 248:  {
 249:  if (dump)
 250:  dumpElementln ("WRITE OVERRIDE: " + obj);
 251:  
 252:  writeObjectOverride(obj);
 253:  return;
 254:  }
 255: 
 256:  if (dump)
 257:  dumpElementln ("WRITE: " + obj);
 258:  
 259:  depth += 2; 
 260: 
 261:  boolean was_serializing = isSerializing;
 262:  boolean old_mode = setBlockDataMode(false);
 263:  try
 264:  {
 265:  isSerializing = true;
 266:  boolean replaceDone = false;
 267:  Object replacedObject = null;
 268:  
 269:  while (true)
 270:  {
 271:  if (obj == null)
 272:  {
 273:  realOutput.writeByte(TC_NULL);
 274:  break;
 275:  }
 276: 
 277:  int handle = findHandle(obj);
 278:  if (handle >= 0 && shared)
 279:  {
 280:  realOutput.writeByte(TC_REFERENCE);
 281:  realOutput.writeInt(handle);
 282:  break;
 283:  }
 284: 
 285:  if (obj instanceof Class)
 286:  {
 287:  Class cl = (Class)obj;
 288:  ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(cl);
 289:  realOutput.writeByte(TC_CLASS);
 290:  if (!osc.isProxyClass)
 291:  {
 292:  writeObject (osc);
 293:  }
 294:  else
 295:  {System.err.println("1");
 296:  realOutput.writeByte(TC_PROXYCLASSDESC);
 297:  Class[] intfs = cl.getInterfaces();
 298:  realOutput.writeInt(intfs.length);
 299:  for (int i = 0; i < intfs.length; i++)
 300:  realOutput.writeUTF(intfs[i].getName());
 301:  
 302:  boolean oldmode = setBlockDataMode(true);
 303:  annotateProxyClass(cl);
 304:  setBlockDataMode(oldmode);
 305:  realOutput.writeByte(TC_ENDBLOCKDATA);
 306:  
 307:  writeObject(osc.getSuper());
 308:  }
 309:  if (shared)
 310:  assignNewHandle(obj);
 311:  break;
 312:  }
 313: 
 314:  if (obj instanceof ObjectStreamClass)
 315:  {
 316:  writeClassDescriptor((ObjectStreamClass) obj);
 317:  break;
 318:  }
 319: 
 320:  Class clazz = obj.getClass();
 321:  ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(clazz);
 322:  if (osc == null)
 323:  throw new NotSerializableException(clazz.getName());
 324: 
 325:  if (osc.isEnum())
 326:  {
 327:  /* TC_ENUM classDesc newHandle enumConstantName */
 328:  realOutput.writeByte(TC_ENUM);
 329:  writeObject(osc);
 330:  if (shared)
 331:  assignNewHandle(obj);
 332:  writeObject(((Enum) obj).name());
 333:  break;
 334:  }
 335: 
 336:  if ((replacementEnabled || obj instanceof Serializable)
 337:  && ! replaceDone)
 338:  {
 339:  replacedObject = obj;
 340:  
 341:  if (obj instanceof Serializable)
 342:  {
 343:  try
 344:  {
 345:  Method m = osc.writeReplaceMethod;
 346:  if (m != null)
 347:  obj = m.invoke(obj, new Object[0]);
 348:  }
 349:  catch (IllegalAccessException ignore)
 350:  {
 351:  }
 352:  catch (InvocationTargetException ignore)
 353:  {
 354:  }
 355:  }
 356:  
 357:  if (replacementEnabled)
 358:  obj = replaceObject(obj);
 359:  
 360:  replaceDone = true;
 361:  continue;
 362:  }
 363: 
 364:  if (obj instanceof String)
 365:  {
 366:  realOutput.writeByte(TC_STRING);
 367:  if (shared)
 368:  assignNewHandle(obj);
 369:  realOutput.writeUTF((String)obj);
 370:  break;
 371:  }
 372: 
 373:  if (clazz.isArray ())
 374:  {
 375:  realOutput.writeByte(TC_ARRAY);
 376:  writeObject(osc);
 377:  if (shared)
 378:  assignNewHandle(obj);
 379:  writeArraySizeAndElements(obj, clazz.getComponentType());
 380:  break;
 381:  }
 382:  
 383:  realOutput.writeByte(TC_OBJECT);
 384:  writeObject(osc);
 385: 
 386:  if (shared)
 387:  if (replaceDone)
 388:  assignNewHandle(replacedObject);
 389:  else
 390:  assignNewHandle(obj);
 391:  
 392:  if (obj instanceof Externalizable)
 393:  {
 394:  if (protocolVersion == PROTOCOL_VERSION_2)
 395:  setBlockDataMode(true);
 396:  
 397:  ((Externalizable)obj).writeExternal(this);
 398:  
 399:  if (protocolVersion == PROTOCOL_VERSION_2)
 400:  {
 401:  setBlockDataMode(false);
 402:  realOutput.writeByte(TC_ENDBLOCKDATA);
 403:  }
 404: 
 405:  break;
 406:  }
 407: 
 408:  if (obj instanceof Serializable)
 409:  {
 410:  Object prevObject = this.currentObject;
 411:  ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
 412:  currentObject = obj;
 413:  ObjectStreamClass[] hierarchy = osc.hierarchy();
 414:  
 415:  for (int i = 0; i < hierarchy.length; i++)
 416:  {
 417:  currentObjectStreamClass = hierarchy[i];
 418:  
 419:  fieldsAlreadyWritten = false;
 420:  if (currentObjectStreamClass.hasWriteMethod())
 421:  {
 422:  if (dump)
 423:  dumpElementln ("WRITE METHOD CALLED FOR: " + obj);
 424:  setBlockDataMode(true);
 425:  callWriteMethod(obj, currentObjectStreamClass);
 426:  setBlockDataMode(false);
 427:  realOutput.writeByte(TC_ENDBLOCKDATA);
 428:  if (dump)
 429:  dumpElementln ("WRITE ENDBLOCKDATA FOR: " + obj);
 430:  }
 431:  else
 432:  {
 433:  if (dump)
 434:  dumpElementln ("WRITE FIELDS CALLED FOR: " + obj);
 435:  writeFields(obj, currentObjectStreamClass);
 436:  }
 437:  }
 438: 
 439:  this.currentObject = prevObject;
 440:  this.currentObjectStreamClass = prevObjectStreamClass;
 441:  currentPutField = null;
 442:  break;
 443:  }
 444: 
 445:  throw new NotSerializableException(clazz.getName()
 446:  + " in "
 447:  + obj.getClass());
 448:  } // end pseudo-loop
 449:  }
 450:  catch (ObjectStreamException ose)
 451:  {
 452:  // Rethrow these are fatal.
 453:  throw ose;
 454:  }
 455:  catch (IOException e)
 456:  {
 457:  realOutput.writeByte(TC_EXCEPTION);
 458:  reset(true);
 459: 
 460:  setBlockDataMode(false);
 461:  try
 462:  {
 463:  if (DEBUG)
 464:  {
 465:  e.printStackTrace(System.out);
 466:  }
 467:  writeObject(e);
 468:  }
 469:  catch (IOException ioe)
 470:  {
 471:  StreamCorruptedException ex = 
 472:  new StreamCorruptedException
 473:  (ioe + " thrown while exception was being written to stream.");
 474:  if (DEBUG)
 475:  {
 476:  ex.printStackTrace(System.out);
 477:  }
 478:  throw ex;
 479:  }
 480: 
 481:  reset (true);
 482:  
 483:  }
 484:  finally
 485:  {
 486:  isSerializing = was_serializing;
 487:  setBlockDataMode(old_mode);
 488:  depth -= 2;
 489: 
 490:  if (dump)
 491:  dumpElementln ("END: " + obj);
 492:  }
 493:  }
 494: 
 495:  protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException
 496:  {
 497:  if (osc.isProxyClass)
 498:  {
 499:  realOutput.writeByte(TC_PROXYCLASSDESC);
 500:  Class[] intfs = osc.forClass().getInterfaces();
 501:  realOutput.writeInt(intfs.length);
 502:  for (int i = 0; i < intfs.length; i++)
 503:  realOutput.writeUTF(intfs[i].getName());
 504: 
 505:  assignNewHandle(osc);
 506:  
 507:  boolean oldmode = setBlockDataMode(true);
 508:  annotateProxyClass(osc.forClass());
 509:  setBlockDataMode(oldmode);
 510:  realOutput.writeByte(TC_ENDBLOCKDATA);
 511:  }
 512:  else
 513:  {
 514:  realOutput.writeByte(TC_CLASSDESC);
 515:  realOutput.writeUTF(osc.getName());
 516:  if (osc.isEnum())
 517:  realOutput.writeLong(0L);
 518:  else
 519:  realOutput.writeLong(osc.getSerialVersionUID());
 520:  assignNewHandle(osc);
 521: 
 522:  int flags = osc.getFlags();
 523: 
 524:  if (protocolVersion == PROTOCOL_VERSION_2
 525:  && osc.isExternalizable())
 526:  flags |= SC_BLOCK_DATA;
 527: 
 528:  realOutput.writeByte(flags);
 529: 
 530:  ObjectStreamField[] fields = osc.fields;
 531: 
 532:  if (fields == ObjectStreamClass.INVALID_FIELDS)
 533:  throw new InvalidClassException
 534:  (osc.getName(), "serialPersistentFields is invalid");
 535: 
 536:  realOutput.writeShort(fields.length);
 537: 
 538:  ObjectStreamField field;
 539:  for (int i = 0; i < fields.length; i++)
 540:  {
 541:  field = fields[i];
 542:  realOutput.writeByte(field.getTypeCode ());
 543:  realOutput.writeUTF(field.getName ());
 544: 
 545:  if (! field.isPrimitive())
 546:  writeObject(field.getTypeString());
 547:  }
 548: 
 549:  boolean oldmode = setBlockDataMode(true);
 550:  annotateClass(osc.forClass());
 551:  setBlockDataMode(oldmode);
 552:  realOutput.writeByte(TC_ENDBLOCKDATA);
 553:  }
 554: 
 555:  if (osc.isSerializable() || osc.isExternalizable())
 556:  writeObject(osc.getSuper());
 557:  else
 558:  writeObject(null);
 559:  }
 560:  
 561:  /**
 562:  * Writes the current objects non-transient, non-static fields from
 563:  * the current class to the underlying output stream.
 564:  *
 565:  * This method is intended to be called from within a object's
 566:  * <code>private void writeObject (ObjectOutputStream)</code>
 567:  * method.
 568:  *
 569:  * @exception NotActiveException This method was called from a
 570:  * context other than from the current object's and current class's
 571:  * <code>private void writeObject (ObjectOutputStream)</code>
 572:  * method.
 573:  *
 574:  * @exception IOException Exception from underlying
 575:  * <code>OutputStream</code>.
 576:  */
 577:  public void defaultWriteObject()
 578:  throws IOException, NotActiveException
 579:  {
 580:  markFieldsWritten();
 581:  writeFields(currentObject, currentObjectStreamClass);
 582:  }
 583: 
 584: 
 585:  private void markFieldsWritten() throws IOException
 586:  {
 587:  if (currentObject == null || currentObjectStreamClass == null)
 588:  throw new NotActiveException
 589:  ("defaultWriteObject called by non-active class and/or object");
 590: 
 591:  if (fieldsAlreadyWritten)
 592:  throw new IOException
 593:  ("Only one of writeFields and defaultWriteObject may be called, and it may only be called once");
 594: 
 595:  fieldsAlreadyWritten = true;
 596:  }
 597: 
 598:  /**
 599:  * Resets stream to state equivalent to the state just after it was
 600:  * constructed.
 601:  *
 602:  * Causes all objects previously written to the stream to be
 603:  * forgotten. A notification of this reset is also written to the
 604:  * underlying stream.
 605:  *
 606:  * @exception IOException Exception from underlying
 607:  * <code>OutputStream</code> or reset called while serialization is
 608:  * in progress.
 609:  */
 610:  public void reset() throws IOException
 611:  {
 612:  reset(false);
 613:  }
 614: 
 615: 
 616:  private void reset(boolean internal) throws IOException
 617:  {
 618:  if (!internal)
 619:  {
 620:  if (isSerializing)
 621:  throw new IOException("Reset called while serialization in progress");
 622: 
 623:  realOutput.writeByte(TC_RESET);
 624:  }
 625:  
 626:  clearHandles();
 627:  }
 628: 
 629: 
 630:  /**
 631:  * Informs this <code>ObjectOutputStream</code> to write data
 632:  * according to the specified protocol. There are currently two
 633:  * different protocols, specified by <code>PROTOCOL_VERSION_1</code>
 634:  * and <code>PROTOCOL_VERSION_2</code>. This implementation writes
 635:  * data using <code>PROTOCOL_VERSION_2</code> by default, as is done
 636:  * since the JDK 1.2.
 637:  * <p>
 638:  * For an explanation of the differences between the two protocols
 639:  * see the Java Object Serialization Specification.
 640:  * </p>
 641:  * 
 642:  * @param version the version to use.
 643:  * 
 644:  * @throws IllegalArgumentException if <code>version</code> is not a valid 
 645:  * protocol.
 646:  * @throws IllegalStateException if called after the first the first object
 647:  * was serialized.
 648:  * @throws IOException if an I/O error occurs.
 649:  * 
 650:  * @see ObjectStreamConstants#PROTOCOL_VERSION_1
 651:  * @see ObjectStreamConstants#PROTOCOL_VERSION_2
 652:  * 
 653:  * @since 1.2
 654:  */
 655:  public void useProtocolVersion(int version) throws IOException
 656:  {
 657:  if (version != PROTOCOL_VERSION_1 && version != PROTOCOL_VERSION_2)
 658:  throw new IllegalArgumentException("Invalid protocol version requested.");
 659:  
 660:  if (nextOID != baseWireHandle)
 661:  throw new IllegalStateException("Protocol version cannot be changed " 
 662:  + "after serialization started.");
 663:  
 664:  protocolVersion = version;
 665:  }
 666: 
 667:  /**
 668:  * An empty hook that allows subclasses to write extra information
 669:  * about classes to the stream. This method is called the first
 670:  * time each class is seen, and after all of the standard
 671:  * information about the class has been written.
 672:  *
 673:  * @exception IOException Exception from underlying
 674:  * <code>OutputStream</code>.
 675:  *
 676:  * @see ObjectInputStream#resolveClass(java.io.ObjectStreamClass)
 677:  */
 678:  protected void annotateClass(Class<?> cl) throws IOException
 679:  {
 680:  }
 681: 
 682:  protected void annotateProxyClass(Class<?> cl) throws IOException
 683:  {
 684:  }
 685: 
 686:  /**
 687:  * Allows subclasses to replace objects that are written to the
 688:  * stream with other objects to be written in their place. This
 689:  * method is called the first time each object is encountered
 690:  * (modulo reseting of the stream).
 691:  *
 692:  * This method must be enabled before it will be called in the
 693:  * serialization process.
 694:  *
 695:  * @exception IOException Exception from underlying
 696:  * <code>OutputStream</code>.
 697:  *
 698:  * @see #enableReplaceObject(boolean)
 699:  */
 700:  protected Object replaceObject(Object obj) throws IOException
 701:  {
 702:  return obj;
 703:  }
 704: 
 705: 
 706:  /**
 707:  * If <code>enable</code> is <code>true</code> and this object is
 708:  * trusted, then <code>replaceObject (Object)</code> will be called
 709:  * in subsequent calls to <code>writeObject (Object)</code>.
 710:  * Otherwise, <code>replaceObject (Object)</code> will not be called.
 711:  *
 712:  * @exception SecurityException This class is not trusted.
 713:  */
 714:  protected boolean enableReplaceObject(boolean enable)
 715:  throws SecurityException
 716:  {
 717:  if (enable)
 718:  {
 719:  SecurityManager sm = System.getSecurityManager();
 720:  if (sm != null)
 721:  sm.checkPermission(new SerializablePermission("enableSubstitution"));
 722:  }
 723: 
 724:  boolean old_val = replacementEnabled;
 725:  replacementEnabled = enable;
 726:  return old_val;
 727:  }
 728: 
 729: 
 730:  /**
 731:  * Writes stream magic and stream version information to the
 732:  * underlying stream.
 733:  *
 734:  * @exception IOException Exception from underlying
 735:  * <code>OutputStream</code>.
 736:  */
 737:  protected void writeStreamHeader() throws IOException
 738:  {
 739:  realOutput.writeShort(STREAM_MAGIC);
 740:  realOutput.writeShort(STREAM_VERSION);
 741:  }
 742: 
 743:  /**
 744:  * Protected constructor that allows subclasses to override
 745:  * serialization. This constructor should be called by subclasses
 746:  * that wish to override <code>writeObject (Object)</code>. This
 747:  * method does a security check <i>NOTE: currently not
 748:  * implemented</i>, then sets a flag that informs
 749:  * <code>writeObject (Object)</code> to call the subclasses
 750:  * <code>writeObjectOverride (Object)</code> method.
 751:  *
 752:  * @see #writeObjectOverride(Object)
 753:  */
 754:  protected ObjectOutputStream() throws IOException, SecurityException
 755:  {
 756:  SecurityManager sec_man = System.getSecurityManager ();
 757:  if (sec_man != null)
 758:  sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
 759:  useSubclassMethod = true;
 760:  }
 761: 
 762: 
 763:  /**
 764:  * This method allows subclasses to override the default
 765:  * serialization mechanism provided by
 766:  * <code>ObjectOutputStream</code>. To make this method be used for
 767:  * writing objects, subclasses must invoke the 0-argument
 768:  * constructor on this class from there constructor.
 769:  *
 770:  * @see #ObjectOutputStream()
 771:  *
 772:  * @exception NotActiveException Subclass has arranged for this
 773:  * method to be called, but did not implement this method.
 774:  */
 775:  protected void writeObjectOverride(Object obj) throws NotActiveException,
 776:  IOException
 777:  {
 778:  throw new NotActiveException
 779:  ("Subclass of ObjectOutputStream must implement writeObjectOverride");
 780:  }
 781: 
 782: 
 783:  /**
 784:  * @see DataOutputStream#write(int)
 785:  */
 786:  public void write (int data) throws IOException
 787:  {
 788:  if (writeDataAsBlocks)
 789:  {
 790:  if (blockDataCount == BUFFER_SIZE)
 791:  drain();
 792: 
 793:  blockData[ blockDataCount++ ] = (byte)data;
 794:  }
 795:  else
 796:  realOutput.write(data);
 797:  }
 798: 
 799: 
 800:  /**
 801:  * @see DataOutputStream#write(byte[])
 802:  */
 803:  public void write(byte[] b) throws IOException
 804:  {
 805:  write(b, 0, b.length);
 806:  }
 807: 
 808: 
 809:  /**
 810:  * @see DataOutputStream#write(byte[],int,int)
 811:  */
 812:  public void write(byte[] b, int off, int len) throws IOException
 813:  {
 814:  if (writeDataAsBlocks)
 815:  {
 816:  if (len < 0)
 817:  throw new IndexOutOfBoundsException();
 818: 
 819:  if (blockDataCount + len < BUFFER_SIZE)
 820:  {
 821:  System.arraycopy(b, off, blockData, blockDataCount, len);
 822:  blockDataCount += len;
 823:  }
 824:  else
 825:  {
 826:  drain();
 827:  writeBlockDataHeader(len);
 828:  realOutput.write(b, off, len);
 829:  }
 830:  }
 831:  else
 832:  realOutput.write(b, off, len);
 833:  }
 834: 
 835: 
 836:  /**
 837:  * @see DataOutputStream#flush()
 838:  */
 839:  public void flush () throws IOException
 840:  {
 841:  drain();
 842:  realOutput.flush();
 843:  }
 844: 
 845: 
 846:  /**
 847:  * Causes the block-data buffer to be written to the underlying
 848:  * stream, but does not flush underlying stream.
 849:  *
 850:  * @exception IOException Exception from underlying
 851:  * <code>OutputStream</code>.
 852:  */
 853:  protected void drain() throws IOException
 854:  {
 855:  if (blockDataCount == 0)
 856:  return;
 857: 
 858:  if (writeDataAsBlocks)
 859:  writeBlockDataHeader(blockDataCount);
 860:  realOutput.write(blockData, 0, blockDataCount);
 861:  blockDataCount = 0;
 862:  }
 863: 
 864: 
 865:  /**
 866:  * @see java.io.DataOutputStream#close ()
 867:  */
 868:  public void close() throws IOException
 869:  {
 870:  flush();
 871:  realOutput.close();
 872:  }
 873: 
 874: 
 875:  /**
 876:  * @see java.io.DataOutputStream#writeBoolean (boolean)
 877:  */
 878:  public void writeBoolean(boolean data) throws IOException
 879:  {
 880:  blockDataOutput.writeBoolean(data);
 881:  }
 882: 
 883: 
 884:  /**
 885:  * @see java.io.DataOutputStream#writeByte (int)
 886:  */
 887:  public void writeByte(int data) throws IOException
 888:  {
 889:  blockDataOutput.writeByte(data);
 890:  }
 891: 
 892: 
 893:  /**
 894:  * @see java.io.DataOutputStream#writeShort (int)
 895:  */
 896:  public void writeShort (int data) throws IOException
 897:  {
 898:  blockDataOutput.writeShort(data);
 899:  }
 900: 
 901: 
 902:  /**
 903:  * @see java.io.DataOutputStream#writeChar (int)
 904:  */
 905:  public void writeChar(int data) throws IOException
 906:  {
 907:  blockDataOutput.writeChar(data);
 908:  }
 909: 
 910: 
 911:  /**
 912:  * @see java.io.DataOutputStream#writeInt (int)
 913:  */
 914:  public void writeInt(int data) throws IOException
 915:  {
 916:  blockDataOutput.writeInt(data);
 917:  }
 918: 
 919: 
 920:  /**
 921:  * @see java.io.DataOutputStream#writeLong (long)
 922:  */
 923:  public void writeLong(long data) throws IOException
 924:  {
 925:  blockDataOutput.writeLong(data);
 926:  }
 927: 
 928: 
 929:  /**
 930:  * @see java.io.DataOutputStream#writeFloat (float)
 931:  */
 932:  public void writeFloat(float data) throws IOException
 933:  {
 934:  blockDataOutput.writeFloat(data);
 935:  }
 936: 
 937: 
 938:  /**
 939:  * @see java.io.DataOutputStream#writeDouble (double)
 940:  */
 941:  public void writeDouble(double data) throws IOException
 942:  {
 943:  blockDataOutput.writeDouble(data);
 944:  }
 945: 
 946: 
 947:  /**
 948:  * @see java.io.DataOutputStream#writeBytes (java.lang.String)
 949:  */
 950:  public void writeBytes(String data) throws IOException
 951:  {
 952:  blockDataOutput.writeBytes(data);
 953:  }
 954: 
 955: 
 956:  /**
 957:  * @see java.io.DataOutputStream#writeChars (java.lang.String)
 958:  */
 959:  public void writeChars(String data) throws IOException
 960:  {
 961:  dataOutput.writeChars(data);
 962:  }
 963: 
 964: 
 965:  /**
 966:  * @see java.io.DataOutputStream#writeUTF (java.lang.String)
 967:  */
 968:  public void writeUTF(String data) throws IOException
 969:  {
 970:  dataOutput.writeUTF(data);
 971:  }
 972: 
 973: 
 974:  /**
 975:  * This class allows a class to specify exactly which fields should
 976:  * be written, and what values should be written for these fields.
 977:  *
 978:  * XXX: finish up comments
 979:  */
 980:  public abstract static class PutField
 981:  {
 982:  public abstract void put (String name, boolean value);
 983:  public abstract void put (String name, byte value);
 984:  public abstract void put (String name, char value);
 985:  public abstract void put (String name, double value);
 986:  public abstract void put (String name, float value);
 987:  public abstract void put (String name, int value);
 988:  public abstract void put (String name, long value);
 989:  public abstract void put (String name, short value);
 990:  public abstract void put (String name, Object value);
 991: 
 992:  /**
 993:  * @deprecated
 994:  */
 995:  public abstract void write (ObjectOutput out) throws IOException;
 996:  }
 997: 
 998:  public PutField putFields() throws IOException
 999:  {
1000:  if (currentPutField != null)
1001:  return currentPutField;
1002: 
1003:  currentPutField = new PutField()
1004:  {
1005:  private byte[] prim_field_data
1006:  = new byte[currentObjectStreamClass.primFieldSize];
1007:  private Object[] objs
1008:  = new Object[currentObjectStreamClass.objectFieldCount];
1009: 
1010:  private ObjectStreamField getField (String name)
1011:  {
1012:  ObjectStreamField field
1013:  = currentObjectStreamClass.getField(name);
1014:  
1015:  if (field == null)
1016:  throw new IllegalArgumentException("no such serializable field " + name);
1017:  
1018:  return field;
1019:  }
1020:  
1021:  public void put(String name, boolean value)
1022:  {
1023:  ObjectStreamField field = getField(name);
1024: 
1025:  checkType(field, 'Z');
1026:  prim_field_data[field.getOffset ()] = (byte)(value ? 1 : 0);
1027:  }
1028: 
1029:  public void put(String name, byte value)
1030:  {
1031:  ObjectStreamField field = getField(name);
1032: 
1033:  checkType(field, 'B');
1034:  prim_field_data[field.getOffset()] = value;
1035:  }
1036: 
1037:  public void put(String name, char value)
1038:  {
1039:  ObjectStreamField field = getField(name);
1040: 
1041:  checkType(field, 'C');
1042:  int off = field.getOffset();
1043:  prim_field_data[off++] = (byte)(value >>> 8);
1044:  prim_field_data[off] = (byte)value;
1045:  }
1046: 
1047:  public void put(String name, double value)
1048:  {
1049:  ObjectStreamField field = getField (name);
1050: 
1051:  checkType(field, 'D');
1052:  int off = field.getOffset();
1053:  long l_value = Double.doubleToLongBits (value);
1054:  prim_field_data[off++] = (byte)(l_value >>> 52);
1055:  prim_field_data[off++] = (byte)(l_value >>> 48);
1056:  prim_field_data[off++] = (byte)(l_value >>> 40);
1057:  prim_field_data[off++] = (byte)(l_value >>> 32);
1058:  prim_field_data[off++] = (byte)(l_value >>> 24);
1059:  prim_field_data[off++] = (byte)(l_value >>> 16);
1060:  prim_field_data[off++] = (byte)(l_value >>> 8);
1061:  prim_field_data[off] = (byte)l_value;
1062:  }
1063: 
1064:  public void put(String name, float value)
1065:  {
1066:  ObjectStreamField field = getField(name);
1067: 
1068:  checkType(field, 'F');
1069:  int off = field.getOffset();
1070:  int i_value = Float.floatToIntBits(value);
1071:  prim_field_data[off++] = (byte)(i_value >>> 24);
1072:  prim_field_data[off++] = (byte)(i_value >>> 16);
1073:  prim_field_data[off++] = (byte)(i_value >>> 8);
1074:  prim_field_data[off] = (byte)i_value;
1075:  }
1076: 
1077:  public void put(String name, int value)
1078:  {
1079:  ObjectStreamField field = getField(name);
1080:  checkType(field, 'I');
1081:  int off = field.getOffset();
1082:  prim_field_data[off++] = (byte)(value >>> 24);
1083:  prim_field_data[off++] = (byte)(value >>> 16);
1084:  prim_field_data[off++] = (byte)(value >>> 8);
1085:  prim_field_data[off] = (byte)value;
1086:  }
1087: 
1088:  public void put(String name, long value)
1089:  {
1090:  ObjectStreamField field = getField(name);
1091:  checkType(field, 'J');
1092:  int off = field.getOffset();
1093:  prim_field_data[off++] = (byte)(value >>> 52);
1094:  prim_field_data[off++] = (byte)(value >>> 48);
1095:  prim_field_data[off++] = (byte)(value >>> 40);
1096:  prim_field_data[off++] = (byte)(value >>> 32);
1097:  prim_field_data[off++] = (byte)(value >>> 24);
1098:  prim_field_data[off++] = (byte)(value >>> 16);
1099:  prim_field_data[off++] = (byte)(value >>> 8);
1100:  prim_field_data[off] = (byte)value;
1101:  }
1102: 
1103:  public void put(String name, short value)
1104:  {
1105:  ObjectStreamField field = getField(name);
1106:  checkType(field, 'S');
1107:  int off = field.getOffset();
1108:  prim_field_data[off++] = (byte)(value >>> 8);
1109:  prim_field_data[off] = (byte)value;
1110:  }
1111: 
1112:  public void put(String name, Object value)
1113:  {
1114:  ObjectStreamField field = getField(name);
1115: 
1116:  if (value != null &&
1117:  ! field.getType().isAssignableFrom(value.getClass ())) 
1118:  throw new IllegalArgumentException("Class " + value.getClass() +
1119:  " cannot be cast to " + field.getType());
1120:  objs[field.getOffset()] = value;
1121:  }
1122: 
1123:  public void write(ObjectOutput out) throws IOException
1124:  {
1125:  // Apparently Block data is not used with PutField as per
1126:  // empirical evidence against JDK 1.2. Also see Mauve test
1127:  // java.io.ObjectInputOutput.Test.GetPutField.
1128:  boolean oldmode = setBlockDataMode(false);
1129:  out.write(prim_field_data);
1130:  for (int i = 0; i < objs.length; ++ i)
1131:  out.writeObject(objs[i]);
1132:  setBlockDataMode(oldmode);
1133:  }
1134: 
1135:  private void checkType(ObjectStreamField field, char type)
1136:  throws IllegalArgumentException
1137:  {
1138:  if (TypeSignature.getEncodingOfClass(field.getType()).charAt(0)
1139:  != type)
1140:  throw new IllegalArgumentException();
1141:  }
1142:  };
1143:  // end PutFieldImpl
1144: 
1145:  return currentPutField;
1146:  }
1147: 
1148: 
1149:  public void writeFields() throws IOException
1150:  {
1151:  if (currentPutField == null)
1152:  throw new NotActiveException("writeFields can only be called after putFields has been called");
1153: 
1154:  markFieldsWritten();
1155:  currentPutField.write(this);
1156:  }
1157: 
1158: 
1159:  // write out the block-data buffer, picking the correct header
1160:  // depending on the size of the buffer
1161:  private void writeBlockDataHeader(int size) throws IOException
1162:  {
1163:  if (size < 256)
1164:  {
1165:  realOutput.writeByte(TC_BLOCKDATA);
1166:  realOutput.write(size);
1167:  }
1168:  else
1169:  {
1170:  realOutput.writeByte(TC_BLOCKDATALONG);
1171:  realOutput.writeInt(size);
1172:  }
1173:  }
1174: 
1175: 
1176:  // lookup the handle for OBJ, return null if OBJ doesn't have a
1177:  // handle yet
1178:  private int findHandle(Object obj)
1179:  {
1180:  return OIDLookupTable.get(obj);
1181:  }
1182: 
1183: 
1184:  // assigns the next availible handle to OBJ
1185:  private int assignNewHandle(Object obj)
1186:  {
1187:  OIDLookupTable.put(obj, nextOID);
1188:  return nextOID++;
1189:  }
1190: 
1191: 
1192:  // resets mapping from objects to handles
1193:  private void clearHandles()
1194:  {
1195:  nextOID = baseWireHandle;
1196:  OIDLookupTable.clear();
1197:  }
1198: 
1199: 
1200:  // write out array size followed by each element of the array
1201:  private void writeArraySizeAndElements(Object array, Class clazz)
1202:  throws IOException
1203:  {
1204:  int length = Array.getLength(array);
1205: 
1206:  if (clazz.isPrimitive())
1207:  {
1208:  if (clazz == Boolean.TYPE)
1209:  {
1210:  boolean[] cast_array = (boolean[])array;
1211:  realOutput.writeInt (length);
1212:  for (int i = 0; i < length; i++)
1213:  realOutput.writeBoolean(cast_array[i]);
1214:  return;
1215:  }
1216:  if (clazz == Byte.TYPE)
1217:  {
1218:  byte[] cast_array = (byte[])array;
1219:  realOutput.writeInt(length);
1220:  realOutput.write(cast_array, 0, length);
1221:  return;
1222:  }
1223:  if (clazz == Character.TYPE)
1224:  {
1225:  char[] cast_array = (char[])array;
1226:  realOutput.writeInt(length);
1227:  for (int i = 0; i < length; i++)
1228:  realOutput.writeChar(cast_array[i]);
1229:  return;
1230:  }
1231:  if (clazz == Double.TYPE)
1232:  {
1233:  double[] cast_array = (double[])array;
1234:  realOutput.writeInt(length);
1235:  for (int i = 0; i < length; i++)
1236:  realOutput.writeDouble(cast_array[i]);
1237:  return;
1238:  }
1239:  if (clazz == Float.TYPE)
1240:  {
1241:  float[] cast_array = (float[])array;
1242:  realOutput.writeInt(length);
1243:  for (int i = 0; i < length; i++)
1244:  realOutput.writeFloat(cast_array[i]);
1245:  return;
1246:  }
1247:  if (clazz == Integer.TYPE)
1248:  {
1249:  int[] cast_array = (int[])array;
1250:  realOutput.writeInt(length);
1251:  for (int i = 0; i < length; i++)
1252:  realOutput.writeInt(cast_array[i]);
1253:  return;
1254:  }
1255:  if (clazz == Long.TYPE)
1256:  {
1257:  long[] cast_array = (long[])array;
1258:  realOutput.writeInt (length);
1259:  for (int i = 0; i < length; i++)
1260:  realOutput.writeLong(cast_array[i]);
1261:  return;
1262:  }
1263:  if (clazz == Short.TYPE)
1264:  {
1265:  short[] cast_array = (short[])array;
1266:  realOutput.writeInt (length);
1267:  for (int i = 0; i < length; i++)
1268:  realOutput.writeShort(cast_array[i]);
1269:  return;
1270:  }
1271:  }
1272:  else
1273:  {
1274:  Object[] cast_array = (Object[])array;
1275:  realOutput.writeInt(length);
1276:  for (int i = 0; i < length; i++)
1277:  writeObject(cast_array[i]);
1278:  }
1279:  }
1280: 
1281: 
1282:  // writes out FIELDS of OBJECT for the specified ObjectStreamClass.
1283:  // FIELDS are already in canonical order.
1284:  private void writeFields(Object obj, ObjectStreamClass osc)
1285:  throws IOException
1286:  {
1287:  ObjectStreamField[] fields = osc.fields;
1288:  boolean oldmode = setBlockDataMode(false);
1289: 
1290:  try
1291:  {
1292:  writeFields(obj,fields);
1293:  }
1294:  catch (IllegalArgumentException _)
1295:  {
1296:  InvalidClassException e = new InvalidClassException
1297:  ("writing fields of class " + osc.forClass().getName());
1298:  e.initCause(_);
1299:  throw e;
1300:  }
1301:  catch (IOException e)
1302:  {
1303:  throw e;
1304:  }
1305:  catch (Exception _)
1306:  {
1307:  IOException e = new IOException("Unexpected exception " + _);
1308:  e.initCause(_);
1309:  throw(e);
1310:  } 
1311: 
1312:  setBlockDataMode(oldmode);
1313:  }
1314:  
1315: 
1316:  /**
1317:  * Helper function for writeFields(Object,ObjectStreamClass): write
1318:  * fields from given fields array. Pass exception on.
1319:  *
1320:  * @param obj the object to be written
1321:  *
1322:  * @param fields the fields of obj to be written.
1323:  */
1324:  private void writeFields(Object obj, ObjectStreamField[] fields)
1325:  throws
1326:  IllegalArgumentException, IllegalAccessException, IOException
1327:  {
1328:  for (int i = 0; i < fields.length; i++)
1329:  {
1330:  ObjectStreamField osf = fields[i];
1331:  Field field = osf.field;
1332:  
1333:  if (DEBUG && dump)
1334:  dumpElementln ("WRITE FIELD: " + osf.getName() + " type=" + osf.getType());
1335:  
1336:  switch (osf.getTypeCode())
1337:  {
1338:  case 'Z': realOutput.writeBoolean(field.getBoolean(obj)); break;
1339:  case 'B': realOutput.writeByte (field.getByte (obj)); break;
1340:  case 'S': realOutput.writeShort (field.getShort (obj)); break;
1341:  case 'C': realOutput.writeChar (field.getChar (obj)); break;
1342:  case 'I': realOutput.writeInt (field.getInt (obj)); break;
1343:  case 'F': realOutput.writeFloat (field.getFloat (obj)); break;
1344:  case 'J': realOutput.writeLong (field.getLong (obj)); break;
1345:  case 'D': realOutput.writeDouble (field.getDouble (obj)); break;
1346:  case 'L': 
1347:  case '[': writeObject (field.get (obj)); break;
1348:  default: 
1349:  throw new IOException("Unexpected type code " + osf.getTypeCode());
1350:  }
1351:  }
1352:  }
1353: 
1354: 
1355:  // Toggles writing primitive data to block-data buffer.
1356:  // Package-private to avoid a trampoline constructor.
1357:  boolean setBlockDataMode(boolean on) throws IOException
1358:  {
1359:  if (on == writeDataAsBlocks)
1360:  return on;
1361: 
1362:  drain();
1363:  boolean oldmode = writeDataAsBlocks;
1364:  writeDataAsBlocks = on;
1365: 
1366:  if (on)
1367:  dataOutput = blockDataOutput;
1368:  else
1369:  dataOutput = realOutput;
1370: 
1371:  return oldmode;
1372:  }
1373: 
1374: 
1375:  private void callWriteMethod(Object obj, ObjectStreamClass osc)
1376:  throws IOException
1377:  {
1378:  currentPutField = null;
1379:  try
1380:  {
1381:  Object args[] = {this};
1382:  osc.writeObjectMethod.invoke(obj, args);
1383:  }
1384:  catch (InvocationTargetException x)
1385:  {
1386:  /* Rethrow if possible. */
1387:  Throwable exception = x.getTargetException();
1388:  if (exception instanceof RuntimeException)
1389:  throw (RuntimeException) exception;
1390:  if (exception instanceof IOException)
1391:  throw (IOException) exception;
1392: 
1393:  IOException ioe
1394:  = new IOException("Exception thrown from writeObject() on " +
1395:  osc.forClass().getName() + ": " +
1396:  exception.getClass().getName());
1397:  ioe.initCause(exception);
1398:  throw ioe;
1399:  }
1400:  catch (Exception x)
1401:  {
1402:  IOException ioe
1403:  = new IOException("Failure invoking writeObject() on " +
1404:  osc.forClass().getName() + ": " +
1405:  x.getClass().getName());
1406:  ioe.initCause(x);
1407:  throw ioe;
1408:  }
1409:  }
1410: 
1411:  private void dumpElementln (String msg)
1412:  {
1413:  for (int i = 0; i < depth; i++)
1414:  System.out.print (" ");
1415:  System.out.print (Thread.currentThread() + ": ");
1416:  System.out.println(msg);
1417:  }
1418: 
1419:  // this value comes from 1.2 spec, but is used in 1.1 as well
1420:  private static final int BUFFER_SIZE = 1024;
1421: 
1422:  private static int defaultProtocolVersion = PROTOCOL_VERSION_2;
1423: 
1424:  private DataOutputStream dataOutput;
1425:  private boolean writeDataAsBlocks;
1426:  private DataOutputStream realOutput;
1427:  private DataOutputStream blockDataOutput;
1428:  private byte[] blockData;
1429:  private int blockDataCount;
1430:  private Object currentObject;
1431:  // Package-private to avoid a trampoline.
1432:  ObjectStreamClass currentObjectStreamClass;
1433:  private PutField currentPutField;
1434:  private boolean fieldsAlreadyWritten;
1435:  private boolean replacementEnabled;
1436:  private boolean isSerializing;
1437:  private int nextOID;
1438:  private ObjectIdentityMap2Int OIDLookupTable;
1439:  private int protocolVersion;
1440:  private boolean useSubclassMethod;
1441:  private SetAccessibleAction setAccessible = new SetAccessibleAction();
1442: 
1443:  // The nesting depth for debugging output
1444:  private int depth = 0;
1445: 
1446:  // Set if we're generating debugging dumps
1447:  private boolean dump = false;
1448: 
1449:  private static final boolean DEBUG = false;
1450: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

AltStyle によって変換されたページ (->オリジナル) /