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