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