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: import ;
58:
59: public class ObjectInputStream extends InputStream
60: implements ObjectInput, ObjectStreamConstants
61: {
62:
76: public ObjectInputStream(InputStream in)
77: throws IOException, StreamCorruptedException
78: {
79: if (DEBUG)
80: {
81: String val = System.getProperty("gcj.dumpobjects");
82: if (dump == false && val != null && !val.equals(""))
83: {
84: dump = true;
85: System.out.println ("Serialization debugging enabled");
86: }
87: else if (dump == true && (val == null || val.equals("")))
88: {
89: dump = false;
90: System.out.println ("Serialization debugging disabled");
91: }
92: }
93:
94: this.resolveEnabled = false;
95: this.blockDataPosition = 0;
96: this.blockDataBytes = 0;
97: this.blockData = new byte[BUFFER_SIZE];
98: this.blockDataInput = new DataInputStream(this);
99: this.realInputStream = new DataInputStream(in);
100: this.nextOID = baseWireHandle;
101: this.objectLookupTable = new Hashtable();
102: this.classLookupTable = new Hashtable();
103: setBlockDataMode(true);
104: readStreamHeader();
105: }
106:
107:
108:
123: public final Object readObject()
124: throws ClassNotFoundException, IOException
125: {
126: if (this.useSubclassMethod)
127: return readObjectOverride();
128:
129: Object ret_val;
130: boolean old_mode = setBlockDataMode(false);
131: byte marker = this.realInputStream.readByte();
132:
133: if (DEBUG)
134: depth += 2;
135:
136: if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
137:
138: try
139: {
140: ret_val = parseContent(marker);
141: }
142: finally
143: {
144: setBlockDataMode(old_mode);
145: if (DEBUG)
146: depth -= 2;
147: }
148:
149: return ret_val;
150: }
151:
152:
163: private Object parseContent(byte marker)
164: throws ClassNotFoundException, IOException
165: {
166: Object ret_val;
167: boolean is_consumed = false;
168:
169: switch (marker)
170: {
171: case TC_ENDBLOCKDATA:
172: {
173: ret_val = null;
174: is_consumed = true;
175: break;
176: }
177:
178: case TC_BLOCKDATA:
179: case TC_BLOCKDATALONG:
180: {
181: if (marker == TC_BLOCKDATALONG)
182: { if(dump) dumpElementln("BLOCKDATALONG"); }
183: else
184: { if(dump) dumpElementln("BLOCKDATA"); }
185: readNextBlock(marker);
186: }
187:
188: case TC_NULL:
189: {
190: if(dump) dumpElementln("NULL");
191: ret_val = null;
192: break;
193: }
194:
195: case TC_REFERENCE:
196: {
197: if(dump) dumpElement("REFERENCE ");
198: Integer oid = new Integer(this.realInputStream.readInt());
199: if(dump) dumpElementln(Integer.toHexString(oid.intValue()));
200: ret_val = ((ObjectIdentityWrapper)
201: this.objectLookupTable.get(oid)).object;
202: break;
203: }
204:
205: case TC_CLASS:
206: {
207: if(dump) dumpElementln("CLASS");
208: ObjectStreamClass osc = (ObjectStreamClass)readObject();
209: Class clazz = osc.forClass();
210: assignNewHandle(clazz);
211: ret_val = clazz;
212: break;
213: }
214:
215: case TC_PROXYCLASSDESC:
216: {
217: if(dump) dumpElementln("PROXYCLASS");
218: int n_intf = this.realInputStream.readInt();
219: String[] intfs = new String[n_intf];
220: for (int i = 0; i < n_intf; i++)
221: {
222: intfs[i] = this.realInputStream.readUTF();
223: }
224:
225: boolean oldmode = setBlockDataMode(true);
226: Class cl = resolveProxyClass(intfs);
227: setBlockDataMode(oldmode);
228:
229: ObjectStreamClass osc = lookupClass(cl);
230: if (osc.firstNonSerializableParentConstructor == null)
231: {
232: osc.realClassIsSerializable = true;
233: osc.fields = osc.fieldMapping = new ObjectStreamField[0];
234: try
235: {
236: osc.firstNonSerializableParentConstructor =
237: Object.class.getConstructor(new Class[0]);
238: }
239: catch (NoSuchMethodException x)
240: {
241: throw (InternalError)
242: new InternalError("Object ctor missing").initCause(x);
243: }
244: }
245: assignNewHandle(osc);
246:
247: if (!is_consumed)
248: {
249: byte b = this.realInputStream.readByte();
250: if (b != TC_ENDBLOCKDATA)
251: throw new IOException("Data annotated to class was not consumed." + b);
252: }
253: else
254: is_consumed = false;
255: ObjectStreamClass superosc = (ObjectStreamClass)readObject();
256: osc.setSuperclass(superosc);
257: ret_val = osc;
258: break;
259: }
260:
261: case TC_CLASSDESC:
262: {
263: ObjectStreamClass osc = readClassDescriptor();
264:
265: if (!is_consumed)
266: {
267: byte b = this.realInputStream.readByte();
268: if (b != TC_ENDBLOCKDATA)
269: throw new IOException("Data annotated to class was not consumed." + b);
270: }
271: else
272: is_consumed = false;
273:
274: osc.setSuperclass ((ObjectStreamClass)readObject());
275: ret_val = osc;
276: break;
277: }
278:
279: case TC_STRING:
280: case TC_LONGSTRING:
281: {
282: if(dump) dumpElement("STRING=");
283: String s = this.realInputStream.readUTF();
284: if(dump) dumpElementln(s);
285: ret_val = processResolution(null, s, assignNewHandle(s));
286: break;
287: }
288:
289: case TC_ARRAY:
290: {
291: if(dump) dumpElementln("ARRAY");
292: ObjectStreamClass osc = (ObjectStreamClass)readObject();
293: Class componentType = osc.forClass().getComponentType();
294: if(dump) dumpElement("ARRAY LENGTH=");
295: int length = this.realInputStream.readInt();
296: if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
297: Object array = Array.newInstance(componentType, length);
298: int handle = assignNewHandle(array);
299: readArrayElements(array, componentType);
300: if(dump)
301: for (int i = 0, len = Array.getLength(array); i < len; i++)
302: dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
303: ret_val = processResolution(null, array, handle);
304: break;
305: }
306:
307: case TC_OBJECT:
308: {
309: if(dump) dumpElementln("OBJECT");
310: ObjectStreamClass osc = (ObjectStreamClass)readObject();
311: Class clazz = osc.forClass();
312:
313: if (!osc.realClassIsSerializable)
314: throw new NotSerializableException
315: (clazz + " is not Serializable, and thus cannot be deserialized.");
316:
317: if (osc.realClassIsExternalizable)
318: {
319: Externalizable obj = osc.newInstance();
320:
321: int handle = assignNewHandle(obj);
322:
323: boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
324:
325: boolean oldmode = this.readDataFromBlock;
326: if (read_from_blocks)
327: setBlockDataMode(true);
328:
329: obj.readExternal(this);
330:
331: if (read_from_blocks)
332: {
333: setBlockDataMode(oldmode);
334: if (!oldmode)
335: if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
336: throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
337: }
338:
339: ret_val = processResolution(osc, obj, handle);
340: break;
341:
342: }
343:
344: Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
345:
346: int handle = assignNewHandle(obj);
347: Object prevObject = this.currentObject;
348: ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
349: TreeSet prevObjectValidators = this.currentObjectValidators;
350:
351: this.currentObject = obj;
352: this.currentObjectValidators = null;
353: ObjectStreamClass[] hierarchy =
354: inputGetObjectStreamClasses(clazz);
355:
356: for (int i = 0; i < hierarchy.length; i++)
357: {
358: this.currentObjectStreamClass = hierarchy[i];
359: if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
360:
361:
362:
363:
364:
365:
366: Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
367: if (readObjectMethod != null)
368: {
369: fieldsAlreadyRead = false;
370: boolean oldmode = setBlockDataMode(true);
371: callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
372: setBlockDataMode(oldmode);
373: }
374: else
375: {
376: readFields(obj, currentObjectStreamClass);
377: }
378:
379: if (this.currentObjectStreamClass.hasWriteMethod())
380: {
381: if(dump) dumpElement("ENDBLOCKDATA? ");
382: try
383: {
384:
385: byte writeMarker = this.realInputStream.readByte();
386: while (writeMarker != TC_ENDBLOCKDATA)
387: {
388: parseContent(writeMarker);
389: writeMarker = this.realInputStream.readByte();
390: }
391: if(dump) dumpElementln("yes");
392: }
393: catch (EOFException e)
394: {
395: throw (IOException) new IOException
396: ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e);
397: }
398: }
399: }
400:
401: this.currentObject = prevObject;
402: this.currentObjectStreamClass = prevObjectStreamClass;
403: ret_val = processResolution(osc, obj, handle);
404: if (currentObjectValidators != null)
405: invokeValidators();
406: this.currentObjectValidators = prevObjectValidators;
407:
408: break;
409: }
410:
411: case TC_RESET:
412: if(dump) dumpElementln("RESET");
413: clearHandles();
414: ret_val = readObject();
415: break;
416:
417: case TC_EXCEPTION:
418: {
419: if(dump) dumpElement("EXCEPTION=");
420: Exception e = (Exception)readObject();
421: if(dump) dumpElementln(e.toString());
422: clearHandles();
423: throw new WriteAbortedException("Exception thrown during writing of stream", e);
424: }
425:
426: default:
427: throw new IOException("Unknown marker on stream: " + marker);
428: }
429: return ret_val;
430: }
431:
432:
445: private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
446: throws InvalidClassException
447: {
448: int nonPrimitive = 0;
449:
450: for (nonPrimitive = 0;
451: nonPrimitive < fields1.length
452: && fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
453: {
454: }
455:
456: if (nonPrimitive == fields1.length)
457: return;
458:
459: int i = 0;
460: ObjectStreamField f1;
461: ObjectStreamField f2;
462:
463: while (i < fields2.length
464: && nonPrimitive < fields1.length)
465: {
466: f1 = fields1[nonPrimitive];
467: f2 = fields2[i];
468:
469: if (!f2.isPrimitive())
470: break;
471:
472: int compVal = f1.getName().compareTo (f2.getName());
473:
474: if (compVal < 0)
475: {
476: nonPrimitive++;
477: }
478: else if (compVal > 0)
479: {
480: i++;
481: }
482: else
483: {
484: throw new InvalidClassException
485: ("invalid field type for " + f2.getName() +
486: " in class " + name);
487: }
488: }
489: }
490:
491:
507: protected ObjectStreamClass readClassDescriptor()
508: throws ClassNotFoundException, IOException
509: {
510: if(dump) dumpElement("CLASSDESC NAME=");
511: String name = this.realInputStream.readUTF();
512: if(dump) dumpElement(name + "; UID=");
513: long uid = this.realInputStream.readLong ();
514: if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");
515: byte flags = this.realInputStream.readByte ();
516: if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");
517: short field_count = this.realInputStream.readShort();
518: if(dump) dumpElementln(Short.toString(field_count));
519: ObjectStreamField[] fields = new ObjectStreamField[field_count];
520: ObjectStreamClass osc = new ObjectStreamClass(name, uid,
521: flags, fields);
522: assignNewHandle(osc);
523:
524: ClassLoader callersClassLoader = currentLoader();
525:
526: for (int i = 0; i < field_count; i++)
527: {
528: if(dump) dumpElement(" TYPE CODE=");
529: char type_code = (char)this.realInputStream.readByte();
530: if(dump) dumpElement(type_code + "; FIELD NAME=");
531: String field_name = this.realInputStream.readUTF();
532: if(dump) dumpElementln(field_name);
533: String class_name;
534:
535:
536:
537:
538:
539: if (type_code == 'L' || type_code == '[')
540: class_name = (String)readObject();
541: else
542: class_name = String.valueOf(type_code);
543:
544: fields[i] =
545: new ObjectStreamField(field_name, class_name, callersClassLoader);
546: }
547:
548:
550: Class clazz = resolveClass(osc);
551: boolean oldmode = setBlockDataMode(true);
552: osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
553: classLookupTable.put(clazz, osc);
554: setBlockDataMode(oldmode);
555:
556:
557:
558: Class first_nonserial = clazz.getSuperclass();
559:
560:
561:
562:
563: if (first_nonserial == null)
564: first_nonserial = clazz;
565: else
566: while (Serializable.class.isAssignableFrom(first_nonserial)
567: || Modifier.isAbstract(first_nonserial.getModifiers()))
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 ignore)
1569: {
1570: }
1571: }
1572:
1573: if (this.resolveEnabled)
1574: obj = resolveObject(obj);
1575:
1576: this.objectLookupTable.put(new Integer(handle),
1577: new ObjectIdentityWrapper(obj));
1578:
1579: return obj;
1580: }
1581:
1582: private void clearHandles()
1583: {
1584: this.objectLookupTable.clear();
1585: this.nextOID = baseWireHandle;
1586: }
1587:
1588: private void readNextBlock() throws IOException
1589: {
1590: readNextBlock(this.realInputStream.readByte());
1591: }
1592:
1593: private void readNextBlock(byte marker) throws IOException
1594: {
1595: if (marker == TC_BLOCKDATA)
1596: {
1597: if(dump) dumpElement("BLOCK DATA SIZE=");
1598: this.blockDataBytes = this.realInputStream.readUnsignedByte();
1599: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1600: }
1601: else if (marker == TC_BLOCKDATALONG)
1602: {
1603: if(dump) dumpElement("BLOCK DATA LONG SIZE=");
1604: this.blockDataBytes = this.realInputStream.readInt();
1605: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1606: }
1607: else
1608: {
1609: throw new EOFException("Attempt to read primitive data, but no data block is active.");
1610: }
1611:
1612: if (this.blockData.length < this.blockDataBytes)
1613: this.blockData = new byte[this.blockDataBytes];
1614:
1615: this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
1616: this.blockDataPosition = 0;
1617: }
1618:
1619: private void readArrayElements (Object array, Class clazz)
1620: throws ClassNotFoundException, IOException
1621: {
1622: if (clazz.isPrimitive())
1623: {
1624: if (clazz == Boolean.TYPE)
1625: {
1626: boolean[] cast_array = (boolean[])array;
1627: for (int i=0; i < cast_array.length; i++)
1628: cast_array[i] = this.realInputStream.readBoolean();
1629: return;
1630: }
1631: if (clazz == Byte.TYPE)
1632: {
1633: byte[] cast_array = (byte[])array;
1634: for (int i=0; i < cast_array.length; i++)
1635: cast_array[i] = this.realInputStream.readByte();
1636: return;
1637: }
1638: if (clazz == Character.TYPE)
1639: {
1640: char[] cast_array = (char[])array;
1641: for (int i=0; i < cast_array.length; i++)
1642: cast_array[i] = this.realInputStream.readChar();
1643: return;
1644: }
1645: if (clazz == Double.TYPE)
1646: {
1647: double[] cast_array = (double[])array;
1648: for (int i=0; i < cast_array.length; i++)
1649: cast_array[i] = this.realInputStream.readDouble();
1650: return;
1651: }
1652: if (clazz == Float.TYPE)
1653: {
1654: float[] cast_array = (float[])array;
1655: for (int i=0; i < cast_array.length; i++)
1656: cast_array[i] = this.realInputStream.readFloat();
1657: return;
1658: }
1659: if (clazz == Integer.TYPE)
1660: {
1661: int[] cast_array = (int[])array;
1662: for (int i=0; i < cast_array.length; i++)
1663: cast_array[i] = this.realInputStream.readInt();
1664: return;
1665: }
1666: if (clazz == Long.TYPE)
1667: {
1668: long[] cast_array = (long[])array;
1669: for (int i=0; i < cast_array.length; i++)
1670: cast_array[i] = this.realInputStream.readLong();
1671: return;
1672: }
1673: if (clazz == Short.TYPE)
1674: {
1675: short[] cast_array = (short[])array;
1676: for (int i=0; i < cast_array.length; i++)
1677: cast_array[i] = this.realInputStream.readShort();
1678: return;
1679: }
1680: }
1681: else
1682: {
1683: Object[] cast_array = (Object[])array;
1684: for (int i=0; i < cast_array.length; i++)
1685: cast_array[i] = readObject();
1686: }
1687: }
1688:
1689: private void readFields (Object obj, ObjectStreamClass stream_osc)
1690: throws ClassNotFoundException, IOException
1691: {
1692: ObjectStreamField[] fields = stream_osc.fieldMapping;
1693:
1694: for (int i = 0; i < fields.length; i += 2)
1695: {
1696: ObjectStreamField stream_field = fields[i];
1697: ObjectStreamField real_field = fields[i + 1];
1698: boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
1699: boolean set_value = (real_field != null && real_field.isToSet());
1700: String field_name;
1701: char type;
1702:
1703: if (stream_field != null)
1704: {
1705: field_name = stream_field.getName();
1706: type = stream_field.getTypeCode();
1707: }
1708: else
1709: {
1710: field_name = real_field.getName();
1711: type = real_field.getTypeCode();
1712: }
1713:
1714: switch(type)
1715: {
1716: case 'Z':
1717: {
1718: boolean value =
1719: read_value ? this.realInputStream.readBoolean() : false;
1720: if (dump && read_value && set_value)
1721: dumpElementln(" " + field_name + ": " + value);
1722: if (set_value)
1723: real_field.setBooleanField(obj, value);
1724: break;
1725: }
1726: case 'B':
1727: {
1728: byte value =
1729: read_value ? this.realInputStream.readByte() : 0;
1730: if (dump && read_value && set_value)
1731: dumpElementln(" " + field_name + ": " + value);
1732: if (set_value)
1733: real_field.setByteField(obj, value);
1734: break;
1735: }
1736: case 'C':
1737: {
1738: char value =
1739: read_value ? this.realInputStream.readChar(): 0;
1740: if (dump && read_value && set_value)
1741: dumpElementln(" " + field_name + ": " + value);
1742: if (set_value)
1743: real_field.setCharField(obj, value);
1744: break;
1745: }
1746: case 'D':
1747: {
1748: double value =
1749: read_value ? this.realInputStream.readDouble() : 0;
1750: if (dump && read_value && set_value)
1751: dumpElementln(" " + field_name + ": " + value);
1752: if (set_value)
1753: real_field.setDoubleField(obj, value);
1754: break;
1755: }
1756: case 'F':
1757: {
1758: float value =
1759: read_value ? this.realInputStream.readFloat() : 0;
1760: if (dump && read_value && set_value)
1761: dumpElementln(" " + field_name + ": " + value);
1762: if (set_value)
1763: real_field.setFloatField(obj, value);
1764: break;
1765: }
1766: case 'I':
1767: {
1768: int value =
1769: read_value ? this.realInputStream.readInt() : 0;
1770: if (dump && read_value && set_value)
1771: dumpElementln(" " + field_name + ": " + value);
1772: if (set_value)
1773: real_field.setIntField(obj, value);
1774: break;
1775: }
1776: case 'J':
1777: {
1778: long value =
1779: read_value ? this.realInputStream.readLong() : 0;
1780: if (dump && read_value && set_value)
1781: dumpElementln(" " + field_name + ": " + value);
1782: if (set_value)
1783: real_field.setLongField(obj, value);
1784: break;
1785: }
1786: case 'S':
1787: {
1788: short value =
1789: read_value ? this.realInputStream.readShort() : 0;
1790: if (dump && read_value && set_value)
1791: dumpElementln(" " + field_name + ": " + value);
1792: if (set_value)
1793: real_field.setShortField(obj, value);
1794: break;
1795: }
1796: case 'L':
1797: case '[':
1798: {
1799: Object value =
1800: read_value ? readObject() : null;
1801: if (set_value)
1802: real_field.setObjectField(obj, value);
1803: break;
1804: }
1805: default:
1806: throw new InternalError("Invalid type code: " + type);
1807: }
1808: }
1809: }
1810:
1811:
1812: private boolean setBlockDataMode (boolean on)
1813: {
1814: boolean oldmode = this.readDataFromBlock;
1815: this.readDataFromBlock = on;
1816:
1817: if (on)
1818: this.dataInputStream = this.blockDataInput;
1819: else
1820: this.dataInputStream = this.realInputStream;
1821: return oldmode;
1822: }
1823:
1824:
1825:
1826: private Object newObject (Class real_class, Constructor constructor)
1827: throws ClassNotFoundException, IOException
1828: {
1829: if (constructor == null)
1830: throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
1831: try
1832: {
1833: return VMObjectInputStream.allocateObject(real_class, constructor.getDeclaringClass(), constructor);
1834: }
1835: catch (InstantiationException e)
1836: {
1837: throw (ClassNotFoundException) new ClassNotFoundException
1838: ("Instance of " + real_class + " could not be created").initCause(e);
1839: }
1840: }
1841:
1842:
1843:
1844: private void invokeValidators() throws InvalidObjectException
1845: {
1846: try
1847: {
1848: Iterator it = currentObjectValidators.iterator();
1849: while(it.hasNext())
1850: {
1851: ValidatorAndPriority vap = (ValidatorAndPriority) it.next();
1852: ObjectInputValidation validator = vap.validator;
1853: validator.validateObject();
1854: }
1855: }
1856: finally
1857: {
1858: currentObjectValidators = null;
1859: }
1860: }
1861:
1862: private void callReadMethod (Method readObject, Class klass, Object obj)
1863: throws ClassNotFoundException, IOException
1864: {
1865: try
1866: {
1867: readObject.invoke(obj, new Object[] { this });
1868: }
1869: catch (InvocationTargetException x)
1870: {
1871:
1872: Throwable exception = x.getTargetException();
1873: if (exception instanceof RuntimeException)
1874: throw (RuntimeException) exception;
1875: if (exception instanceof IOException)
1876: throw (IOException) exception;
1877: if (exception instanceof ClassNotFoundException)
1878: throw (ClassNotFoundException) exception;
1879:
1880: throw (IOException) new IOException(
1881: "Exception thrown from readObject() on " + klass).initCause(x);
1882: }
1883: catch (Exception x)
1884: {
1885: throw (IOException) new IOException(
1886: "Failure invoking readObject() on " + klass).initCause(x);
1887: }
1888:
1889:
1890: prereadFields = null;
1891: }
1892:
1893: private static final int BUFFER_SIZE = 1024;
1894:
1895: private DataInputStream realInputStream;
1896: private DataInputStream dataInputStream;
1897: private DataInputStream blockDataInput;
1898: private int blockDataPosition;
1899: private int blockDataBytes;
1900: private byte[] blockData;
1901: private boolean useSubclassMethod;
1902: private int nextOID;
1903: private boolean resolveEnabled;
1904: private Hashtable objectLookupTable;
1905: private Object currentObject;
1906: private ObjectStreamClass currentObjectStreamClass;
1907: private TreeSet currentObjectValidators;
1908: private boolean readDataFromBlock;
1909: private boolean fieldsAlreadyRead;
1910: private Hashtable classLookupTable;
1911: private GetField prereadFields;
1912:
1913: private static boolean dump;
1914:
1915:
1916: private int depth = 0;
1917:
1918: private static final boolean DEBUG = false;
1919:
1920: private void dumpElement (String msg)
1921: {
1922: System.out.print(msg);
1923: }
1924:
1925: private void dumpElementln (String msg)
1926: {
1927: System.out.println(msg);
1928: for (int i = 0; i < depth; i++)
1929: System.out.print (" ");
1930: System.out.print (Thread.currentThread() + ": ");
1931: }
1932:
1933:
1934: private static final class ValidatorAndPriority implements Comparable
1935: {
1936: int priority;
1937: ObjectInputValidation validator;
1938:
1939: ValidatorAndPriority (ObjectInputValidation validator, int priority)
1940: {
1941: this.priority = priority;
1942: this.validator = validator;
1943: }
1944:
1945: public int compareTo (Object o)
1946: {
1947: ValidatorAndPriority vap = (ValidatorAndPriority)o;
1948: return this.priority - vap.priority;
1949: }
1950: }
1951: }