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:
560: Class first_nonserial = clazz.getSuperclass();
561:
562:
563:
564:
565: if (first_nonserial == null)
566: first_nonserial = clazz;
567: else
568: while (Serializable.class.isAssignableFrom(first_nonserial)
569: || Modifier.isAbstract(first_nonserial.getModifiers()))
570: first_nonserial = first_nonserial.getSuperclass();
571:
572: final Class local_constructor_class = first_nonserial;
573:
574: osc.firstNonSerializableParentConstructor =
575: (Constructor)AccessController.doPrivileged(new PrivilegedAction()
576: {
577: public Object run()
578: {
579: try
580: {
581: Constructor c = local_constructor_class.
582: getDeclaredConstructor(new Class[0]);
583: if (Modifier.isPrivate(c.getModifiers()))
584: return null;
585: return c;
586: }
587: catch (NoSuchMethodException e)
588: {
589:
590: return null;
591: }
592: }
593: });
594:
595: osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);
596: osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);
597:
598: ObjectStreamField[] stream_fields = osc.fields;
599: ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;
600: ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];
601:
602: int stream_idx = 0;
603: int real_idx = 0;
604: int map_idx = 0;
605:
606:
611: checkTypeConsistency(name, real_fields, stream_fields);
612: checkTypeConsistency(name, stream_fields, real_fields);
613:
614:
615: while (stream_idx < stream_fields.length
616: || real_idx < real_fields.length)
617: {
618: ObjectStreamField stream_field = null;
619: ObjectStreamField real_field = null;
620:
621: if (stream_idx == stream_fields.length)
622: {
623: real_field = real_fields[real_idx++];
624: }
625: else if (real_idx == real_fields.length)
626: {
627: stream_field = stream_fields[stream_idx++];
628: }
629: else
630: {
631: int comp_val =
632: real_fields[real_idx].compareTo (stream_fields[stream_idx]);
633:
634: if (comp_val < 0)
635: {
636: real_field = real_fields[real_idx++];
637: }
638: else if (comp_val > 0)
639: {
640: stream_field = stream_fields[stream_idx++];
641: }
642: else
643: {
644: stream_field = stream_fields[stream_idx++];
645: real_field = real_fields[real_idx++];
646: if (stream_field.getType() != real_field.getType())
647: throw new InvalidClassException
648: ("invalid field type for " + real_field.getName() +
649: " in class " + name);
650: }
651: }
652:
653:
656: if (map_idx == fieldmapping.length)
657: {
658: ObjectStreamField[] newfieldmapping =
659: new ObjectStreamField[fieldmapping.length + 2];
660: System.arraycopy(fieldmapping, 0,
661: newfieldmapping, 0, fieldmapping.length);
662: fieldmapping = newfieldmapping;
663: }
664: fieldmapping[map_idx++] = stream_field;
665: fieldmapping[map_idx++] = real_field;
666: }
667: osc.fieldMapping = fieldmapping;
668:
669: return osc;
670: }
671:
672:
691: public void defaultReadObject()
692: throws ClassNotFoundException, IOException, NotActiveException
693: {
694: if (this.currentObject == null || this.currentObjectStreamClass == null)
695: throw new NotActiveException("defaultReadObject called by non-active"
696: + " class and/or object");
697:
698: if (fieldsAlreadyRead)
699: throw new NotActiveException("defaultReadObject called but fields "
700: + "already read from stream (by "
701: + "defaultReadObject or readFields)");
702:
703: boolean oldmode = setBlockDataMode(false);
704: readFields(this.currentObject, this.currentObjectStreamClass);
705: setBlockDataMode(oldmode);
706:
707: fieldsAlreadyRead = true;
708: }
709:
710:
711:
729: public void registerValidation(ObjectInputValidation validator,
730: int priority)
731: throws InvalidObjectException, NotActiveException
732: {
733: if (this.currentObject == null || this.currentObjectStreamClass == null)
734: throw new NotActiveException("registerValidation called by non-active "
735: + "class and/or object");
736:
737: if (validator == null)
738: throw new InvalidObjectException("attempt to add a null "
739: + "ObjectInputValidation object");
740:
741: if (currentObjectValidators == null)
742: currentObjectValidators = new TreeSet();
743:
744: currentObjectValidators.add(new ValidatorAndPriority(validator, priority));
745: }
746:
747:
748:
764: protected Class resolveClass(ObjectStreamClass osc)
765: throws ClassNotFoundException, IOException
766: {
767: String name = osc.getName();
768: try
769: {
770: return Class.forName(name, true, currentLoader());
771: }
772: catch(ClassNotFoundException x)
773: {
774: if (name.equals("void"))
775: return Void.TYPE;
776: else if (name.equals("boolean"))
777: return Boolean.TYPE;
778: else if (name.equals("byte"))
779: return Byte.TYPE;
780: else if (name.equals("char"))
781: return Character.TYPE;
782: else if (name.equals("short"))
783: return Short.TYPE;
784: else if (name.equals("int"))
785: return Integer.TYPE;
786: else if (name.equals("long"))
787: return Long.TYPE;
788: else if (name.equals("float"))
789: return Float.TYPE;
790: else if (name.equals("double"))
791: return Double.TYPE;
792: else
793: throw x;
794: }
795: }
796:
797:
801: private ClassLoader currentLoader()
802: {
803: return VMObjectInputStream.currentClassLoader();
804: }
805:
806:
817: private ObjectStreamClass lookupClass(Class clazz)
818: {
819: if (clazz == null)
820: return null;
821:
822: ObjectStreamClass oclazz;
823: oclazz = (ObjectStreamClass)classLookupTable.get(clazz);
824: if (oclazz == null)
825: return ObjectStreamClass.lookup(clazz);
826: else
827: return oclazz;
828: }
829:
830:
842: private ObjectStreamClass[] inputGetObjectStreamClasses(Class clazz)
843: {
844: ObjectStreamClass osc = lookupClass(clazz);
845:
846: if (osc == null)
847: return new ObjectStreamClass[0];
848: else
849: {
850: Vector oscs = new Vector();
851:
852: while (osc != null)
853: {
854: oscs.addElement(osc);
855: osc = osc.getSuper();
856: }
857:
858: int count = oscs.size();
859: ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[count];
860:
861: for (int i = count - 1; i >= 0; i--)
862: sorted_oscs[count - i - 1] = (ObjectStreamClass) oscs.elementAt(i);
863:
864: return sorted_oscs;
865: }
866: }
867:
868:
881: protected Object resolveObject(Object obj) throws IOException
882: {
883: return obj;
884: }
885:
886:
887: protected Class resolveProxyClass(String[] intfs)
888: throws IOException, ClassNotFoundException
889: {
890: ClassLoader cl = currentLoader();
891:
892: Class[] clss = new Class[intfs.length];
893: if(cl == null)
894: {
895: for (int i = 0; i < intfs.length; i++)
896: clss[i] = Class.forName(intfs[i]);
897: cl = ClassLoader.getSystemClassLoader();
898: }
899: else
900: for (int i = 0; i < intfs.length; i++)
901: clss[i] = Class.forName(intfs[i], false, cl);
902: try
903: {
904: return Proxy.getProxyClass(cl, clss);
905: }
906: catch (IllegalArgumentException e)
907: {
908: throw new ClassNotFoundException(null, e);
909: }
910: }
911:
912:
920: protected boolean enableResolveObject (boolean enable)
921: throws SecurityException
922: {
923: if (enable)
924: {
925: SecurityManager sm = System.getSecurityManager();
926: if (sm != null)
927: sm.checkPermission(new SerializablePermission("enableSubstitution"));
928: }
929:
930: boolean old_val = this.resolveEnabled;
931: this.resolveEnabled = enable;
932: return old_val;
933: }
934:
935:
944: protected void readStreamHeader()
945: throws IOException, StreamCorruptedException
946: {
947: if(dump) dumpElement("STREAM MAGIC ");
948: if (this.realInputStream.readShort() != STREAM_MAGIC)
949: throw new StreamCorruptedException("Invalid stream magic number");
950:
951: if(dump) dumpElementln("STREAM VERSION ");
952: if (this.realInputStream.readShort() != STREAM_VERSION)
953: throw new StreamCorruptedException("Invalid stream version number");
954: }
955:
956: public int read() throws IOException
957: {
958: if (this.readDataFromBlock)
959: {
960: if (this.blockDataPosition >= this.blockDataBytes)
961: readNextBlock();
962: return (this.blockData[this.blockDataPosition++] & 0xff);
963: }
964: else
965: return this.realInputStream.read();
966: }
967:
968: public int read(byte[] data, int offset, int length) throws IOException
969: {
970: if (this.readDataFromBlock)
971: {
972: int remain = this.blockDataBytes - this.blockDataPosition;
973: if (remain == 0)
974: {
975: readNextBlock();
976: remain = this.blockDataBytes - this.blockDataPosition;
977: }
978: length = Math.min(length, remain);
979: System.arraycopy(this.blockData, this.blockDataPosition,
980: data, offset, length);
981: this.blockDataPosition += length;
982:
983: return length;
984: }
985: else
986: return this.realInputStream.read(data, offset, length);
987: }
988:
989: public int available() throws IOException
990: {
991: if (this.readDataFromBlock)
992: {
993: if (this.blockDataPosition >= this.blockDataBytes)
994: readNextBlock ();
995:
996: return this.blockDataBytes - this.blockDataPosition;
997: }
998: else
999: return this.realInputStream.available();
1000: }
1001:
1002: public void close() throws IOException
1003: {
1004: this.realInputStream.close();
1005: }
1006:
1007: public boolean readBoolean() throws IOException
1008: {
1009: boolean switchmode = true;
1010: boolean oldmode = this.readDataFromBlock;
1011: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1012: switchmode = false;
1013: if (switchmode)
1014: oldmode = setBlockDataMode (true);
1015: boolean value = this.dataInputStream.readBoolean ();
1016: if (switchmode)
1017: setBlockDataMode (oldmode);
1018: return value;
1019: }
1020:
1021: public byte readByte() throws IOException
1022: {
1023: boolean switchmode = true;
1024: boolean oldmode = this.readDataFromBlock;
1025: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1026: switchmode = false;
1027: if (switchmode)
1028: oldmode = setBlockDataMode(true);
1029: byte value = this.dataInputStream.readByte();
1030: if (switchmode)
1031: setBlockDataMode(oldmode);
1032: return value;
1033: }
1034:
1035: public int readUnsignedByte() throws IOException
1036: {
1037: boolean switchmode = true;
1038: boolean oldmode = this.readDataFromBlock;
1039: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1040: switchmode = false;
1041: if (switchmode)
1042: oldmode = setBlockDataMode(true);
1043: int value = this.dataInputStream.readUnsignedByte();
1044: if (switchmode)
1045: setBlockDataMode(oldmode);
1046: return value;
1047: }
1048:
1049: public short readShort() throws IOException
1050: {
1051: boolean switchmode = true;
1052: boolean oldmode = this.readDataFromBlock;
1053: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1054: switchmode = false;
1055: if (switchmode)
1056: oldmode = setBlockDataMode(true);
1057: short value = this.dataInputStream.readShort();
1058: if (switchmode)
1059: setBlockDataMode(oldmode);
1060: return value;
1061: }
1062:
1063: public int readUnsignedShort() throws IOException
1064: {
1065: boolean switchmode = true;
1066: boolean oldmode = this.readDataFromBlock;
1067: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1068: switchmode = false;
1069: if (switchmode)
1070: oldmode = setBlockDataMode(true);
1071: int value = this.dataInputStream.readUnsignedShort();
1072: if (switchmode)
1073: setBlockDataMode(oldmode);
1074: return value;
1075: }
1076:
1077: public char readChar() throws IOException
1078: {
1079: boolean switchmode = true;
1080: boolean oldmode = this.readDataFromBlock;
1081: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1082: switchmode = false;
1083: if (switchmode)
1084: oldmode = setBlockDataMode(true);
1085: char value = this.dataInputStream.readChar();
1086: if (switchmode)
1087: setBlockDataMode(oldmode);
1088: return value;
1089: }
1090:
1091: public int readInt() throws IOException
1092: {
1093: boolean switchmode = true;
1094: boolean oldmode = this.readDataFromBlock;
1095: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1096: switchmode = false;
1097: if (switchmode)
1098: oldmode = setBlockDataMode(true);
1099: int value = this.dataInputStream.readInt();
1100: if (switchmode)
1101: setBlockDataMode(oldmode);
1102: return value;
1103: }
1104:
1105: public long readLong() throws IOException
1106: {
1107: boolean switchmode = true;
1108: boolean oldmode = this.readDataFromBlock;
1109: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1110: switchmode = false;
1111: if (switchmode)
1112: oldmode = setBlockDataMode(true);
1113: long value = this.dataInputStream.readLong();
1114: if (switchmode)
1115: setBlockDataMode(oldmode);
1116: return value;
1117: }
1118:
1119: public float readFloat() throws IOException
1120: {
1121: boolean switchmode = true;
1122: boolean oldmode = this.readDataFromBlock;
1123: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1124: switchmode = false;
1125: if (switchmode)
1126: oldmode = setBlockDataMode(true);
1127: float value = this.dataInputStream.readFloat();
1128: if (switchmode)
1129: setBlockDataMode(oldmode);
1130: return value;
1131: }
1132:
1133: public double readDouble() throws IOException
1134: {
1135: boolean switchmode = true;
1136: boolean oldmode = this.readDataFromBlock;
1137: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1138: switchmode = false;
1139: if (switchmode)
1140: oldmode = setBlockDataMode(true);
1141: double value = this.dataInputStream.readDouble();
1142: if (switchmode)
1143: setBlockDataMode(oldmode);
1144: return value;
1145: }
1146:
1147: public void readFully(byte data[]) throws IOException
1148: {
1149: this.dataInputStream.readFully(data);
1150: }
1151:
1152: public void readFully(byte data[], int offset, int size)
1153: throws IOException
1154: {
1155: this.dataInputStream.readFully(data, offset, size);
1156: }
1157:
1158: public int skipBytes(int len) throws IOException
1159: {
1160: return this.dataInputStream.skipBytes(len);
1161: }
1162:
1163:
1167: public String readLine() throws IOException
1168: {
1169: return this.dataInputStream.readLine();
1170: }
1171:
1172: public String readUTF() throws IOException
1173: {
1174: return this.dataInputStream.readUTF();
1175: }
1176:
1177:
1183: public abstract static class GetField
1184: {
1185: public abstract ObjectStreamClass getObjectStreamClass();
1186:
1187: public abstract boolean defaulted(String name)
1188: throws IOException, IllegalArgumentException;
1189:
1190: public abstract boolean get(String name, boolean defvalue)
1191: throws IOException, IllegalArgumentException;
1192:
1193: public abstract char get(String name, char defvalue)
1194: throws IOException, IllegalArgumentException;
1195:
1196: public abstract byte get(String name, byte defvalue)
1197: throws IOException, IllegalArgumentException;
1198:
1199: public abstract short get(String name, short defvalue)
1200: throws IOException, IllegalArgumentException;
1201:
1202: public abstract int get(String name, int defvalue)
1203: throws IOException, IllegalArgumentException;
1204:
1205: public abstract long get(String name, long defvalue)
1206: throws IOException, IllegalArgumentException;
1207:
1208: public abstract float get(String name, float defvalue)
1209: throws IOException, IllegalArgumentException;
1210:
1211: public abstract double get(String name, double defvalue)
1212: throws IOException, IllegalArgumentException;
1213:
1214: public abstract Object get(String name, Object defvalue)
1215: throws IOException, IllegalArgumentException;
1216: }
1217:
1218:
1231: public GetField readFields()
1232: throws IOException, ClassNotFoundException, NotActiveException
1233: {
1234: if (this.currentObject == null || this.currentObjectStreamClass == null)
1235: throw new NotActiveException("readFields called by non-active class and/or object");
1236:
1237: if (prereadFields != null)
1238: return prereadFields;
1239:
1240: if (fieldsAlreadyRead)
1241: throw new NotActiveException("readFields called but fields already read from"
1242: + " stream (by defaultReadObject or readFields)");
1243:
1244: final ObjectStreamClass clazz = this.currentObjectStreamClass;
1245: final byte[] prim_field_data = new byte[clazz.primFieldSize];
1246: final Object[] objs = new Object[clazz.objectFieldCount];
1247:
1248:
1249:
1250:
1251: boolean oldmode = setBlockDataMode(false);
1252: readFully(prim_field_data);
1253: for (int i = 0; i < objs.length; ++ i)
1254: objs[i] = readObject();
1255: setBlockDataMode(oldmode);
1256:
1257: prereadFields = new GetField()
1258: {
1259: public ObjectStreamClass getObjectStreamClass()
1260: {
1261: return clazz;
1262: }
1263:
1264: public boolean defaulted(String name)
1265: throws IOException, IllegalArgumentException
1266: {
1267: ObjectStreamField f = clazz.getField(name);
1268:
1269:
1270: if (f != null)
1271: {
1272:
1275: if (f.isPersistent() && !f.isToSet())
1276: return true;
1277:
1278: return false;
1279: }
1280:
1281:
1284: try
1285: {
1286: return (clazz.forClass().getDeclaredField (name) != null);
1287: }
1288: catch (NoSuchFieldException e)
1289: {
1290: throw new IllegalArgumentException(e);
1291: }
1292: }
1293:
1294: public boolean get(String name, boolean defvalue)
1295: throws IOException, IllegalArgumentException
1296: {
1297: ObjectStreamField field = getField(name, Boolean.TYPE);
1298:
1299: if (field == null)
1300: return defvalue;
1301:
1302: return prim_field_data[field.getOffset()] == 0 ? false : true;
1303: }
1304:
1305: public char get(String name, char defvalue)
1306: throws IOException, IllegalArgumentException
1307: {
1308: ObjectStreamField field = getField(name, Character.TYPE);
1309:
1310: if (field == null)
1311: return defvalue;
1312:
1313: int off = field.getOffset();
1314:
1315: return (char)(((prim_field_data[off++] & 0xFF) << 8)
1316: | (prim_field_data[off] & 0xFF));
1317: }
1318:
1319: public byte get(String name, byte defvalue)
1320: throws IOException, IllegalArgumentException
1321: {
1322: ObjectStreamField field = getField(name, Byte.TYPE);
1323:
1324: if (field == null)
1325: return defvalue;
1326:
1327: return prim_field_data[field.getOffset()];
1328: }
1329:
1330: public short get(String name, short defvalue)
1331: throws IOException, IllegalArgumentException
1332: {
1333: ObjectStreamField field = getField(name, Short.TYPE);
1334:
1335: if (field == null)
1336: return defvalue;
1337:
1338: int off = field.getOffset();
1339:
1340: return (short)(((prim_field_data[off++] & 0xFF) << 8)
1341: | (prim_field_data[off] & 0xFF));
1342: }
1343:
1344: public int get(String name, int defvalue)
1345: throws IOException, IllegalArgumentException
1346: {
1347: ObjectStreamField field = getField(name, Integer.TYPE);
1348:
1349: if (field == null)
1350: return defvalue;
1351:
1352: int off = field.getOffset();
1353:
1354: return ((prim_field_data[off++] & 0xFF) << 24)
1355: | ((prim_field_data[off++] & 0xFF) << 16)
1356: | ((prim_field_data[off++] & 0xFF) << 8)
1357: | (prim_field_data[off] & 0xFF);
1358: }
1359:
1360: public long get(String name, long defvalue)
1361: throws IOException, IllegalArgumentException
1362: {
1363: ObjectStreamField field = getField(name, Long.TYPE);
1364:
1365: if (field == null)
1366: return defvalue;
1367:
1368: int off = field.getOffset();
1369:
1370: return (long)(((prim_field_data[off++] & 0xFFL) << 56)
1371: | ((prim_field_data[off++] & 0xFFL) << 48)
1372: | ((prim_field_data[off++] & 0xFFL) << 40)
1373: | ((prim_field_data[off++] & 0xFFL) << 32)
1374: | ((prim_field_data[off++] & 0xFF) << 24)
1375: | ((prim_field_data[off++] & 0xFF) << 16)
1376: | ((prim_field_data[off++] & 0xFF) << 8)
1377: | (prim_field_data[off] & 0xFF));
1378: }
1379:
1380: public float get(String name, float defvalue)
1381: throws IOException, IllegalArgumentException
1382: {
1383: ObjectStreamField field = getField(name, Float.TYPE);
1384:
1385: if (field == null)
1386: return defvalue;
1387:
1388: int off = field.getOffset();
1389:
1390: return Float.intBitsToFloat(((prim_field_data[off++] & 0xFF) << 24)
1391: | ((prim_field_data[off++] & 0xFF) << 16)
1392: | ((prim_field_data[off++] & 0xFF) << 8)
1393: | (prim_field_data[off] & 0xFF));
1394: }
1395:
1396: public double get(String name, double defvalue)
1397: throws IOException, IllegalArgumentException
1398: {
1399: ObjectStreamField field = getField(name, Double.TYPE);
1400:
1401: if (field == null)
1402: return defvalue;
1403:
1404: int off = field.getOffset();
1405:
1406: return Double.longBitsToDouble
1407: ( (long) (((prim_field_data[off++] & 0xFFL) << 56)
1408: | ((prim_field_data[off++] & 0xFFL) << 48)
1409: | ((prim_field_data[off++] & 0xFFL) << 40)
1410: | ((prim_field_data[off++] & 0xFFL) << 32)
1411: | ((prim_field_data[off++] & 0xFF) << 24)
1412: | ((prim_field_data[off++] & 0xFF) << 16)
1413: | ((prim_field_data[off++] & 0xFF) << 8)
1414: | (prim_field_data[off] & 0xFF)));
1415: }
1416:
1417: public Object get(String name, Object defvalue)
1418: throws IOException, IllegalArgumentException
1419: {
1420: ObjectStreamField field =
1421: getField(name, defvalue == null ? null : defvalue.getClass ());
1422:
1423: if (field == null)
1424: return defvalue;
1425:
1426: return objs[field.getOffset()];
1427: }
1428:
1429: private ObjectStreamField getField(String name, Class type)
1430: throws IllegalArgumentException
1431: {
1432: ObjectStreamField field = clazz.getField(name);
1433: boolean illegal = false;
1434:
1435:
1436: try
1437: {
1438: try
1439: {
1440: Class field_type = field.getType();
1441:
1442: if (type == field_type ||
1443: (type == null && !field_type.isPrimitive()))
1444: {
1445:
1446: return field;
1447: }
1448:
1449: illegal = true;
1450: throw new IllegalArgumentException
1451: ("Field requested is of type "
1452: + field_type.getName()
1453: + ", but requested type was "
1454: + (type == null ? "Object" : type.getName()));
1455: }
1456: catch (NullPointerException _)
1457: {
1458:
1463: }
1464: catch (IllegalArgumentException e)
1465: {
1466: throw e;
1467: }
1468:
1469: return null;
1470: }
1471: finally
1472: {
1473:
1476: if (!illegal && field != null && !field.isToSet() && field.isPersistent())
1477: return null;
1478:
1479:
1482: try
1483: {
1484: Field f = clazz.forClass().getDeclaredField(name);
1485: if (Modifier.isTransient(f.getModifiers()))
1486: throw new IllegalArgumentException
1487: ("no such field (non transient) " + name);
1488: if (field == null && f.getType() != type)
1489: throw new IllegalArgumentException
1490: ("Invalid requested type for field " + name);
1491: }
1492: catch (NoSuchFieldException e)
1493: {
1494: if (field == null)
1495: throw new IllegalArgumentException(e);
1496: }
1497:
1498: }
1499: }
1500: };
1501:
1502: fieldsAlreadyRead = true;
1503: return prereadFields;
1504: }
1505:
1506:
1517: protected ObjectInputStream()
1518: throws IOException, SecurityException
1519: {
1520: SecurityManager sec_man = System.getSecurityManager();
1521: if (sec_man != null)
1522: sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1523: this.useSubclassMethod = true;
1524: }
1525:
1526:
1535: protected Object readObjectOverride()
1536: throws ClassNotFoundException, IOException, OptionalDataException
1537: {
1538: throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");
1539: }
1540:
1541:
1547: private int assignNewHandle(Object obj)
1548: {
1549: this.objectLookupTable.put(new Integer(this.nextOID),
1550: new ObjectIdentityWrapper(obj));
1551: return this.nextOID++;
1552: }
1553:
1554: private Object processResolution(ObjectStreamClass osc, Object obj, int handle)
1555: throws IOException
1556: {
1557: if (osc != null && obj instanceof Serializable)
1558: {
1559: try
1560: {
1561: Method m = osc.readResolveMethod;
1562: if(m != null)
1563: {
1564: obj = m.invoke(obj, new Object[] {});
1565: }
1566: }
1567: catch (IllegalAccessException ignore)
1568: {
1569: }
1570: catch (InvocationTargetException exception)
1571: {
1572: Throwable cause = exception.getCause();
1573: if (cause instanceof ObjectStreamException)
1574: throw (ObjectStreamException) cause;
1575: else if (cause instanceof RuntimeException)
1576: throw (RuntimeException) cause;
1577: else if (cause instanceof Error)
1578: throw (Error) cause;
1579: }
1580: }
1581:
1582: if (this.resolveEnabled)
1583: obj = resolveObject(obj);
1584:
1585: this.objectLookupTable.put(new Integer(handle),
1586: new ObjectIdentityWrapper(obj));
1587:
1588: return obj;
1589: }
1590:
1591: private void clearHandles()
1592: {
1593: this.objectLookupTable.clear();
1594: this.nextOID = baseWireHandle;
1595: }
1596:
1597: private void readNextBlock() throws IOException
1598: {
1599: readNextBlock(this.realInputStream.readByte());
1600: }
1601:
1602: private void readNextBlock(byte marker) throws IOException
1603: {
1604: if (marker == TC_BLOCKDATA)
1605: {
1606: if(dump) dumpElement("BLOCK DATA SIZE=");
1607: this.blockDataBytes = this.realInputStream.readUnsignedByte();
1608: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1609: }
1610: else if (marker == TC_BLOCKDATALONG)
1611: {
1612: if(dump) dumpElement("BLOCK DATA LONG SIZE=");
1613: this.blockDataBytes = this.realInputStream.readInt();
1614: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1615: }
1616: else
1617: {
1618: throw new EOFException("Attempt to read primitive data, but no data block is active.");
1619: }
1620:
1621: if (this.blockData.length < this.blockDataBytes)
1622: this.blockData = new byte[this.blockDataBytes];
1623:
1624: this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
1625: this.blockDataPosition = 0;
1626: }
1627:
1628: private void readArrayElements (Object array, Class clazz)
1629: throws ClassNotFoundException, IOException
1630: {
1631: if (clazz.isPrimitive())
1632: {
1633: if (clazz == Boolean.TYPE)
1634: {
1635: boolean[] cast_array = (boolean[])array;
1636: for (int i=0; i < cast_array.length; i++)
1637: cast_array[i] = this.realInputStream.readBoolean();
1638: return;
1639: }
1640: if (clazz == Byte.TYPE)
1641: {
1642: byte[] cast_array = (byte[])array;
1643: for (int i=0; i < cast_array.length; i++)
1644: cast_array[i] = this.realInputStream.readByte();
1645: return;
1646: }
1647: if (clazz == Character.TYPE)
1648: {
1649: char[] cast_array = (char[])array;
1650: for (int i=0; i < cast_array.length; i++)
1651: cast_array[i] = this.realInputStream.readChar();
1652: return;
1653: }
1654: if (clazz == Double.TYPE)
1655: {
1656: double[] cast_array = (double[])array;
1657: for (int i=0; i < cast_array.length; i++)
1658: cast_array[i] = this.realInputStream.readDouble();
1659: return;
1660: }
1661: if (clazz == Float.TYPE)
1662: {
1663: float[] cast_array = (float[])array;
1664: for (int i=0; i < cast_array.length; i++)
1665: cast_array[i] = this.realInputStream.readFloat();
1666: return;
1667: }
1668: if (clazz == Integer.TYPE)
1669: {
1670: int[] cast_array = (int[])array;
1671: for (int i=0; i < cast_array.length; i++)
1672: cast_array[i] = this.realInputStream.readInt();
1673: return;
1674: }
1675: if (clazz == Long.TYPE)
1676: {
1677: long[] cast_array = (long[])array;
1678: for (int i=0; i < cast_array.length; i++)
1679: cast_array[i] = this.realInputStream.readLong();
1680: return;
1681: }
1682: if (clazz == Short.TYPE)
1683: {
1684: short[] cast_array = (short[])array;
1685: for (int i=0; i < cast_array.length; i++)
1686: cast_array[i] = this.realInputStream.readShort();
1687: return;
1688: }
1689: }
1690: else
1691: {
1692: Object[] cast_array = (Object[])array;
1693: for (int i=0; i < cast_array.length; i++)
1694: cast_array[i] = readObject();
1695: }
1696: }
1697:
1698: private void readFields (Object obj, ObjectStreamClass stream_osc)
1699: throws ClassNotFoundException, IOException
1700: {
1701: ObjectStreamField[] fields = stream_osc.fieldMapping;
1702:
1703: for (int i = 0; i < fields.length; i += 2)
1704: {
1705: ObjectStreamField stream_field = fields[i];
1706: ObjectStreamField real_field = fields[i + 1];
1707: boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
1708: boolean set_value = (real_field != null && real_field.isToSet());
1709: String field_name;
1710: char type;
1711:
1712: if (stream_field != null)
1713: {
1714: field_name = stream_field.getName();
1715: type = stream_field.getTypeCode();
1716: }
1717: else
1718: {
1719: field_name = real_field.getName();
1720: type = real_field.getTypeCode();
1721: }
1722:
1723: switch(type)
1724: {
1725: case 'Z':
1726: {
1727: boolean value =
1728: read_value ? this.realInputStream.readBoolean() : false;
1729: if (dump && read_value && set_value)
1730: dumpElementln(" " + field_name + ": " + value);
1731: if (set_value)
1732: real_field.setBooleanField(obj, value);
1733: break;
1734: }
1735: case 'B':
1736: {
1737: byte value =
1738: read_value ? this.realInputStream.readByte() : 0;
1739: if (dump && read_value && set_value)
1740: dumpElementln(" " + field_name + ": " + value);
1741: if (set_value)
1742: real_field.setByteField(obj, value);
1743: break;
1744: }
1745: case 'C':
1746: {
1747: char value =
1748: read_value ? this.realInputStream.readChar(): 0;
1749: if (dump && read_value && set_value)
1750: dumpElementln(" " + field_name + ": " + value);
1751: if (set_value)
1752: real_field.setCharField(obj, value);
1753: break;
1754: }
1755: case 'D':
1756: {
1757: double value =
1758: read_value ? this.realInputStream.readDouble() : 0;
1759: if (dump && read_value && set_value)
1760: dumpElementln(" " + field_name + ": " + value);
1761: if (set_value)
1762: real_field.setDoubleField(obj, value);
1763: break;
1764: }
1765: case 'F':
1766: {
1767: float value =
1768: read_value ? this.realInputStream.readFloat() : 0;
1769: if (dump && read_value && set_value)
1770: dumpElementln(" " + field_name + ": " + value);
1771: if (set_value)
1772: real_field.setFloatField(obj, value);
1773: break;
1774: }
1775: case 'I':
1776: {
1777: int value =
1778: read_value ? this.realInputStream.readInt() : 0;
1779: if (dump && read_value && set_value)
1780: dumpElementln(" " + field_name + ": " + value);
1781: if (set_value)
1782: real_field.setIntField(obj, value);
1783: break;
1784: }
1785: case 'J':
1786: {
1787: long value =
1788: read_value ? this.realInputStream.readLong() : 0;
1789: if (dump && read_value && set_value)
1790: dumpElementln(" " + field_name + ": " + value);
1791: if (set_value)
1792: real_field.setLongField(obj, value);
1793: break;
1794: }
1795: case 'S':
1796: {
1797: short value =
1798: read_value ? this.realInputStream.readShort() : 0;
1799: if (dump && read_value && set_value)
1800: dumpElementln(" " + field_name + ": " + value);
1801: if (set_value)
1802: real_field.setShortField(obj, value);
1803: break;
1804: }
1805: case 'L':
1806: case '[':
1807: {
1808: Object value =
1809: read_value ? readObject() : null;
1810: if (set_value)
1811: real_field.setObjectField(obj, value);
1812: break;
1813: }
1814: default:
1815: throw new InternalError("Invalid type code: " + type);
1816: }
1817: }
1818: }
1819:
1820:
1821: private boolean setBlockDataMode (boolean on)
1822: {
1823: boolean oldmode = this.readDataFromBlock;
1824: this.readDataFromBlock = on;
1825:
1826: if (on)
1827: this.dataInputStream = this.blockDataInput;
1828: else
1829: this.dataInputStream = this.realInputStream;
1830: return oldmode;
1831: }
1832:
1833:
1834:
1835: private Object newObject (Class real_class, Constructor constructor)
1836: throws ClassNotFoundException, IOException
1837: {
1838: if (constructor == null)
1839: throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
1840: try
1841: {
1842: return VMObjectInputStream.allocateObject(real_class, constructor.getDeclaringClass(), constructor);
1843: }
1844: catch (InstantiationException e)
1845: {
1846: throw (ClassNotFoundException) new ClassNotFoundException
1847: ("Instance of " + real_class + " could not be created").initCause(e);
1848: }
1849: }
1850:
1851:
1852:
1853: private void invokeValidators() throws InvalidObjectException
1854: {
1855: try
1856: {
1857: Iterator it = currentObjectValidators.iterator();
1858: while(it.hasNext())
1859: {
1860: ValidatorAndPriority vap = (ValidatorAndPriority) it.next();
1861: ObjectInputValidation validator = vap.validator;
1862: validator.validateObject();
1863: }
1864: }
1865: finally
1866: {
1867: currentObjectValidators = null;
1868: }
1869: }
1870:
1871: private void callReadMethod (Method readObject, Class klass, Object obj)
1872: throws ClassNotFoundException, IOException
1873: {
1874: try
1875: {
1876: readObject.invoke(obj, new Object[] { this });
1877: }
1878: catch (InvocationTargetException x)
1879: {
1880:
1881: Throwable exception = x.getTargetException();
1882: if (exception instanceof RuntimeException)
1883: throw (RuntimeException) exception;
1884: if (exception instanceof IOException)
1885: throw (IOException) exception;
1886: if (exception instanceof ClassNotFoundException)
1887: throw (ClassNotFoundException) exception;
1888:
1889: throw (IOException) new IOException(
1890: "Exception thrown from readObject() on " + klass).initCause(x);
1891: }
1892: catch (Exception x)
1893: {
1894: throw (IOException) new IOException(
1895: "Failure invoking readObject() on " + klass).initCause(x);
1896: }
1897:
1898:
1899: prereadFields = null;
1900: }
1901:
1902: private static final int BUFFER_SIZE = 1024;
1903:
1904: private DataInputStream realInputStream;
1905: private DataInputStream dataInputStream;
1906: private DataInputStream blockDataInput;
1907: private int blockDataPosition;
1908: private int blockDataBytes;
1909: private byte[] blockData;
1910: private boolean useSubclassMethod;
1911: private int nextOID;
1912: private boolean resolveEnabled;
1913: private Hashtable objectLookupTable;
1914: private Object currentObject;
1915: private ObjectStreamClass currentObjectStreamClass;
1916: private TreeSet currentObjectValidators;
1917: private boolean readDataFromBlock;
1918: private boolean fieldsAlreadyRead;
1919: private Hashtable classLookupTable;
1920: private GetField prereadFields;
1921:
1922: private static boolean dump;
1923:
1924:
1925: private int depth = 0;
1926:
1927: private static final boolean DEBUG = false;
1928:
1929: private void dumpElement (String msg)
1930: {
1931: System.out.print(msg);
1932: }
1933:
1934: private void dumpElementln (String msg)
1935: {
1936: System.out.println(msg);
1937: for (int i = 0; i < depth; i++)
1938: System.out.print (" ");
1939: System.out.print (Thread.currentThread() + ": ");
1940: }
1941:
1942:
1943: private static final class ValidatorAndPriority implements Comparable
1944: {
1945: int priority;
1946: ObjectInputValidation validator;
1947:
1948: ValidatorAndPriority (ObjectInputValidation validator, int priority)
1949: {
1950: this.priority = priority;
1951: this.validator = validator;
1952: }
1953:
1954: public int compareTo (Object o)
1955: {
1956: ValidatorAndPriority vap = (ValidatorAndPriority)o;
1957: return this.priority - vap.priority;
1958: }
1959: }
1960: }