1:
38:
39:
40: package ;
41:
42: import ;
43:
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58: public class ObjectInputStream extends InputStream
59: implements ObjectInput, ObjectStreamConstants
60: {
61:
75: public ObjectInputStream(InputStream in)
76: throws IOException, StreamCorruptedException
77: {
78: if (DEBUG)
79: {
80: String val = System.getProperty("gcj.dumpobjects");
81: if (dump == false && val != null && !val.equals(""))
82: {
83: dump = true;
84: System.out.println ("Serialization debugging enabled");
85: }
86: else if (dump == true && (val == null || val.equals("")))
87: {
88: dump = false;
89: System.out.println ("Serialization debugging disabled");
90: }
91: }
92:
93: this.resolveEnabled = false;
94: this.blockDataPosition = 0;
95: this.blockDataBytes = 0;
96: this.blockData = new byte[BUFFER_SIZE];
97: this.blockDataInput = new DataInputStream(this);
98: this.realInputStream = new DataInputStream(in);
99: this.nextOID = baseWireHandle;
100: this.objectLookupTable = new Hashtable();
101: this.classLookupTable = new Hashtable();
102: setBlockDataMode(true);
103: readStreamHeader();
104: }
105:
106:
107:
125: public final Object readObject()
126: throws ClassNotFoundException, IOException
127: {
128: if (this.useSubclassMethod)
129: return readObjectOverride();
130:
131: Object ret_val;
132: boolean old_mode = setBlockDataMode(false);
133: byte marker = this.realInputStream.readByte();
134:
135: if (DEBUG)
136: depth += 2;
137:
138: if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
139:
140: try
141: {
142: ret_val = parseContent(marker);
143: }
144: finally
145: {
146: setBlockDataMode(old_mode);
147: if (DEBUG)
148: depth -= 2;
149: }
150:
151: return ret_val;
152: }
153:
154:
165: private Object parseContent(byte marker)
166: throws ClassNotFoundException, IOException
167: {
168: Object ret_val;
169: boolean is_consumed = false;
170:
171: switch (marker)
172: {
173: case TC_ENDBLOCKDATA:
174: {
175: ret_val = null;
176: is_consumed = true;
177: break;
178: }
179:
180: case TC_BLOCKDATA:
181: case TC_BLOCKDATALONG:
182: {
183: if (marker == TC_BLOCKDATALONG)
184: { if(dump) dumpElementln("BLOCKDATALONG"); }
185: else
186: { if(dump) dumpElementln("BLOCKDATA"); }
187: readNextBlock(marker);
188: }
189:
190: case TC_NULL:
191: {
192: if(dump) dumpElementln("NULL");
193: ret_val = null;
194: break;
195: }
196:
197: case TC_REFERENCE:
198: {
199: if(dump) dumpElement("REFERENCE ");
200: Integer oid = new Integer(this.realInputStream.readInt());
201: if(dump) dumpElementln(Integer.toHexString(oid.intValue()));
202: ret_val = ((ObjectIdentityWrapper)
203: this.objectLookupTable.get(oid)).object;
204: break;
205: }
206:
207: case TC_CLASS:
208: {
209: if(dump) dumpElementln("CLASS");
210: ObjectStreamClass osc = (ObjectStreamClass)readObject();
211: Class clazz = osc.forClass();
212: assignNewHandle(clazz);
213: ret_val = clazz;
214: break;
215: }
216:
217: case TC_PROXYCLASSDESC:
218: {
219: if(dump) dumpElementln("PROXYCLASS");
220: int n_intf = this.realInputStream.readInt();
221: String[] intfs = new String[n_intf];
222: for (int i = 0; i < n_intf; i++)
223: {
224: intfs[i] = this.realInputStream.readUTF();
225: }
226:
227: boolean oldmode = setBlockDataMode(true);
228: Class cl = resolveProxyClass(intfs);
229: setBlockDataMode(oldmode);
230:
231: ObjectStreamClass osc = lookupClass(cl);
232: if (osc.firstNonSerializableParentConstructor == null)
233: {
234: osc.realClassIsSerializable = true;
235: osc.fields = osc.fieldMapping = new ObjectStreamField[0];
236: try
237: {
238: osc.firstNonSerializableParentConstructor =
239: Object.class.getConstructor(new Class[0]);
240: }
241: catch (NoSuchMethodException x)
242: {
243: throw (InternalError)
244: new InternalError("Object ctor missing").initCause(x);
245: }
246: }
247: assignNewHandle(osc);
248:
249: if (!is_consumed)
250: {
251: byte b = this.realInputStream.readByte();
252: if (b != TC_ENDBLOCKDATA)
253: throw new IOException("Data annotated to class was not consumed." + b);
254: }
255: else
256: is_consumed = false;
257: ObjectStreamClass superosc = (ObjectStreamClass)readObject();
258: osc.setSuperclass(superosc);
259: ret_val = osc;
260: break;
261: }
262:
263: case TC_CLASSDESC:
264: {
265: ObjectStreamClass osc = readClassDescriptor();
266:
267: if (!is_consumed)
268: {
269: byte b = this.realInputStream.readByte();
270: if (b != TC_ENDBLOCKDATA)
271: throw new IOException("Data annotated to class was not consumed." + b);
272: }
273: else
274: is_consumed = false;
275:
276: osc.setSuperclass ((ObjectStreamClass)readObject());
277: ret_val = osc;
278: break;
279: }
280:
281: case TC_STRING:
282: case TC_LONGSTRING:
283: {
284: if(dump) dumpElement("STRING=");
285: String s = this.realInputStream.readUTF();
286: if(dump) dumpElementln(s);
287: ret_val = processResolution(null, s, assignNewHandle(s));
288: break;
289: }
290:
291: case TC_ARRAY:
292: {
293: if(dump) dumpElementln("ARRAY");
294: ObjectStreamClass osc = (ObjectStreamClass)readObject();
295: Class componentType = osc.forClass().getComponentType();
296: if(dump) dumpElement("ARRAY LENGTH=");
297: int length = this.realInputStream.readInt();
298: if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
299: Object array = Array.newInstance(componentType, length);
300: int handle = assignNewHandle(array);
301: readArrayElements(array, componentType);
302: if(dump)
303: for (int i = 0, len = Array.getLength(array); i < len; i++)
304: dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
305: ret_val = processResolution(null, array, handle);
306: break;
307: }
308:
309: case TC_OBJECT:
310: {
311: if(dump) dumpElementln("OBJECT");
312: ObjectStreamClass osc = (ObjectStreamClass)readObject();
313: Class clazz = osc.forClass();
314:
315: if (!osc.realClassIsSerializable)
316: throw new NotSerializableException
317: (clazz + " is not Serializable, and thus cannot be deserialized.");
318:
319: if (osc.realClassIsExternalizable)
320: {
321: Externalizable obj = osc.newInstance();
322:
323: int handle = assignNewHandle(obj);
324:
325: boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
326:
327: boolean oldmode = this.readDataFromBlock;
328: if (read_from_blocks)
329: setBlockDataMode(true);
330:
331: obj.readExternal(this);
332:
333: if (read_from_blocks)
334: {
335: setBlockDataMode(oldmode);
336: if (!oldmode)
337: if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
338: throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
339: }
340:
341: ret_val = processResolution(osc, obj, handle);
342: break;
343:
344: }
345:
346: Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
347:
348: int handle = assignNewHandle(obj);
349: Object prevObject = this.currentObject;
350: ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
351: TreeSet prevObjectValidators = this.currentObjectValidators;
352:
353: this.currentObject = obj;
354: this.currentObjectValidators = null;
355: ObjectStreamClass[] hierarchy =
356: inputGetObjectStreamClasses(clazz);
357:
358: for (int i = 0; i < hierarchy.length; i++)
359: {
360: this.currentObjectStreamClass = hierarchy[i];
361: if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
362:
363:
364:
365:
366:
367:
368: Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
369: if (readObjectMethod != null)
370: {
371: fieldsAlreadyRead = false;
372: boolean oldmode = setBlockDataMode(true);
373: callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
374: setBlockDataMode(oldmode);
375: }
376: else
377: {
378: readFields(obj, currentObjectStreamClass);
379: }
380:
381: if (this.currentObjectStreamClass.hasWriteMethod())
382: {
383: if(dump) dumpElement("ENDBLOCKDATA? ");
384: try
385: {
386:
387: byte writeMarker = this.realInputStream.readByte();
388: while (writeMarker != TC_ENDBLOCKDATA)
389: {
390: parseContent(writeMarker);
391: writeMarker = this.realInputStream.readByte();
392: }
393: if(dump) dumpElementln("yes");
394: }
395: catch (EOFException e)
396: {
397: throw (IOException) new IOException
398: ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e);
399: }
400: }
401: }
402:
403: this.currentObject = prevObject;
404: this.currentObjectStreamClass = prevObjectStreamClass;
405: ret_val = processResolution(osc, obj, handle);
406: if (currentObjectValidators != null)
407: invokeValidators();
408: this.currentObjectValidators = prevObjectValidators;
409:
410: break;
411: }
412:
413: case TC_RESET:
414: if(dump) dumpElementln("RESET");
415: clearHandles();
416: ret_val = readObject();
417: break;
418:
419: case TC_EXCEPTION:
420: {
421: if(dump) dumpElement("EXCEPTION=");
422: Exception e = (Exception)readObject();
423: if(dump) dumpElementln(e.toString());
424: clearHandles();
425: throw new WriteAbortedException("Exception thrown during writing of stream", e);
426: }
427:
428: default:
429: throw new IOException("Unknown marker on stream: " + marker);
430: }
431: return ret_val;
432: }
433:
434:
447: private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
448: throws InvalidClassException
449: {
450: int nonPrimitive = 0;
451:
452: for (nonPrimitive = 0;
453: nonPrimitive < fields1.length
454: && fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
455: {
456: }
457:
458: if (nonPrimitive == fields1.length)
459: return;
460:
461: int i = 0;
462: ObjectStreamField f1;
463: ObjectStreamField f2;
464:
465: while (i < fields2.length
466: && nonPrimitive < fields1.length)
467: {
468: f1 = fields1[nonPrimitive];
469: f2 = fields2[i];
470:
471: if (!f2.isPrimitive())
472: break;
473:
474: int compVal = f1.getName().compareTo (f2.getName());
475:
476: if (compVal < 0)
477: {
478: nonPrimitive++;
479: }
480: else if (compVal > 0)
481: {
482: i++;
483: }
484: else
485: {
486: throw new InvalidClassException
487: ("invalid field type for " + f2.getName() +
488: " in class " + name);
489: }
490: }
491: }
492:
493:
509: protected ObjectStreamClass readClassDescriptor()
510: throws ClassNotFoundException, IOException
511: {
512: if(dump) dumpElement("CLASSDESC NAME=");
513: String name = this.realInputStream.readUTF();
514: if(dump) dumpElement(name + "; UID=");
515: long uid = this.realInputStream.readLong ();
516: if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");
517: byte flags = this.realInputStream.readByte ();
518: if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");
519: short field_count = this.realInputStream.readShort();
520: if(dump) dumpElementln(Short.toString(field_count));
521: ObjectStreamField[] fields = new ObjectStreamField[field_count];
522: ObjectStreamClass osc = new ObjectStreamClass(name, uid,
523: flags, fields);
524: assignNewHandle(osc);
525:
526: ClassLoader callersClassLoader = currentLoader();
527:
528: for (int i = 0; i < field_count; i++)
529: {
530: if(dump) dumpElement(" TYPE CODE=");
531: char type_code = (char)this.realInputStream.readByte();
532: if(dump) dumpElement(type_code + "; FIELD NAME=");
533: String field_name = this.realInputStream.readUTF();
534: if(dump) dumpElementln(field_name);
535: String class_name;
536:
537:
538:
539:
540:
541: if (type_code == 'L' || type_code == '[')
542: class_name = (String)readObject();
543: else
544: class_name = String.valueOf(type_code);
545:
546: fields[i] =
547: new ObjectStreamField(field_name, class_name, callersClassLoader);
548: }
549:
550:
552: Class clazz = resolveClass(osc);
553: boolean oldmode = setBlockDataMode(true);
554: osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
555: classLookupTable.put(clazz, osc);
556: setBlockDataMode(oldmode);
557:
558:
559: Class first_nonserial = clazz.getSuperclass();
560:
561:
562:
563:
564: if (first_nonserial == null)
565: first_nonserial = clazz;
566: else
567: while (Serializable.class.isAssignableFrom(first_nonserial))
568: first_nonserial = first_nonserial.getSuperclass();
569:
570: final Class local_constructor_class = first_nonserial;
571:
572: osc.firstNonSerializableParentConstructor =
573: (Constructor)AccessController.doPrivileged(new PrivilegedAction()
574: {
575: public Object run()
576: {
577: try
578: {
579: Constructor c = local_constructor_class.
580: getDeclaredConstructor(new Class[0]);
581: if (Modifier.isPrivate(c.getModifiers()))
582: return null;
583: return c;
584: }
585: catch (NoSuchMethodException e)
586: {
587:
588: return null;
589: }
590: }
591: });
592:
593: osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);
594: osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);
595:
596: ObjectStreamField[] stream_fields = osc.fields;
597: ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;
598: ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];
599:
600: int stream_idx = 0;
601: int real_idx = 0;
602: int map_idx = 0;
603:
604:
609: checkTypeConsistency(name, real_fields, stream_fields);
610: checkTypeConsistency(name, stream_fields, real_fields);
611:
612:
613: while (stream_idx < stream_fields.length
614: || real_idx < real_fields.length)
615: {
616: ObjectStreamField stream_field = null;
617: ObjectStreamField real_field = null;
618:
619: if (stream_idx == stream_fields.length)
620: {
621: real_field = real_fields[real_idx++];
622: }
623: else if (real_idx == real_fields.length)
624: {
625: stream_field = stream_fields[stream_idx++];
626: }
627: else
628: {
629: int comp_val =
630: real_fields[real_idx].compareTo (stream_fields[stream_idx]);
631:
632: if (comp_val < 0)
633: {
634: real_field = real_fields[real_idx++];
635: }
636: else if (comp_val > 0)
637: {
638: stream_field = stream_fields[stream_idx++];
639: }
640: else
641: {
642: stream_field = stream_fields[stream_idx++];
643: real_field = real_fields[real_idx++];
644: if (stream_field.getType() != real_field.getType())
645: throw new InvalidClassException
646: ("invalid field type for " + real_field.getName() +
647: " in class " + name);
648: }
649: }
650:
651:
654: if (map_idx == fieldmapping.length)
655: {
656: ObjectStreamField[] newfieldmapping =
657: new ObjectStreamField[fieldmapping.length + 2];
658: System.arraycopy(fieldmapping, 0,
659: newfieldmapping, 0, fieldmapping.length);
660: fieldmapping = newfieldmapping;
661: }
662: fieldmapping[map_idx++] = stream_field;
663: fieldmapping[map_idx++] = real_field;
664: }
665: osc.fieldMapping = fieldmapping;
666:
667: return osc;
668: }
669:
670:
689: public void defaultReadObject()
690: throws ClassNotFoundException, IOException, NotActiveException
691: {
692: if (this.currentObject == null || this.currentObjectStreamClass == null)
693: throw new NotActiveException("defaultReadObject called by non-active"
694: + " class and/or object");
695:
696: if (fieldsAlreadyRead)
697: throw new NotActiveException("defaultReadObject called but fields "
698: + "already read from stream (by "
699: + "defaultReadObject or readFields)");
700:
701: boolean oldmode = setBlockDataMode(false);
702: readFields(this.currentObject, this.currentObjectStreamClass);
703: setBlockDataMode(oldmode);
704:
705: fieldsAlreadyRead = true;
706: }
707:
708:
709:
727: public void registerValidation(ObjectInputValidation validator,
728: int priority)
729: throws InvalidObjectException, NotActiveException
730: {
731: if (this.currentObject == null || this.currentObjectStreamClass == null)
732: throw new NotActiveException("registerValidation called by non-active "
733: + "class and/or object");
734:
735: if (validator == null)
736: throw new InvalidObjectException("attempt to add a null "
737: + "ObjectInputValidation object");
738:
739: if (currentObjectValidators == null)
740: currentObjectValidators = new TreeSet();
741:
742: currentObjectValidators.add(new ValidatorAndPriority(validator, priority));
743: }
744:
745:
746:
762: protected Class resolveClass(ObjectStreamClass osc)
763: throws ClassNotFoundException, IOException
764: {
765: String name = osc.getName();
766: try
767: {
768: return Class.forName(name, true, currentLoader());
769: }
770: catch(ClassNotFoundException x)
771: {
772: if (name.equals("void"))
773: return Void.TYPE;
774: else if (name.equals("boolean"))
775: return Boolean.TYPE;
776: else if (name.equals("byte"))
777: return Byte.TYPE;
778: else if (name.equals("char"))
779: return Character.TYPE;
780: else if (name.equals("short"))
781: return Short.TYPE;
782: else if (name.equals("int"))
783: return Integer.TYPE;
784: else if (name.equals("long"))
785: return Long.TYPE;
786: else if (name.equals("float"))
787: return Float.TYPE;
788: else if (name.equals("double"))
789: return Double.TYPE;
790: else
791: throw x;
792: }
793: }
794:
795:
799: private ClassLoader currentLoader()
800: {
801: return VMObjectInputStream.currentClassLoader();
802: }
803:
804:
815: private ObjectStreamClass lookupClass(Class clazz)
816: {
817: if (clazz == null)
818: return null;
819:
820: ObjectStreamClass oclazz;
821: oclazz = (ObjectStreamClass)classLookupTable.get(clazz);
822: if (oclazz == null)
823: return ObjectStreamClass.lookup(clazz);
824: else
825: return oclazz;
826: }
827:
828:
840: private ObjectStreamClass[] inputGetObjectStreamClasses(Class clazz)
841: {
842: ObjectStreamClass osc = lookupClass(clazz);
843:
844: if (osc == null)
845: return new ObjectStreamClass[0];
846: else
847: {
848: Vector oscs = new Vector();
849:
850: while (osc != null)
851: {
852: oscs.addElement(osc);
853: osc = osc.getSuper();
854: }
855:
856: int count = oscs.size();
857: ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[count];
858:
859: for (int i = count - 1; i >= 0; i--)
860: sorted_oscs[count - i - 1] = (ObjectStreamClass) oscs.elementAt(i);
861:
862: return sorted_oscs;
863: }
864: }
865:
866:
879: protected Object resolveObject(Object obj) throws IOException
880: {
881: return obj;
882: }
883:
884:
885: protected Class resolveProxyClass(String[] intfs)
886: throws IOException, ClassNotFoundException
887: {
888: ClassLoader cl = currentLoader();
889:
890: Class[] clss = new Class[intfs.length];
891: if(cl == null)
892: {
893: for (int i = 0; i < intfs.length; i++)
894: clss[i] = Class.forName(intfs[i]);
895: cl = ClassLoader.getSystemClassLoader();
896: }
897: else
898: for (int i = 0; i < intfs.length; i++)
899: clss[i] = Class.forName(intfs[i], false, cl);
900: try
901: {
902: return Proxy.getProxyClass(cl, clss);
903: }
904: catch (IllegalArgumentException e)
905: {
906: throw new ClassNotFoundException(null, e);
907: }
908: }
909:
910:
918: protected boolean enableResolveObject (boolean enable)
919: throws SecurityException
920: {
921: if (enable)
922: {
923: SecurityManager sm = System.getSecurityManager();
924: if (sm != null)
925: sm.checkPermission(new SerializablePermission("enableSubstitution"));
926: }
927:
928: boolean old_val = this.resolveEnabled;
929: this.resolveEnabled = enable;
930: return old_val;
931: }
932:
933:
942: protected void readStreamHeader()
943: throws IOException, StreamCorruptedException
944: {
945: if(dump) dumpElement("STREAM MAGIC ");
946: if (this.realInputStream.readShort() != STREAM_MAGIC)
947: throw new StreamCorruptedException("Invalid stream magic number");
948:
949: if(dump) dumpElementln("STREAM VERSION ");
950: if (this.realInputStream.readShort() != STREAM_VERSION)
951: throw new StreamCorruptedException("Invalid stream version number");
952: }
953:
954: public int read() throws IOException
955: {
956: if (this.readDataFromBlock)
957: {
958: if (this.blockDataPosition >= this.blockDataBytes)
959: readNextBlock();
960: return (this.blockData[this.blockDataPosition++] & 0xff);
961: }
962: else
963: return this.realInputStream.read();
964: }
965:
966: public int read(byte[] data, int offset, int length) throws IOException
967: {
968: if (this.readDataFromBlock)
969: {
970: int remain = this.blockDataBytes - this.blockDataPosition;
971: if (remain == 0)
972: {
973: readNextBlock();
974: remain = this.blockDataBytes - this.blockDataPosition;
975: }
976: length = Math.min(length, remain);
977: System.arraycopy(this.blockData, this.blockDataPosition,
978: data, offset, length);
979: this.blockDataPosition += length;
980:
981: return length;
982: }
983: else
984: return this.realInputStream.read(data, offset, length);
985: }
986:
987: public int available() throws IOException
988: {
989: if (this.readDataFromBlock)
990: {
991: if (this.blockDataPosition >= this.blockDataBytes)
992: readNextBlock ();
993:
994: return this.blockDataBytes - this.blockDataPosition;
995: }
996: else
997: return this.realInputStream.available();
998: }
999:
1000: public void close() throws IOException
1001: {
1002: this.realInputStream.close();
1003: }
1004:
1005: public boolean readBoolean() throws IOException
1006: {
1007: boolean switchmode = true;
1008: boolean oldmode = this.readDataFromBlock;
1009: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1010: switchmode = false;
1011: if (switchmode)
1012: oldmode = setBlockDataMode (true);
1013: boolean value = this.dataInputStream.readBoolean ();
1014: if (switchmode)
1015: setBlockDataMode (oldmode);
1016: return value;
1017: }
1018:
1019: public byte readByte() throws IOException
1020: {
1021: boolean switchmode = true;
1022: boolean oldmode = this.readDataFromBlock;
1023: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1024: switchmode = false;
1025: if (switchmode)
1026: oldmode = setBlockDataMode(true);
1027: byte value = this.dataInputStream.readByte();
1028: if (switchmode)
1029: setBlockDataMode(oldmode);
1030: return value;
1031: }
1032:
1033: public int readUnsignedByte() throws IOException
1034: {
1035: boolean switchmode = true;
1036: boolean oldmode = this.readDataFromBlock;
1037: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1038: switchmode = false;
1039: if (switchmode)
1040: oldmode = setBlockDataMode(true);
1041: int value = this.dataInputStream.readUnsignedByte();
1042: if (switchmode)
1043: setBlockDataMode(oldmode);
1044: return value;
1045: }
1046:
1047: public short readShort() throws IOException
1048: {
1049: boolean switchmode = true;
1050: boolean oldmode = this.readDataFromBlock;
1051: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1052: switchmode = false;
1053: if (switchmode)
1054: oldmode = setBlockDataMode(true);
1055: short value = this.dataInputStream.readShort();
1056: if (switchmode)
1057: setBlockDataMode(oldmode);
1058: return value;
1059: }
1060:
1061: public int readUnsignedShort() throws IOException
1062: {
1063: boolean switchmode = true;
1064: boolean oldmode = this.readDataFromBlock;
1065: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1066: switchmode = false;
1067: if (switchmode)
1068: oldmode = setBlockDataMode(true);
1069: int value = this.dataInputStream.readUnsignedShort();
1070: if (switchmode)
1071: setBlockDataMode(oldmode);
1072: return value;
1073: }
1074:
1075: public char readChar() throws IOException
1076: {
1077: boolean switchmode = true;
1078: boolean oldmode = this.readDataFromBlock;
1079: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1080: switchmode = false;
1081: if (switchmode)
1082: oldmode = setBlockDataMode(true);
1083: char value = this.dataInputStream.readChar();
1084: if (switchmode)
1085: setBlockDataMode(oldmode);
1086: return value;
1087: }
1088:
1089: public int readInt() throws IOException
1090: {
1091: boolean switchmode = true;
1092: boolean oldmode = this.readDataFromBlock;
1093: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1094: switchmode = false;
1095: if (switchmode)
1096: oldmode = setBlockDataMode(true);
1097: int value = this.dataInputStream.readInt();
1098: if (switchmode)
1099: setBlockDataMode(oldmode);
1100: return value;
1101: }
1102:
1103: public long readLong() throws IOException
1104: {
1105: boolean switchmode = true;
1106: boolean oldmode = this.readDataFromBlock;
1107: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1108: switchmode = false;
1109: if (switchmode)
1110: oldmode = setBlockDataMode(true);
1111: long value = this.dataInputStream.readLong();
1112: if (switchmode)
1113: setBlockDataMode(oldmode);
1114: return value;
1115: }
1116:
1117: public float readFloat() throws IOException
1118: {
1119: boolean switchmode = true;
1120: boolean oldmode = this.readDataFromBlock;
1121: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1122: switchmode = false;
1123: if (switchmode)
1124: oldmode = setBlockDataMode(true);
1125: float value = this.dataInputStream.readFloat();
1126: if (switchmode)
1127: setBlockDataMode(oldmode);
1128: return value;
1129: }
1130:
1131: public double readDouble() throws IOException
1132: {
1133: boolean switchmode = true;
1134: boolean oldmode = this.readDataFromBlock;
1135: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1136: switchmode = false;
1137: if (switchmode)
1138: oldmode = setBlockDataMode(true);
1139: double value = this.dataInputStream.readDouble();
1140: if (switchmode)
1141: setBlockDataMode(oldmode);
1142: return value;
1143: }
1144:
1145: public void readFully(byte data[]) throws IOException
1146: {
1147: this.dataInputStream.readFully(data);
1148: }
1149:
1150: public void readFully(byte data[], int offset, int size)
1151: throws IOException
1152: {
1153: this.dataInputStream.readFully(data, offset, size);
1154: }
1155:
1156: public int skipBytes(int len) throws IOException
1157: {
1158: return this.dataInputStream.skipBytes(len);
1159: }
1160:
1161:
1165: public String readLine() throws IOException
1166: {
1167: return this.dataInputStream.readLine();
1168: }
1169:
1170: public String readUTF() throws IOException
1171: {
1172: return this.dataInputStream.readUTF();
1173: }
1174:
1175:
1181: public abstract static class GetField
1182: {
1183: public abstract ObjectStreamClass getObjectStreamClass();
1184:
1185: public abstract boolean defaulted(String name)
1186: throws IOException, IllegalArgumentException;
1187:
1188: public abstract boolean get(String name, boolean defvalue)
1189: throws IOException, IllegalArgumentException;
1190:
1191: public abstract char get(String name, char defvalue)
1192: throws IOException, IllegalArgumentException;
1193:
1194: public abstract byte get(String name, byte defvalue)
1195: throws IOException, IllegalArgumentException;
1196:
1197: public abstract short get(String name, short defvalue)
1198: throws IOException, IllegalArgumentException;
1199:
1200: public abstract int get(String name, int defvalue)
1201: throws IOException, IllegalArgumentException;
1202:
1203: public abstract long get(String name, long defvalue)
1204: throws IOException, IllegalArgumentException;
1205:
1206: public abstract float get(String name, float defvalue)
1207: throws IOException, IllegalArgumentException;
1208:
1209: public abstract double get(String name, double defvalue)
1210: throws IOException, IllegalArgumentException;
1211:
1212: public abstract Object get(String name, Object defvalue)
1213: throws IOException, IllegalArgumentException;
1214: }
1215:
1216:
1229: public GetField readFields()
1230: throws IOException, ClassNotFoundException, NotActiveException
1231: {
1232: if (this.currentObject == null || this.currentObjectStreamClass == null)
1233: throw new NotActiveException("readFields called by non-active class and/or object");
1234:
1235: if (prereadFields != null)
1236: return prereadFields;
1237:
1238: if (fieldsAlreadyRead)
1239: throw new NotActiveException("readFields called but fields already read from"
1240: + " stream (by defaultReadObject or readFields)");
1241:
1242: final ObjectStreamClass clazz = this.currentObjectStreamClass;
1243: final byte[] prim_field_data = new byte[clazz.primFieldSize];
1244: final Object[] objs = new Object[clazz.objectFieldCount];
1245:
1246:
1247:
1248:
1249: boolean oldmode = setBlockDataMode(false);
1250: readFully(prim_field_data);
1251: for (int i = 0; i < objs.length; ++ i)
1252: objs[i] = readObject();
1253: setBlockDataMode(oldmode);
1254:
1255: prereadFields = new GetField()
1256: {
1257: public ObjectStreamClass getObjectStreamClass()
1258: {
1259: return clazz;
1260: }
1261:
1262: public boolean defaulted(String name)
1263: throws IOException, IllegalArgumentException
1264: {
1265: ObjectStreamField f = clazz.getField(name);
1266:
1267:
1268: if (f != null)
1269: {
1270:
1273: if (f.isPersistent() && !f.isToSet())
1274: return true;
1275:
1276: return false;
1277: }
1278:
1279:
1282: try
1283: {
1284: return (clazz.forClass().getDeclaredField (name) != null);
1285: }
1286: catch (NoSuchFieldException e)
1287: {
1288: throw new IllegalArgumentException(e);
1289: }
1290: }
1291:
1292: public boolean get(String name, boolean defvalue)
1293: throws IOException, IllegalArgumentException
1294: {
1295: ObjectStreamField field = getField(name, Boolean.TYPE);
1296:
1297: if (field == null)
1298: return defvalue;
1299:
1300: return prim_field_data[field.getOffset()] == 0 ? false : true;
1301: }
1302:
1303: public char get(String name, char defvalue)
1304: throws IOException, IllegalArgumentException
1305: {
1306: ObjectStreamField field = getField(name, Character.TYPE);
1307:
1308: if (field == null)
1309: return defvalue;
1310:
1311: int off = field.getOffset();
1312:
1313: return (char)(((prim_field_data[off++] & 0xFF) << 8)
1314: | (prim_field_data[off] & 0xFF));
1315: }
1316:
1317: public byte get(String name, byte defvalue)
1318: throws IOException, IllegalArgumentException
1319: {
1320: ObjectStreamField field = getField(name, Byte.TYPE);
1321:
1322: if (field == null)
1323: return defvalue;
1324:
1325: return prim_field_data[field.getOffset()];
1326: }
1327:
1328: public short get(String name, short defvalue)
1329: throws IOException, IllegalArgumentException
1330: {
1331: ObjectStreamField field = getField(name, Short.TYPE);
1332:
1333: if (field == null)
1334: return defvalue;
1335:
1336: int off = field.getOffset();
1337:
1338: return (short)(((prim_field_data[off++] & 0xFF) << 8)
1339: | (prim_field_data[off] & 0xFF));
1340: }
1341:
1342: public int get(String name, int defvalue)
1343: throws IOException, IllegalArgumentException
1344: {
1345: ObjectStreamField field = getField(name, Integer.TYPE);
1346:
1347: if (field == null)
1348: return defvalue;
1349:
1350: int off = field.getOffset();
1351:
1352: return ((prim_field_data[off++] & 0xFF) << 24)
1353: | ((prim_field_data[off++] & 0xFF) << 16)
1354: | ((prim_field_data[off++] & 0xFF) << 8)
1355: | (prim_field_data[off] & 0xFF);
1356: }
1357:
1358: public long get(String name, long defvalue)
1359: throws IOException, IllegalArgumentException
1360: {
1361: ObjectStreamField field = getField(name, Long.TYPE);
1362:
1363: if (field == null)
1364: return defvalue;
1365:
1366: int off = field.getOffset();
1367:
1368: return (long)(((prim_field_data[off++] & 0xFFL) << 56)
1369: | ((prim_field_data[off++] & 0xFFL) << 48)
1370: | ((prim_field_data[off++] & 0xFFL) << 40)
1371: | ((prim_field_data[off++] & 0xFFL) << 32)
1372: | ((prim_field_data[off++] & 0xFF) << 24)
1373: | ((prim_field_data[off++] & 0xFF) << 16)
1374: | ((prim_field_data[off++] & 0xFF) << 8)
1375: | (prim_field_data[off] & 0xFF));
1376: }
1377:
1378: public float get(String name, float defvalue)
1379: throws IOException, IllegalArgumentException
1380: {
1381: ObjectStreamField field = getField(name, Float.TYPE);
1382:
1383: if (field == null)
1384: return defvalue;
1385:
1386: int off = field.getOffset();
1387:
1388: return Float.intBitsToFloat(((prim_field_data[off++] & 0xFF) << 24)
1389: | ((prim_field_data[off++] & 0xFF) << 16)
1390: | ((prim_field_data[off++] & 0xFF) << 8)
1391: | (prim_field_data[off] & 0xFF));
1392: }
1393:
1394: public double get(String name, double defvalue)
1395: throws IOException, IllegalArgumentException
1396: {
1397: ObjectStreamField field = getField(name, Double.TYPE);
1398:
1399: if (field == null)
1400: return defvalue;
1401:
1402: int off = field.getOffset();
1403:
1404: return Double.longBitsToDouble
1405: ( (long) (((prim_field_data[off++] & 0xFFL) << 56)
1406: | ((prim_field_data[off++] & 0xFFL) << 48)
1407: | ((prim_field_data[off++] & 0xFFL) << 40)
1408: | ((prim_field_data[off++] & 0xFFL) << 32)
1409: | ((prim_field_data[off++] & 0xFF) << 24)
1410: | ((prim_field_data[off++] & 0xFF) << 16)
1411: | ((prim_field_data[off++] & 0xFF) << 8)
1412: | (prim_field_data[off] & 0xFF)));
1413: }
1414:
1415: public Object get(String name, Object defvalue)
1416: throws IOException, IllegalArgumentException
1417: {
1418: ObjectStreamField field =
1419: getField(name, defvalue == null ? null : defvalue.getClass ());
1420:
1421: if (field == null)
1422: return defvalue;
1423:
1424: return objs[field.getOffset()];
1425: }
1426:
1427: private ObjectStreamField getField(String name, Class type)
1428: throws IllegalArgumentException
1429: {
1430: ObjectStreamField field = clazz.getField(name);
1431: boolean illegal = false;
1432:
1433:
1434: try
1435: {
1436: try
1437: {
1438: Class field_type = field.getType();
1439:
1440: if (type == field_type ||
1441: (type == null && !field_type.isPrimitive()))
1442: {
1443:
1444: return field;
1445: }
1446:
1447: illegal = true;
1448: throw new IllegalArgumentException
1449: ("Field requested is of type "
1450: + field_type.getName()
1451: + ", but requested type was "
1452: + (type == null ? "Object" : type.getName()));
1453: }
1454: catch (NullPointerException _)
1455: {
1456:
1461: }
1462: catch (IllegalArgumentException e)
1463: {
1464: throw e;
1465: }
1466:
1467: return null;
1468: }
1469: finally
1470: {
1471:
1474: if (!illegal && field != null && !field.isToSet() && field.isPersistent())
1475: return null;
1476:
1477:
1480: try
1481: {
1482: Field f = clazz.forClass().getDeclaredField(name);
1483: if (Modifier.isTransient(f.getModifiers()))
1484: throw new IllegalArgumentException
1485: ("no such field (non transient) " + name);
1486: if (field == null && f.getType() != type)
1487: throw new IllegalArgumentException
1488: ("Invalid requested type for field " + name);
1489: }
1490: catch (NoSuchFieldException e)
1491: {
1492: if (field == null)
1493: throw new IllegalArgumentException(e);
1494: }
1495:
1496: }
1497: }
1498: };
1499:
1500: fieldsAlreadyRead = true;
1501: return prereadFields;
1502: }
1503:
1504:
1515: protected ObjectInputStream()
1516: throws IOException, SecurityException
1517: {
1518: SecurityManager sec_man = System.getSecurityManager();
1519: if (sec_man != null)
1520: sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1521: this.useSubclassMethod = true;
1522: }
1523:
1524:
1533: protected Object readObjectOverride()
1534: throws ClassNotFoundException, IOException, OptionalDataException
1535: {
1536: throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");
1537: }
1538:
1539:
1545: private int assignNewHandle(Object obj)
1546: {
1547: this.objectLookupTable.put(new Integer(this.nextOID),
1548: new ObjectIdentityWrapper(obj));
1549: return this.nextOID++;
1550: }
1551:
1552: private Object processResolution(ObjectStreamClass osc, Object obj, int handle)
1553: throws IOException
1554: {
1555: if (osc != null && obj instanceof Serializable)
1556: {
1557: try
1558: {
1559: Method m = osc.readResolveMethod;
1560: if(m != null)
1561: {
1562: obj = m.invoke(obj, new Object[] {});
1563: }
1564: }
1565: catch (IllegalAccessException ignore)
1566: {
1567: }
1568: catch (InvocationTargetException exception)
1569: {
1570: Throwable cause = exception.getCause();
1571: if (cause instanceof ObjectStreamException)
1572: throw (ObjectStreamException) cause;
1573: else if (cause instanceof RuntimeException)
1574: throw (RuntimeException) cause;
1575: else if (cause instanceof Error)
1576: throw (Error) cause;
1577: }
1578: }
1579:
1580: if (this.resolveEnabled)
1581: obj = resolveObject(obj);
1582:
1583: this.objectLookupTable.put(new Integer(handle),
1584: new ObjectIdentityWrapper(obj));
1585:
1586: return obj;
1587: }
1588:
1589: private void clearHandles()
1590: {
1591: this.objectLookupTable.clear();
1592: this.nextOID = baseWireHandle;
1593: }
1594:
1595: private void readNextBlock() throws IOException
1596: {
1597: byte marker = this.realInputStream.readByte();
1598: while (marker == TC_RESET)
1599: {
1600: if(dump) dumpElementln("RESET");
1601: clearHandles();
1602: marker = this.realInputStream.readByte();
1603: }
1604: readNextBlock(marker);
1605: }
1606:
1607: private void readNextBlock(byte marker) throws IOException
1608: {
1609: if (marker == TC_BLOCKDATA)
1610: {
1611: if(dump) dumpElement("BLOCK DATA SIZE=");
1612: this.blockDataBytes = this.realInputStream.readUnsignedByte();
1613: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1614: }
1615: else if (marker == TC_BLOCKDATALONG)
1616: {
1617: if(dump) dumpElement("BLOCK DATA LONG SIZE=");
1618: this.blockDataBytes = this.realInputStream.readInt();
1619: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1620: }
1621: else
1622: {
1623: throw new EOFException("Attempt to read primitive data, but no data block is active.");
1624: }
1625:
1626: if (this.blockData.length < this.blockDataBytes)
1627: this.blockData = new byte[this.blockDataBytes];
1628:
1629: this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
1630: this.blockDataPosition = 0;
1631: }
1632:
1633: private void readArrayElements (Object array, Class clazz)
1634: throws ClassNotFoundException, IOException
1635: {
1636: if (clazz.isPrimitive())
1637: {
1638: if (clazz == Boolean.TYPE)
1639: {
1640: boolean[] cast_array = (boolean[])array;
1641: for (int i=0; i < cast_array.length; i++)
1642: cast_array[i] = this.realInputStream.readBoolean();
1643: return;
1644: }
1645: if (clazz == Byte.TYPE)
1646: {
1647: byte[] cast_array = (byte[])array;
1648: for (int i=0; i < cast_array.length; i++)
1649: cast_array[i] = this.realInputStream.readByte();
1650: return;
1651: }
1652: if (clazz == Character.TYPE)
1653: {
1654: char[] cast_array = (char[])array;
1655: for (int i=0; i < cast_array.length; i++)
1656: cast_array[i] = this.realInputStream.readChar();
1657: return;
1658: }
1659: if (clazz == Double.TYPE)
1660: {
1661: double[] cast_array = (double[])array;
1662: for (int i=0; i < cast_array.length; i++)
1663: cast_array[i] = this.realInputStream.readDouble();
1664: return;
1665: }
1666: if (clazz == Float.TYPE)
1667: {
1668: float[] cast_array = (float[])array;
1669: for (int i=0; i < cast_array.length; i++)
1670: cast_array[i] = this.realInputStream.readFloat();
1671: return;
1672: }
1673: if (clazz == Integer.TYPE)
1674: {
1675: int[] cast_array = (int[])array;
1676: for (int i=0; i < cast_array.length; i++)
1677: cast_array[i] = this.realInputStream.readInt();
1678: return;
1679: }
1680: if (clazz == Long.TYPE)
1681: {
1682: long[] cast_array = (long[])array;
1683: for (int i=0; i < cast_array.length; i++)
1684: cast_array[i] = this.realInputStream.readLong();
1685: return;
1686: }
1687: if (clazz == Short.TYPE)
1688: {
1689: short[] cast_array = (short[])array;
1690: for (int i=0; i < cast_array.length; i++)
1691: cast_array[i] = this.realInputStream.readShort();
1692: return;
1693: }
1694: }
1695: else
1696: {
1697: Object[] cast_array = (Object[])array;
1698: for (int i=0; i < cast_array.length; i++)
1699: cast_array[i] = readObject();
1700: }
1701: }
1702:
1703: private void readFields (Object obj, ObjectStreamClass stream_osc)
1704: throws ClassNotFoundException, IOException
1705: {
1706: ObjectStreamField[] fields = stream_osc.fieldMapping;
1707:
1708: for (int i = 0; i < fields.length; i += 2)
1709: {
1710: ObjectStreamField stream_field = fields[i];
1711: ObjectStreamField real_field = fields[i + 1];
1712: boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
1713: boolean set_value = (real_field != null && real_field.isToSet());
1714: String field_name;
1715: char type;
1716:
1717: if (stream_field != null)
1718: {
1719: field_name = stream_field.getName();
1720: type = stream_field.getTypeCode();
1721: }
1722: else
1723: {
1724: field_name = real_field.getName();
1725: type = real_field.getTypeCode();
1726: }
1727:
1728: switch(type)
1729: {
1730: case 'Z':
1731: {
1732: boolean value =
1733: read_value ? this.realInputStream.readBoolean() : false;
1734: if (dump && read_value && set_value)
1735: dumpElementln(" " + field_name + ": " + value);
1736: if (set_value)
1737: real_field.setBooleanField(obj, value);
1738: break;
1739: }
1740: case 'B':
1741: {
1742: byte value =
1743: read_value ? this.realInputStream.readByte() : 0;
1744: if (dump && read_value && set_value)
1745: dumpElementln(" " + field_name + ": " + value);
1746: if (set_value)
1747: real_field.setByteField(obj, value);
1748: break;
1749: }
1750: case 'C':
1751: {
1752: char value =
1753: read_value ? this.realInputStream.readChar(): 0;
1754: if (dump && read_value && set_value)
1755: dumpElementln(" " + field_name + ": " + value);
1756: if (set_value)
1757: real_field.setCharField(obj, value);
1758: break;
1759: }
1760: case 'D':
1761: {
1762: double value =
1763: read_value ? this.realInputStream.readDouble() : 0;
1764: if (dump && read_value && set_value)
1765: dumpElementln(" " + field_name + ": " + value);
1766: if (set_value)
1767: real_field.setDoubleField(obj, value);
1768: break;
1769: }
1770: case 'F':
1771: {
1772: float value =
1773: read_value ? this.realInputStream.readFloat() : 0;
1774: if (dump && read_value && set_value)
1775: dumpElementln(" " + field_name + ": " + value);
1776: if (set_value)
1777: real_field.setFloatField(obj, value);
1778: break;
1779: }
1780: case 'I':
1781: {
1782: int value =
1783: read_value ? this.realInputStream.readInt() : 0;
1784: if (dump && read_value && set_value)
1785: dumpElementln(" " + field_name + ": " + value);
1786: if (set_value)
1787: real_field.setIntField(obj, value);
1788: break;
1789: }
1790: case 'J':
1791: {
1792: long value =
1793: read_value ? this.realInputStream.readLong() : 0;
1794: if (dump && read_value && set_value)
1795: dumpElementln(" " + field_name + ": " + value);
1796: if (set_value)
1797: real_field.setLongField(obj, value);
1798: break;
1799: }
1800: case 'S':
1801: {
1802: short value =
1803: read_value ? this.realInputStream.readShort() : 0;
1804: if (dump && read_value && set_value)
1805: dumpElementln(" " + field_name + ": " + value);
1806: if (set_value)
1807: real_field.setShortField(obj, value);
1808: break;
1809: }
1810: case 'L':
1811: case '[':
1812: {
1813: Object value =
1814: read_value ? readObject() : null;
1815: if (set_value)
1816: real_field.setObjectField(obj, value);
1817: break;
1818: }
1819: default:
1820: throw new InternalError("Invalid type code: " + type);
1821: }
1822: }
1823: }
1824:
1825:
1826: private boolean setBlockDataMode (boolean on)
1827: {
1828: boolean oldmode = this.readDataFromBlock;
1829: this.readDataFromBlock = on;
1830:
1831: if (on)
1832: this.dataInputStream = this.blockDataInput;
1833: else
1834: this.dataInputStream = this.realInputStream;
1835: return oldmode;
1836: }
1837:
1838:
1839:
1840: private Object newObject (Class real_class, Constructor constructor)
1841: throws ClassNotFoundException, IOException
1842: {
1843: if (constructor == null)
1844: throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
1845: try
1846: {
1847: return VMObjectInputStream.allocateObject(real_class, constructor.getDeclaringClass(), constructor);
1848: }
1849: catch (InstantiationException e)
1850: {
1851: throw (ClassNotFoundException) new ClassNotFoundException
1852: ("Instance of " + real_class + " could not be created").initCause(e);
1853: }
1854: }
1855:
1856:
1857:
1858: private void invokeValidators() throws InvalidObjectException
1859: {
1860: try
1861: {
1862: Iterator it = currentObjectValidators.iterator();
1863: while(it.hasNext())
1864: {
1865: ValidatorAndPriority vap = (ValidatorAndPriority) it.next();
1866: ObjectInputValidation validator = vap.validator;
1867: validator.validateObject();
1868: }
1869: }
1870: finally
1871: {
1872: currentObjectValidators = null;
1873: }
1874: }
1875:
1876: private void callReadMethod (Method readObject, Class klass, Object obj)
1877: throws ClassNotFoundException, IOException
1878: {
1879: try
1880: {
1881: readObject.invoke(obj, new Object[] { this });
1882: }
1883: catch (InvocationTargetException x)
1884: {
1885:
1886: Throwable exception = x.getTargetException();
1887: if (exception instanceof RuntimeException)
1888: throw (RuntimeException) exception;
1889: if (exception instanceof IOException)
1890: throw (IOException) exception;
1891: if (exception instanceof ClassNotFoundException)
1892: throw (ClassNotFoundException) exception;
1893:
1894: throw (IOException) new IOException(
1895: "Exception thrown from readObject() on " + klass).initCause(x);
1896: }
1897: catch (Exception x)
1898: {
1899: throw (IOException) new IOException(
1900: "Failure invoking readObject() on " + klass).initCause(x);
1901: }
1902:
1903:
1904: prereadFields = null;
1905: }
1906:
1907: private static final int BUFFER_SIZE = 1024;
1908:
1909: private DataInputStream realInputStream;
1910: private DataInputStream dataInputStream;
1911: private DataInputStream blockDataInput;
1912: private int blockDataPosition;
1913: private int blockDataBytes;
1914: private byte[] blockData;
1915: private boolean useSubclassMethod;
1916: private int nextOID;
1917: private boolean resolveEnabled;
1918: private Hashtable objectLookupTable;
1919: private Object currentObject;
1920: private ObjectStreamClass currentObjectStreamClass;
1921: private TreeSet currentObjectValidators;
1922: private boolean readDataFromBlock;
1923: private boolean fieldsAlreadyRead;
1924: private Hashtable classLookupTable;
1925: private GetField prereadFields;
1926:
1927: private static boolean dump;
1928:
1929:
1930: private int depth = 0;
1931:
1932: private static final boolean DEBUG = false;
1933:
1934: private void dumpElement (String msg)
1935: {
1936: System.out.print(msg);
1937: }
1938:
1939: private void dumpElementln (String msg)
1940: {
1941: System.out.println(msg);
1942: for (int i = 0; i < depth; i++)
1943: System.out.print (" ");
1944: System.out.print (Thread.currentThread() + ": ");
1945: }
1946:
1947:
1948: private static final class ValidatorAndPriority implements Comparable
1949: {
1950: int priority;
1951: ObjectInputValidation validator;
1952:
1953: ValidatorAndPriority (ObjectInputValidation validator, int priority)
1954: {
1955: this.priority = priority;
1956: this.validator = validator;
1957: }
1958:
1959: public int compareTo (Object o)
1960: {
1961: ValidatorAndPriority vap = (ValidatorAndPriority)o;
1962: return this.priority - vap.priority;
1963: }
1964: }
1965: }