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