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: import ;
58: import ;
59:
60:
67: public class ObjectInputStream extends InputStream
68: implements ObjectInput, ObjectStreamConstants
69: {
70:
84: public ObjectInputStream(InputStream in)
85: throws IOException, StreamCorruptedException
86: {
87: if (DEBUG)
88: {
89: String val = System.getProperty("gcj.dumpobjects");
90: if (dump == false && val != null && !val.equals(""))
91: {
92: dump = true;
93: System.out.println ("Serialization debugging enabled");
94: }
95: else if (dump == true && (val == null || val.equals("")))
96: {
97: dump = false;
98: System.out.println ("Serialization debugging disabled");
99: }
100: }
101:
102: this.resolveEnabled = false;
103: this.blockDataPosition = 0;
104: this.blockDataBytes = 0;
105: this.blockData = new byte[BUFFER_SIZE];
106: this.blockDataInput = new DataInputStream(this);
107: this.realInputStream = new DataInputStream(in);
108: this.nextOID = baseWireHandle;
109: handles = new HashMap<Integer,Pair<Boolean,Object>>();
110: this.classLookupTable = new Hashtable<Class,ObjectStreamClass>();
111: setBlockDataMode(true);
112: readStreamHeader();
113: }
114:
115:
116:
134: public final Object readObject()
135: throws ClassNotFoundException, IOException
136: {
137: return readObject(true);
138: }
139:
140:
172: public Object readUnshared()
173: throws IOException, ClassNotFoundException
174: {
175: return readObject(false);
176: }
177:
178:
198: private final Object readObject(boolean shared)
199: throws ClassNotFoundException, IOException
200: {
201: if (this.useSubclassMethod)
202: return readObjectOverride();
203:
204: Object ret_val;
205: boolean old_mode = setBlockDataMode(false);
206: byte marker = this.realInputStream.readByte();
207:
208: if (DEBUG)
209: depth += 2;
210:
211: if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
212:
213: try
214: {
215: ret_val = parseContent(marker, shared);
216: }
217: finally
218: {
219: setBlockDataMode(old_mode);
220: if (DEBUG)
221: depth -= 2;
222: }
223:
224: return ret_val;
225: }
226:
227:
240: private Object parseContent(byte marker, boolean shared)
241: throws ClassNotFoundException, IOException
242: {
243: Object ret_val;
244: boolean is_consumed = false;
245:
246: switch (marker)
247: {
248: case TC_ENDBLOCKDATA:
249: {
250: ret_val = null;
251: is_consumed = true;
252: break;
253: }
254:
255: case TC_BLOCKDATA:
256: case TC_BLOCKDATALONG:
257: {
258: if (marker == TC_BLOCKDATALONG)
259: { if(dump) dumpElementln("BLOCKDATALONG"); }
260: else
261: { if(dump) dumpElementln("BLOCKDATA"); }
262: readNextBlock(marker);
263: }
264:
265: case TC_NULL:
266: {
267: if(dump) dumpElementln("NULL");
268: ret_val = null;
269: break;
270: }
271:
272: case TC_REFERENCE:
273: {
274: if(dump) dumpElement("REFERENCE ");
275: int oid = realInputStream.readInt();
276: if(dump) dumpElementln(Integer.toHexString(oid));
277: ret_val = lookupHandle(oid);
278: if (!shared)
279: throw new
280: InvalidObjectException("References can not be read unshared.");
281: break;
282: }
283:
284: case TC_CLASS:
285: {
286: if(dump) dumpElementln("CLASS");
287: ObjectStreamClass osc = (ObjectStreamClass)readObject();
288: Class clazz = osc.forClass();
289: assignNewHandle(clazz,shared);
290: ret_val = clazz;
291: break;
292: }
293:
294: case TC_PROXYCLASSDESC:
295: {
296: if(dump) dumpElementln("PROXYCLASS");
297: int n_intf = this.realInputStream.readInt();
298: String[] intfs = new String[n_intf];
299: for (int i = 0; i < n_intf; i++)
300: {
301: intfs[i] = this.realInputStream.readUTF();
302: }
303:
304: boolean oldmode = setBlockDataMode(true);
305: Class cl = resolveProxyClass(intfs);
306: setBlockDataMode(oldmode);
307:
308: ObjectStreamClass osc = lookupClass(cl);
309: if (osc.firstNonSerializableParentConstructor == null)
310: {
311: osc.realClassIsSerializable = true;
312: osc.fields = osc.fieldMapping = new ObjectStreamField[0];
313: try
314: {
315: osc.firstNonSerializableParentConstructor =
316: Object.class.getConstructor(new Class[0]);
317: }
318: catch (NoSuchMethodException x)
319: {
320: throw (InternalError)
321: new InternalError("Object ctor missing").initCause(x);
322: }
323: }
324: assignNewHandle(osc,shared);
325:
326: if (!is_consumed)
327: {
328: byte b = this.realInputStream.readByte();
329: if (b != TC_ENDBLOCKDATA)
330: throw new IOException("Data annotated to class was not consumed." + b);
331: }
332: else
333: is_consumed = false;
334: ObjectStreamClass superosc = (ObjectStreamClass)readObject();
335: osc.setSuperclass(superosc);
336: ret_val = osc;
337: break;
338: }
339:
340: case TC_CLASSDESC:
341: {
342: ObjectStreamClass osc = readClassDescriptor();
343:
344: if (!is_consumed)
345: {
346: byte b = this.realInputStream.readByte();
347: if (b != TC_ENDBLOCKDATA)
348: throw new IOException("Data annotated to class was not consumed." + b);
349: }
350: else
351: is_consumed = false;
352:
353: osc.setSuperclass ((ObjectStreamClass)readObject());
354: ret_val = osc;
355: break;
356: }
357:
358: case TC_STRING:
359: case TC_LONGSTRING:
360: {
361: if(dump) dumpElement("STRING=");
362: String s = this.realInputStream.readUTF();
363: if(dump) dumpElementln(s);
364: ret_val = processResolution(null, s, assignNewHandle(s,shared),
365: shared);
366: break;
367: }
368:
369: case TC_ARRAY:
370: {
371: if(dump) dumpElementln("ARRAY");
372: ObjectStreamClass osc = (ObjectStreamClass)readObject();
373: Class componentType = osc.forClass().getComponentType();
374: if(dump) dumpElement("ARRAY LENGTH=");
375: int length = this.realInputStream.readInt();
376: if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
377: Object array = Array.newInstance(componentType, length);
378: int handle = assignNewHandle(array,shared);
379: readArrayElements(array, componentType);
380: if(dump)
381: for (int i = 0, len = Array.getLength(array); i < len; i++)
382: dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
383: ret_val = processResolution(null, array, handle, shared);
384: break;
385: }
386:
387: case TC_OBJECT:
388: {
389: if(dump) dumpElementln("OBJECT");
390: ObjectStreamClass osc = (ObjectStreamClass)readObject();
391: Class clazz = osc.forClass();
392:
393: if (!osc.realClassIsSerializable)
394: throw new NotSerializableException
395: (clazz + " is not Serializable, and thus cannot be deserialized.");
396:
397: if (osc.realClassIsExternalizable)
398: {
399: Externalizable obj = osc.newInstance();
400:
401: int handle = assignNewHandle(obj,shared);
402:
403: boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
404:
405: boolean oldmode = this.readDataFromBlock;
406: if (read_from_blocks)
407: setBlockDataMode(true);
408:
409: obj.readExternal(this);
410:
411: if (read_from_blocks)
412: {
413: setBlockDataMode(oldmode);
414: if (!oldmode)
415: if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
416: throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
417: }
418:
419: ret_val = processResolution(osc, obj, handle,shared);
420: break;
421:
422: }
423:
424: Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
425:
426: int handle = assignNewHandle(obj,shared);
427: Object prevObject = this.currentObject;
428: ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
429: TreeSet<ValidatorAndPriority> prevObjectValidators =
430: this.currentObjectValidators;
431:
432: this.currentObject = obj;
433: this.currentObjectValidators = null;
434: ObjectStreamClass[] hierarchy = hierarchy(clazz);
435:
436: for (int i = 0; i < hierarchy.length; i++)
437: {
438: this.currentObjectStreamClass = hierarchy[i];
439: if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
440:
441:
442:
443:
444:
445:
446: Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
447: if (readObjectMethod != null)
448: {
449: fieldsAlreadyRead = false;
450: boolean oldmode = setBlockDataMode(true);
451: callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
452: setBlockDataMode(oldmode);
453: }
454: else
455: {
456: readFields(obj, currentObjectStreamClass);
457: }
458:
459: if (this.currentObjectStreamClass.hasWriteMethod())
460: {
461: if(dump) dumpElement("ENDBLOCKDATA? ");
462: try
463: {
464:
465: byte writeMarker = this.realInputStream.readByte();
466: while (writeMarker != TC_ENDBLOCKDATA)
467: {
468: parseContent(writeMarker, shared);
469: writeMarker = this.realInputStream.readByte();
470: }
471: if(dump) dumpElementln("yes");
472: }
473: catch (EOFException e)
474: {
475: throw (IOException) new IOException
476: ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e);
477: }
478: }
479: }
480:
481: this.currentObject = prevObject;
482: this.currentObjectStreamClass = prevObjectStreamClass;
483: ret_val = processResolution(osc, obj, handle, shared);
484: if (currentObjectValidators != null)
485: invokeValidators();
486: this.currentObjectValidators = prevObjectValidators;
487:
488: break;
489: }
490:
491: case TC_RESET:
492: if(dump) dumpElementln("RESET");
493: clearHandles();
494: ret_val = readObject();
495: break;
496:
497: case TC_EXCEPTION:
498: {
499: if(dump) dumpElement("EXCEPTION=");
500: Exception e = (Exception)readObject();
501: if(dump) dumpElementln(e.toString());
502: clearHandles();
503: throw new WriteAbortedException("Exception thrown during writing of stream", e);
504: }
505:
506: case TC_ENUM:
507: {
508:
509: if (dump)
510: dumpElementln("ENUM=");
511: ObjectStreamClass osc = (ObjectStreamClass) readObject();
512: String constantName = (String) readObject();
513: if (dump)
514: dumpElementln("CONSTANT NAME = " + constantName);
515: Class clazz = osc.forClass();
516: Enum instance = Enum.valueOf(clazz, constantName);
517: assignNewHandle(instance,shared);
518: ret_val = instance;
519: break;
520: }
521:
522: default:
523: throw new IOException("Unknown marker on stream: " + marker);
524: }
525: return ret_val;
526: }
527:
528:
541: private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
542: throws InvalidClassException
543: {
544: int nonPrimitive = 0;
545:
546: for (nonPrimitive = 0;
547: nonPrimitive < fields1.length
548: && fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
549: {
550: }
551:
552: if (nonPrimitive == fields1.length)
553: return;
554:
555: int i = 0;
556: ObjectStreamField f1;
557: ObjectStreamField f2;
558:
559: while (i < fields2.length
560: && nonPrimitive < fields1.length)
561: {
562: f1 = fields1[nonPrimitive];
563: f2 = fields2[i];
564:
565: if (!f2.isPrimitive())
566: break;
567:
568: int compVal = f1.getName().compareTo (f2.getName());
569:
570: if (compVal < 0)
571: {
572: nonPrimitive++;
573: }
574: else if (compVal > 0)
575: {
576: i++;
577: }
578: else
579: {
580: throw new InvalidClassException
581: ("invalid field type for " + f2.getName() +
582: " in class " + name);
583: }
584: }
585: }
586:
587:
603: protected ObjectStreamClass readClassDescriptor()
604: throws ClassNotFoundException, IOException
605: {
606: if(dump) dumpElement("CLASSDESC NAME=");
607: String name = this.realInputStream.readUTF();
608: if(dump) dumpElement(name + "; UID=");
609: long uid = this.realInputStream.readLong ();
610: if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");
611: byte flags = this.realInputStream.readByte ();
612: if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");
613: short field_count = this.realInputStream.readShort();
614: if(dump) dumpElementln(Short.toString(field_count));
615: ObjectStreamField[] fields = new ObjectStreamField[field_count];
616: ObjectStreamClass osc = new ObjectStreamClass(name, uid,
617: flags, fields);
618: assignNewHandle(osc,true);
619:
620: for (int i = 0; i < field_count; i++)
621: {
622: if(dump) dumpElement(" TYPE CODE=");
623: char type_code = (char)this.realInputStream.readByte();
624: if(dump) dumpElement(type_code + "; FIELD NAME=");
625: String field_name = this.realInputStream.readUTF();
626: if(dump) dumpElementln(field_name);
627: String class_name;
628:
629:
630:
631:
632:
633: if (type_code == 'L' || type_code == '[')
634: class_name = (String)readObject();
635: else
636: class_name = String.valueOf(type_code);
637:
638: fields[i] =
639: new ObjectStreamField(field_name, class_name);
640: }
641:
642:
644: Class clazz = resolveClass(osc);
645: ClassLoader loader = clazz.getClassLoader();
646: for (int i = 0; i < field_count; i++)
647: {
648: fields[i].resolveType(loader);
649: }
650: boolean oldmode = setBlockDataMode(true);
651: osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
652: classLookupTable.put(clazz, osc);
653: setBlockDataMode(oldmode);
654:
655:
656: Class first_nonserial = clazz.getSuperclass();
657:
658:
659:
660:
661: if (first_nonserial == null)
662: first_nonserial = clazz;
663: else
664: while (Serializable.class.isAssignableFrom(first_nonserial))
665: first_nonserial = first_nonserial.getSuperclass();
666:
667: final Class local_constructor_class = first_nonserial;
668:
669: osc.firstNonSerializableParentConstructor =
670: (Constructor)AccessController.doPrivileged(new PrivilegedAction()
671: {
672: public Object run()
673: {
674: try
675: {
676: Constructor c = local_constructor_class.
677: getDeclaredConstructor(new Class[0]);
678: if (Modifier.isPrivate(c.getModifiers()))
679: return null;
680: return c;
681: }
682: catch (NoSuchMethodException e)
683: {
684:
685: return null;
686: }
687: }
688: });
689:
690: osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);
691: osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);
692:
693: ObjectStreamField[] stream_fields = osc.fields;
694: ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;
695: ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];
696:
697: int stream_idx = 0;
698: int real_idx = 0;
699: int map_idx = 0;
700:
701:
706: checkTypeConsistency(name, real_fields, stream_fields);
707: checkTypeConsistency(name, stream_fields, real_fields);
708:
709:
710: while (stream_idx < stream_fields.length
711: || real_idx < real_fields.length)
712: {
713: ObjectStreamField stream_field = null;
714: ObjectStreamField real_field = null;
715:
716: if (stream_idx == stream_fields.length)
717: {
718: real_field = real_fields[real_idx++];
719: }
720: else if (real_idx == real_fields.length)
721: {
722: stream_field = stream_fields[stream_idx++];
723: }
724: else
725: {
726: int comp_val =
727: real_fields[real_idx].compareTo (stream_fields[stream_idx]);
728:
729: if (comp_val < 0)
730: {
731: real_field = real_fields[real_idx++];
732: }
733: else if (comp_val > 0)
734: {
735: stream_field = stream_fields[stream_idx++];
736: }
737: else
738: {
739: stream_field = stream_fields[stream_idx++];
740: real_field = real_fields[real_idx++];
741: if (stream_field.getType() != real_field.getType())
742: throw new InvalidClassException
743: ("invalid field type for " + real_field.getName() +
744: " in class " + name);
745: }
746: }
747:
748:
751: if (map_idx == fieldmapping.length)
752: {
753: ObjectStreamField[] newfieldmapping =
754: new ObjectStreamField[fieldmapping.length + 2];
755: System.arraycopy(fieldmapping, 0,
756: newfieldmapping, 0, fieldmapping.length);
757: fieldmapping = newfieldmapping;
758: }
759: fieldmapping[map_idx++] = stream_field;
760: fieldmapping[map_idx++] = real_field;
761: }
762: osc.fieldMapping = fieldmapping;
763:
764: return osc;
765: }
766:
767:
786: public void defaultReadObject()
787: throws ClassNotFoundException, IOException, NotActiveException
788: {
789: if (this.currentObject == null || this.currentObjectStreamClass == null)
790: throw new NotActiveException("defaultReadObject called by non-active"
791: + " class and/or object");
792:
793: if (fieldsAlreadyRead)
794: throw new NotActiveException("defaultReadObject called but fields "
795: + "already read from stream (by "
796: + "defaultReadObject or readFields)");
797:
798: boolean oldmode = setBlockDataMode(false);
799: readFields(this.currentObject, this.currentObjectStreamClass);
800: setBlockDataMode(oldmode);
801:
802: fieldsAlreadyRead = true;
803: }
804:
805:
806:
824: public void registerValidation(ObjectInputValidation validator,
825: int priority)
826: throws InvalidObjectException, NotActiveException
827: {
828: if (this.currentObject == null || this.currentObjectStreamClass == null)
829: throw new NotActiveException("registerValidation called by non-active "
830: + "class and/or object");
831:
832: if (validator == null)
833: throw new InvalidObjectException("attempt to add a null "
834: + "ObjectInputValidation object");
835:
836: if (currentObjectValidators == null)
837: currentObjectValidators = new TreeSet<ValidatorAndPriority>();
838:
839: currentObjectValidators.add(new ValidatorAndPriority(validator, priority));
840: }
841:
842:
843:
859: protected Class<?> resolveClass(ObjectStreamClass osc)
860: throws ClassNotFoundException, IOException
861: {
862: String name = osc.getName();
863: try
864: {
865: return Class.forName(name, true, currentLoader());
866: }
867: catch(ClassNotFoundException x)
868: {
869: if (name.equals("void"))
870: return Void.TYPE;
871: else if (name.equals("boolean"))
872: return Boolean.TYPE;
873: else if (name.equals("byte"))
874: return Byte.TYPE;
875: else if (name.equals("char"))
876: return Character.TYPE;
877: else if (name.equals("short"))
878: return Short.TYPE;
879: else if (name.equals("int"))
880: return Integer.TYPE;
881: else if (name.equals("long"))
882: return Long.TYPE;
883: else if (name.equals("float"))
884: return Float.TYPE;
885: else if (name.equals("double"))
886: return Double.TYPE;
887: else
888: throw x;
889: }
890: }
891:
892:
896: private ClassLoader currentLoader()
897: {
898: return VMStackWalker.firstNonNullClassLoader();
899: }
900:
901:
912: private ObjectStreamClass lookupClass(Class clazz)
913: {
914: if (clazz == null)
915: return null;
916:
917: ObjectStreamClass oclazz;
918: oclazz = (ObjectStreamClass)classLookupTable.get(clazz);
919: if (oclazz == null)
920: return ObjectStreamClass.lookup(clazz);
921: else
922: return oclazz;
923: }
924:
925:
935: private ObjectStreamClass[] hierarchy(Class clazz)
936: {
937: ObjectStreamClass osc = lookupClass(clazz);
938:
939: return osc == null ? new ObjectStreamClass[0] : osc.hierarchy();
940: }
941:
942:
955: protected Object resolveObject(Object obj) throws IOException
956: {
957: return obj;
958: }
959:
960:
961: protected Class<?> resolveProxyClass(String[] intfs)
962: throws IOException, ClassNotFoundException
963: {
964: ClassLoader cl = currentLoader();
965:
966: Class<?>[] clss = new Class<?>[intfs.length];
967: if(cl == null)
968: {
969: for (int i = 0; i < intfs.length; i++)
970: clss[i] = Class.forName(intfs[i]);
971: cl = ClassLoader.getSystemClassLoader();
972: }
973: else
974: for (int i = 0; i < intfs.length; i++)
975: clss[i] = Class.forName(intfs[i], false, cl);
976: try
977: {
978: return Proxy.getProxyClass(cl, clss);
979: }
980: catch (IllegalArgumentException e)
981: {
982: throw new ClassNotFoundException(null, e);
983: }
984: }
985:
986:
994: protected boolean enableResolveObject (boolean enable)
995: throws SecurityException
996: {
997: if (enable)
998: {
999: SecurityManager sm = System.getSecurityManager();
1000: if (sm != null)
1001: sm.checkPermission(new SerializablePermission("enableSubstitution"));
1002: }
1003:
1004: boolean old_val = this.resolveEnabled;
1005: this.resolveEnabled = enable;
1006: return old_val;
1007: }
1008:
1009:
1018: protected void readStreamHeader()
1019: throws IOException, StreamCorruptedException
1020: {
1021: if(dump) dumpElement("STREAM MAGIC ");
1022: if (this.realInputStream.readShort() != STREAM_MAGIC)
1023: throw new StreamCorruptedException("Invalid stream magic number");
1024:
1025: if(dump) dumpElementln("STREAM VERSION ");
1026: if (this.realInputStream.readShort() != STREAM_VERSION)
1027: throw new StreamCorruptedException("Invalid stream version number");
1028: }
1029:
1030: public int read() throws IOException
1031: {
1032: if (this.readDataFromBlock)
1033: {
1034: if (this.blockDataPosition >= this.blockDataBytes)
1035: readNextBlock();
1036: return (this.blockData[this.blockDataPosition++] & 0xff);
1037: }
1038: else
1039: return this.realInputStream.read();
1040: }
1041:
1042: public int read(byte[] data, int offset, int length) throws IOException
1043: {
1044: if (this.readDataFromBlock)
1045: {
1046: int remain = this.blockDataBytes - this.blockDataPosition;
1047: if (remain == 0)
1048: {
1049: readNextBlock();
1050: remain = this.blockDataBytes - this.blockDataPosition;
1051: }
1052: length = Math.min(length, remain);
1053: System.arraycopy(this.blockData, this.blockDataPosition,
1054: data, offset, length);
1055: this.blockDataPosition += length;
1056:
1057: return length;
1058: }
1059: else
1060: return this.realInputStream.read(data, offset, length);
1061: }
1062:
1063: public int available() throws IOException
1064: {
1065: if (this.readDataFromBlock)
1066: {
1067: if (this.blockDataPosition >= this.blockDataBytes)
1068: readNextBlock ();
1069:
1070: return this.blockDataBytes - this.blockDataPosition;
1071: }
1072: else
1073: return this.realInputStream.available();
1074: }
1075:
1076: public void close() throws IOException
1077: {
1078: this.realInputStream.close();
1079: }
1080:
1081: public boolean readBoolean() throws IOException
1082: {
1083: boolean switchmode = true;
1084: boolean oldmode = this.readDataFromBlock;
1085: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1086: switchmode = false;
1087: if (switchmode)
1088: oldmode = setBlockDataMode (true);
1089: boolean value = this.dataInputStream.readBoolean ();
1090: if (switchmode)
1091: setBlockDataMode (oldmode);
1092: return value;
1093: }
1094:
1095: public byte readByte() throws IOException
1096: {
1097: boolean switchmode = true;
1098: boolean oldmode = this.readDataFromBlock;
1099: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1100: switchmode = false;
1101: if (switchmode)
1102: oldmode = setBlockDataMode(true);
1103: byte value = this.dataInputStream.readByte();
1104: if (switchmode)
1105: setBlockDataMode(oldmode);
1106: return value;
1107: }
1108:
1109: public int readUnsignedByte() throws IOException
1110: {
1111: boolean switchmode = true;
1112: boolean oldmode = this.readDataFromBlock;
1113: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1114: switchmode = false;
1115: if (switchmode)
1116: oldmode = setBlockDataMode(true);
1117: int value = this.dataInputStream.readUnsignedByte();
1118: if (switchmode)
1119: setBlockDataMode(oldmode);
1120: return value;
1121: }
1122:
1123: public short readShort() throws IOException
1124: {
1125: boolean switchmode = true;
1126: boolean oldmode = this.readDataFromBlock;
1127: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1128: switchmode = false;
1129: if (switchmode)
1130: oldmode = setBlockDataMode(true);
1131: short value = this.dataInputStream.readShort();
1132: if (switchmode)
1133: setBlockDataMode(oldmode);
1134: return value;
1135: }
1136:
1137: public int readUnsignedShort() throws IOException
1138: {
1139: boolean switchmode = true;
1140: boolean oldmode = this.readDataFromBlock;
1141: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1142: switchmode = false;
1143: if (switchmode)
1144: oldmode = setBlockDataMode(true);
1145: int value = this.dataInputStream.readUnsignedShort();
1146: if (switchmode)
1147: setBlockDataMode(oldmode);
1148: return value;
1149: }
1150:
1151: public char readChar() throws IOException
1152: {
1153: boolean switchmode = true;
1154: boolean oldmode = this.readDataFromBlock;
1155: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1156: switchmode = false;
1157: if (switchmode)
1158: oldmode = setBlockDataMode(true);
1159: char value = this.dataInputStream.readChar();
1160: if (switchmode)
1161: setBlockDataMode(oldmode);
1162: return value;
1163: }
1164:
1165: public int readInt() throws IOException
1166: {
1167: boolean switchmode = true;
1168: boolean oldmode = this.readDataFromBlock;
1169: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1170: switchmode = false;
1171: if (switchmode)
1172: oldmode = setBlockDataMode(true);
1173: int value = this.dataInputStream.readInt();
1174: if (switchmode)
1175: setBlockDataMode(oldmode);
1176: return value;
1177: }
1178:
1179: public long readLong() throws IOException
1180: {
1181: boolean switchmode = true;
1182: boolean oldmode = this.readDataFromBlock;
1183: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1184: switchmode = false;
1185: if (switchmode)
1186: oldmode = setBlockDataMode(true);
1187: long value = this.dataInputStream.readLong();
1188: if (switchmode)
1189: setBlockDataMode(oldmode);
1190: return value;
1191: }
1192:
1193: public float readFloat() throws IOException
1194: {
1195: boolean switchmode = true;
1196: boolean oldmode = this.readDataFromBlock;
1197: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1198: switchmode = false;
1199: if (switchmode)
1200: oldmode = setBlockDataMode(true);
1201: float value = this.dataInputStream.readFloat();
1202: if (switchmode)
1203: setBlockDataMode(oldmode);
1204: return value;
1205: }
1206:
1207: public double readDouble() throws IOException
1208: {
1209: boolean switchmode = true;
1210: boolean oldmode = this.readDataFromBlock;
1211: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1212: switchmode = false;
1213: if (switchmode)
1214: oldmode = setBlockDataMode(true);
1215: double value = this.dataInputStream.readDouble();
1216: if (switchmode)
1217: setBlockDataMode(oldmode);
1218: return value;
1219: }
1220:
1221: public void readFully(byte data[]) throws IOException
1222: {
1223: this.dataInputStream.readFully(data);
1224: }
1225:
1226: public void readFully(byte data[], int offset, int size)
1227: throws IOException
1228: {
1229: this.dataInputStream.readFully(data, offset, size);
1230: }
1231:
1232: public int skipBytes(int len) throws IOException
1233: {
1234: return this.dataInputStream.skipBytes(len);
1235: }
1236:
1237:
1241: public String readLine() throws IOException
1242: {
1243: return this.dataInputStream.readLine();
1244: }
1245:
1246: public String readUTF() throws IOException
1247: {
1248: return this.dataInputStream.readUTF();
1249: }
1250:
1251:
1257: public abstract static class GetField
1258: {
1259: public abstract ObjectStreamClass getObjectStreamClass();
1260:
1261: public abstract boolean defaulted(String name)
1262: throws IOException, IllegalArgumentException;
1263:
1264: public abstract boolean get(String name, boolean defvalue)
1265: throws IOException, IllegalArgumentException;
1266:
1267: public abstract char get(String name, char defvalue)
1268: throws IOException, IllegalArgumentException;
1269:
1270: public abstract byte get(String name, byte defvalue)
1271: throws IOException, IllegalArgumentException;
1272:
1273: public abstract short get(String name, short defvalue)
1274: throws IOException, IllegalArgumentException;
1275:
1276: public abstract int get(String name, int defvalue)
1277: throws IOException, IllegalArgumentException;
1278:
1279: public abstract long get(String name, long defvalue)
1280: throws IOException, IllegalArgumentException;
1281:
1282: public abstract float get(String name, float defvalue)
1283: throws IOException, IllegalArgumentException;
1284:
1285: public abstract double get(String name, double defvalue)
1286: throws IOException, IllegalArgumentException;
1287:
1288: public abstract Object get(String name, Object defvalue)
1289: throws IOException, IllegalArgumentException;
1290: }
1291:
1292:
1305: public GetField readFields()
1306: throws IOException, ClassNotFoundException, NotActiveException
1307: {
1308: if (this.currentObject == null || this.currentObjectStreamClass == null)
1309: throw new NotActiveException("readFields called by non-active class and/or object");
1310:
1311: if (prereadFields != null)
1312: return prereadFields;
1313:
1314: if (fieldsAlreadyRead)
1315: throw new NotActiveException("readFields called but fields already read from"
1316: + " stream (by defaultReadObject or readFields)");
1317:
1318: final ObjectStreamClass clazz = this.currentObjectStreamClass;
1319: final byte[] prim_field_data = new byte[clazz.primFieldSize];
1320: final Object[] objs = new Object[clazz.objectFieldCount];
1321:
1322:
1323:
1324:
1325: boolean oldmode = setBlockDataMode(false);
1326: readFully(prim_field_data);
1327: for (int i = 0; i < objs.length; ++ i)
1328: objs[i] = readObject();
1329: setBlockDataMode(oldmode);
1330:
1331: prereadFields = new GetField()
1332: {
1333: public ObjectStreamClass getObjectStreamClass()
1334: {
1335: return clazz;
1336: }
1337:
1338: public boolean defaulted(String name)
1339: throws IOException, IllegalArgumentException
1340: {
1341: ObjectStreamField f = clazz.getField(name);
1342:
1343:
1344: if (f != null)
1345: {
1346:
1349: if (f.isPersistent() && !f.isToSet())
1350: return true;
1351:
1352: return false;
1353: }
1354:
1355:
1358: try
1359: {
1360: return (clazz.forClass().getDeclaredField (name) != null);
1361: }
1362: catch (NoSuchFieldException e)
1363: {
1364: throw new IllegalArgumentException(e);
1365: }
1366: }
1367:
1368: public boolean get(String name, boolean defvalue)
1369: throws IOException, IllegalArgumentException
1370: {
1371: ObjectStreamField field = getField(name, Boolean.TYPE);
1372:
1373: if (field == null)
1374: return defvalue;
1375:
1376: return prim_field_data[field.getOffset()] == 0 ? false : true;
1377: }
1378:
1379: public char get(String name, char defvalue)
1380: throws IOException, IllegalArgumentException
1381: {
1382: ObjectStreamField field = getField(name, Character.TYPE);
1383:
1384: if (field == null)
1385: return defvalue;
1386:
1387: int off = field.getOffset();
1388:
1389: return (char)(((prim_field_data[off++] & 0xFF) << 8)
1390: | (prim_field_data[off] & 0xFF));
1391: }
1392:
1393: public byte get(String name, byte defvalue)
1394: throws IOException, IllegalArgumentException
1395: {
1396: ObjectStreamField field = getField(name, Byte.TYPE);
1397:
1398: if (field == null)
1399: return defvalue;
1400:
1401: return prim_field_data[field.getOffset()];
1402: }
1403:
1404: public short get(String name, short defvalue)
1405: throws IOException, IllegalArgumentException
1406: {
1407: ObjectStreamField field = getField(name, Short.TYPE);
1408:
1409: if (field == null)
1410: return defvalue;
1411:
1412: int off = field.getOffset();
1413:
1414: return (short)(((prim_field_data[off++] & 0xFF) << 8)
1415: | (prim_field_data[off] & 0xFF));
1416: }
1417:
1418: public int get(String name, int defvalue)
1419: throws IOException, IllegalArgumentException
1420: {
1421: ObjectStreamField field = getField(name, Integer.TYPE);
1422:
1423: if (field == null)
1424: return defvalue;
1425:
1426: int off = field.getOffset();
1427:
1428: return ((prim_field_data[off++] & 0xFF) << 24)
1429: | ((prim_field_data[off++] & 0xFF) << 16)
1430: | ((prim_field_data[off++] & 0xFF) << 8)
1431: | (prim_field_data[off] & 0xFF);
1432: }
1433:
1434: public long get(String name, long defvalue)
1435: throws IOException, IllegalArgumentException
1436: {
1437: ObjectStreamField field = getField(name, Long.TYPE);
1438:
1439: if (field == null)
1440: return defvalue;
1441:
1442: int off = field.getOffset();
1443:
1444: return (long)(((prim_field_data[off++] & 0xFFL) << 56)
1445: | ((prim_field_data[off++] & 0xFFL) << 48)
1446: | ((prim_field_data[off++] & 0xFFL) << 40)
1447: | ((prim_field_data[off++] & 0xFFL) << 32)
1448: | ((prim_field_data[off++] & 0xFF) << 24)
1449: | ((prim_field_data[off++] & 0xFF) << 16)
1450: | ((prim_field_data[off++] & 0xFF) << 8)
1451: | (prim_field_data[off] & 0xFF));
1452: }
1453:
1454: public float get(String name, float defvalue)
1455: throws IOException, IllegalArgumentException
1456: {
1457: ObjectStreamField field = getField(name, Float.TYPE);
1458:
1459: if (field == null)
1460: return defvalue;
1461:
1462: int off = field.getOffset();
1463:
1464: return Float.intBitsToFloat(((prim_field_data[off++] & 0xFF) << 24)
1465: | ((prim_field_data[off++] & 0xFF) << 16)
1466: | ((prim_field_data[off++] & 0xFF) << 8)
1467: | (prim_field_data[off] & 0xFF));
1468: }
1469:
1470: public double get(String name, double defvalue)
1471: throws IOException, IllegalArgumentException
1472: {
1473: ObjectStreamField field = getField(name, Double.TYPE);
1474:
1475: if (field == null)
1476: return defvalue;
1477:
1478: int off = field.getOffset();
1479:
1480: return Double.longBitsToDouble
1481: ( (long) (((prim_field_data[off++] & 0xFFL) << 56)
1482: | ((prim_field_data[off++] & 0xFFL) << 48)
1483: | ((prim_field_data[off++] & 0xFFL) << 40)
1484: | ((prim_field_data[off++] & 0xFFL) << 32)
1485: | ((prim_field_data[off++] & 0xFF) << 24)
1486: | ((prim_field_data[off++] & 0xFF) << 16)
1487: | ((prim_field_data[off++] & 0xFF) << 8)
1488: | (prim_field_data[off] & 0xFF)));
1489: }
1490:
1491: public Object get(String name, Object defvalue)
1492: throws IOException, IllegalArgumentException
1493: {
1494: ObjectStreamField field =
1495: getField(name, defvalue == null ? null : defvalue.getClass ());
1496:
1497: if (field == null)
1498: return defvalue;
1499:
1500: return objs[field.getOffset()];
1501: }
1502:
1503: private ObjectStreamField getField(String name, Class type)
1504: throws IllegalArgumentException
1505: {
1506: ObjectStreamField field = clazz.getField(name);
1507: boolean illegal = false;
1508:
1509:
1510: try
1511: {
1512: try
1513: {
1514: Class field_type = field.getType();
1515:
1516: if (type == field_type ||
1517: (type == null && !field_type.isPrimitive()))
1518: {
1519:
1520: return field;
1521: }
1522:
1523: illegal = true;
1524: throw new IllegalArgumentException
1525: ("Field requested is of type "
1526: + field_type.getName()
1527: + ", but requested type was "
1528: + (type == null ? "Object" : type.getName()));
1529: }
1530: catch (NullPointerException _)
1531: {
1532:
1537: }
1538: catch (IllegalArgumentException e)
1539: {
1540: throw e;
1541: }
1542:
1543: return null;
1544: }
1545: finally
1546: {
1547:
1550: if (!illegal && field != null && !field.isToSet() && field.isPersistent())
1551: return null;
1552:
1553:
1556: try
1557: {
1558: Field f = clazz.forClass().getDeclaredField(name);
1559: if (Modifier.isTransient(f.getModifiers()))
1560: throw new IllegalArgumentException
1561: ("no such field (non transient) " + name);
1562: if (field == null && f.getType() != type)
1563: throw new IllegalArgumentException
1564: ("Invalid requested type for field " + name);
1565: }
1566: catch (NoSuchFieldException e)
1567: {
1568: if (field == null)
1569: throw new IllegalArgumentException(e);
1570: }
1571:
1572: }
1573: }
1574: };
1575:
1576: fieldsAlreadyRead = true;
1577: return prereadFields;
1578: }
1579:
1580:
1591: protected ObjectInputStream()
1592: throws IOException, SecurityException
1593: {
1594: SecurityManager sec_man = System.getSecurityManager();
1595: if (sec_man != null)
1596: sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1597: this.useSubclassMethod = true;
1598: }
1599:
1600:
1609: protected Object readObjectOverride()
1610: throws ClassNotFoundException, IOException, OptionalDataException
1611: {
1612: throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");
1613: }
1614:
1615:
1623: private int assignNewHandle(Object obj, boolean shared)
1624: {
1625: int handle = this.nextOID;
1626: this.nextOID = handle + 1;
1627: rememberHandle(obj,shared,handle);
1628: return handle;
1629: }
1630:
1631:
1641: private void rememberHandle(Object obj, boolean shared,
1642: int handle)
1643: {
1644: handles.put(handle, new Pair<Boolean,Object>(shared, obj));
1645: }
1646:
1647:
1656: private Object lookupHandle(int handle)
1657: throws ObjectStreamException
1658: {
1659: Pair<Boolean,Object> result = handles.get(handle);
1660: if (result == null)
1661: throw new StreamCorruptedException("The handle, " +
1662: Integer.toHexString(handle) +
1663: ", is invalid.");
1664: if (!result.getLeft())
1665: throw new InvalidObjectException("The handle, " +
1666: Integer.toHexString(handle) +
1667: ", is not shared.");
1668: return result.getRight();
1669: }
1670:
1671: private Object processResolution(ObjectStreamClass osc, Object obj, int handle,
1672: boolean shared)
1673: throws IOException
1674: {
1675: if (osc != null && obj instanceof Serializable)
1676: {
1677: try
1678: {
1679: Method m = osc.readResolveMethod;
1680: if(m != null)
1681: {
1682: obj = m.invoke(obj, new Object[] {});
1683: }
1684: }
1685: catch (IllegalAccessException ignore)
1686: {
1687: }
1688: catch (InvocationTargetException exception)
1689: {
1690: Throwable cause = exception.getCause();
1691: if (cause instanceof ObjectStreamException)
1692: throw (ObjectStreamException) cause;
1693: else if (cause instanceof RuntimeException)
1694: throw (RuntimeException) cause;
1695: else if (cause instanceof Error)
1696: throw (Error) cause;
1697: }
1698: }
1699:
1700: if (this.resolveEnabled)
1701: obj = resolveObject(obj);
1702:
1703: rememberHandle(obj, shared, handle);
1704: if (!shared)
1705: {
1706: if (obj instanceof byte[])
1707: return ((byte[]) obj).clone();
1708: if (obj instanceof short[])
1709: return ((short[]) obj).clone();
1710: if (obj instanceof int[])
1711: return ((int[]) obj).clone();
1712: if (obj instanceof long[])
1713: return ((long[]) obj).clone();
1714: if (obj instanceof char[])
1715: return ((char[]) obj).clone();
1716: if (obj instanceof boolean[])
1717: return ((boolean[]) obj).clone();
1718: if (obj instanceof float[])
1719: return ((float[]) obj).clone();
1720: if (obj instanceof double[])
1721: return ((double[]) obj).clone();
1722: if (obj instanceof Object[])
1723: return ((Object[]) obj).clone();
1724: }
1725: return obj;
1726: }
1727:
1728: private void clearHandles()
1729: {
1730: handles.clear();
1731: this.nextOID = baseWireHandle;
1732: }
1733:
1734: private void readNextBlock() throws IOException
1735: {
1736: byte marker = this.realInputStream.readByte();
1737: while (marker == TC_RESET)
1738: {
1739: if(dump) dumpElementln("RESET");
1740: clearHandles();
1741: marker = this.realInputStream.readByte();
1742: }
1743: readNextBlock(marker);
1744: }
1745:
1746: private void readNextBlock(byte marker) throws IOException
1747: {
1748: if (marker == TC_BLOCKDATA)
1749: {
1750: if(dump) dumpElement("BLOCK DATA SIZE=");
1751: this.blockDataBytes = this.realInputStream.readUnsignedByte();
1752: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1753: }
1754: else if (marker == TC_BLOCKDATALONG)
1755: {
1756: if(dump) dumpElement("BLOCK DATA LONG SIZE=");
1757: this.blockDataBytes = this.realInputStream.readInt();
1758: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1759: }
1760: else
1761: {
1762: throw new EOFException("Attempt to read primitive data, but no data block is active.");
1763: }
1764:
1765: if (this.blockData.length < this.blockDataBytes)
1766: this.blockData = new byte[this.blockDataBytes];
1767:
1768: this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
1769: this.blockDataPosition = 0;
1770: }
1771:
1772: private void readArrayElements (Object array, Class clazz)
1773: throws ClassNotFoundException, IOException
1774: {
1775: if (clazz.isPrimitive())
1776: {
1777: if (clazz == Boolean.TYPE)
1778: {
1779: boolean[] cast_array = (boolean[])array;
1780: for (int i=0; i < cast_array.length; i++)
1781: cast_array[i] = this.realInputStream.readBoolean();
1782: return;
1783: }
1784: if (clazz == Byte.TYPE)
1785: {
1786: byte[] cast_array = (byte[])array;
1787: for (int i=0; i < cast_array.length; i++)
1788: cast_array[i] = this.realInputStream.readByte();
1789: return;
1790: }
1791: if (clazz == Character.TYPE)
1792: {
1793: char[] cast_array = (char[])array;
1794: for (int i=0; i < cast_array.length; i++)
1795: cast_array[i] = this.realInputStream.readChar();
1796: return;
1797: }
1798: if (clazz == Double.TYPE)
1799: {
1800: double[] cast_array = (double[])array;
1801: for (int i=0; i < cast_array.length; i++)
1802: cast_array[i] = this.realInputStream.readDouble();
1803: return;
1804: }
1805: if (clazz == Float.TYPE)
1806: {
1807: float[] cast_array = (float[])array;
1808: for (int i=0; i < cast_array.length; i++)
1809: cast_array[i] = this.realInputStream.readFloat();
1810: return;
1811: }
1812: if (clazz == Integer.TYPE)
1813: {
1814: int[] cast_array = (int[])array;
1815: for (int i=0; i < cast_array.length; i++)
1816: cast_array[i] = this.realInputStream.readInt();
1817: return;
1818: }
1819: if (clazz == Long.TYPE)
1820: {
1821: long[] cast_array = (long[])array;
1822: for (int i=0; i < cast_array.length; i++)
1823: cast_array[i] = this.realInputStream.readLong();
1824: return;
1825: }
1826: if (clazz == Short.TYPE)
1827: {
1828: short[] cast_array = (short[])array;
1829: for (int i=0; i < cast_array.length; i++)
1830: cast_array[i] = this.realInputStream.readShort();
1831: return;
1832: }
1833: }
1834: else
1835: {
1836: Object[] cast_array = (Object[])array;
1837: for (int i=0; i < cast_array.length; i++)
1838: cast_array[i] = readObject();
1839: }
1840: }
1841:
1842: private void readFields (Object obj, ObjectStreamClass stream_osc)
1843: throws ClassNotFoundException, IOException
1844: {
1845: ObjectStreamField[] fields = stream_osc.fieldMapping;
1846:
1847: for (int i = 0; i < fields.length; i += 2)
1848: {
1849: ObjectStreamField stream_field = fields[i];
1850: ObjectStreamField real_field = fields[i + 1];
1851: boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
1852: boolean set_value = (real_field != null && real_field.isToSet());
1853: String field_name;
1854: char type;
1855:
1856: if (stream_field != null)
1857: {
1858: field_name = stream_field.getName();
1859: type = stream_field.getTypeCode();
1860: }
1861: else
1862: {
1863: field_name = real_field.getName();
1864: type = real_field.getTypeCode();
1865: }
1866:
1867: switch(type)
1868: {
1869: case 'Z':
1870: {
1871: boolean value =
1872: read_value ? this.realInputStream.readBoolean() : false;
1873: if (dump && read_value && set_value)
1874: dumpElementln(" " + field_name + ": " + value);
1875: if (set_value)
1876: real_field.setBooleanField(obj, value);
1877: break;
1878: }
1879: case 'B':
1880: {
1881: byte value =
1882: read_value ? this.realInputStream.readByte() : 0;
1883: if (dump && read_value && set_value)
1884: dumpElementln(" " + field_name + ": " + value);
1885: if (set_value)
1886: real_field.setByteField(obj, value);
1887: break;
1888: }
1889: case 'C':
1890: {
1891: char value =
1892: read_value ? this.realInputStream.readChar(): 0;
1893: if (dump && read_value && set_value)
1894: dumpElementln(" " + field_name + ": " + value);
1895: if (set_value)
1896: real_field.setCharField(obj, value);
1897: break;
1898: }
1899: case 'D':
1900: {
1901: double value =
1902: read_value ? this.realInputStream.readDouble() : 0;
1903: if (dump && read_value && set_value)
1904: dumpElementln(" " + field_name + ": " + value);
1905: if (set_value)
1906: real_field.setDoubleField(obj, value);
1907: break;
1908: }
1909: case 'F':
1910: {
1911: float value =
1912: read_value ? this.realInputStream.readFloat() : 0;
1913: if (dump && read_value && set_value)
1914: dumpElementln(" " + field_name + ": " + value);
1915: if (set_value)
1916: real_field.setFloatField(obj, value);
1917: break;
1918: }
1919: case 'I':
1920: {
1921: int value =
1922: read_value ? this.realInputStream.readInt() : 0;
1923: if (dump && read_value && set_value)
1924: dumpElementln(" " + field_name + ": " + value);
1925: if (set_value)
1926: real_field.setIntField(obj, value);
1927: break;
1928: }
1929: case 'J':
1930: {
1931: long value =
1932: read_value ? this.realInputStream.readLong() : 0;
1933: if (dump && read_value && set_value)
1934: dumpElementln(" " + field_name + ": " + value);
1935: if (set_value)
1936: real_field.setLongField(obj, value);
1937: break;
1938: }
1939: case 'S':
1940: {
1941: short value =
1942: read_value ? this.realInputStream.readShort() : 0;
1943: if (dump && read_value && set_value)
1944: dumpElementln(" " + field_name + ": " + value);
1945: if (set_value)
1946: real_field.setShortField(obj, value);
1947: break;
1948: }
1949: case 'L':
1950: case '[':
1951: {
1952: Object value =
1953: read_value ? readObject() : null;
1954: if (set_value)
1955: real_field.setObjectField(obj, value);
1956: break;
1957: }
1958: default:
1959: throw new InternalError("Invalid type code: " + type);
1960: }
1961: }
1962: }
1963:
1964:
1965: private boolean setBlockDataMode (boolean on)
1966: {
1967: boolean oldmode = this.readDataFromBlock;
1968: this.readDataFromBlock = on;
1969:
1970: if (on)
1971: this.dataInputStream = this.blockDataInput;
1972: else
1973: this.dataInputStream = this.realInputStream;
1974: return oldmode;
1975: }
1976:
1977:
1978:
1979: private Object newObject (Class real_class, Constructor constructor)
1980: throws ClassNotFoundException, IOException
1981: {
1982: if (constructor == null)
1983: throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
1984: try
1985: {
1986: return VMObjectInputStream.allocateObject(real_class, constructor.getDeclaringClass(), constructor);
1987: }
1988: catch (InstantiationException e)
1989: {
1990: throw (ClassNotFoundException) new ClassNotFoundException
1991: ("Instance of " + real_class + " could not be created").initCause(e);
1992: }
1993: }
1994:
1995:
1996:
1997: private void invokeValidators() throws InvalidObjectException
1998: {
1999: try
2000: {
2001: Iterator<ValidatorAndPriority> it = currentObjectValidators.iterator();
2002: while(it.hasNext())
2003: {
2004: ValidatorAndPriority vap = it.next();
2005: ObjectInputValidation validator = vap.validator;
2006: validator.validateObject();
2007: }
2008: }
2009: finally
2010: {
2011: currentObjectValidators = null;
2012: }
2013: }
2014:
2015: private void callReadMethod (Method readObject, Class klass, Object obj)
2016: throws ClassNotFoundException, IOException
2017: {
2018: try
2019: {
2020: readObject.invoke(obj, new Object[] { this });
2021: }
2022: catch (InvocationTargetException x)
2023: {
2024:
2025: Throwable exception = x.getTargetException();
2026: if (exception instanceof RuntimeException)
2027: throw (RuntimeException) exception;
2028: if (exception instanceof IOException)
2029: throw (IOException) exception;
2030: if (exception instanceof ClassNotFoundException)
2031: throw (ClassNotFoundException) exception;
2032:
2033: throw (IOException) new IOException(
2034: "Exception thrown from readObject() on " + klass).initCause(x);
2035: }
2036: catch (Exception x)
2037: {
2038: throw (IOException) new IOException(
2039: "Failure invoking readObject() on " + klass).initCause(x);
2040: }
2041:
2042:
2043: prereadFields = null;
2044: }
2045:
2046: private static final int BUFFER_SIZE = 1024;
2047:
2048: private DataInputStream realInputStream;
2049: private DataInputStream dataInputStream;
2050: private DataInputStream blockDataInput;
2051: private int blockDataPosition;
2052: private int blockDataBytes;
2053: private byte[] blockData;
2054: private boolean useSubclassMethod;
2055: private int nextOID;
2056: private boolean resolveEnabled;
2057: private Map<Integer,Pair<Boolean,Object>> handles;
2058: private Object currentObject;
2059: private ObjectStreamClass currentObjectStreamClass;
2060: private TreeSet<ValidatorAndPriority> currentObjectValidators;
2061: private boolean readDataFromBlock;
2062: private boolean fieldsAlreadyRead;
2063: private Hashtable<Class,ObjectStreamClass> classLookupTable;
2064: private GetField prereadFields;
2065:
2066: private static boolean dump;
2067:
2068:
2069: private int depth = 0;
2070:
2071: private static final boolean DEBUG = false;
2072:
2073: private void dumpElement (String msg)
2074: {
2075: System.out.print(msg);
2076: }
2077:
2078: private void dumpElementln (String msg)
2079: {
2080: System.out.println(msg);
2081: for (int i = 0; i < depth; i++)
2082: System.out.print (" ");
2083: System.out.print (Thread.currentThread() + ": ");
2084: }
2085:
2086:
2087: private static final class ValidatorAndPriority implements Comparable
2088: {
2089: int priority;
2090: ObjectInputValidation validator;
2091:
2092: ValidatorAndPriority (ObjectInputValidation validator, int priority)
2093: {
2094: this.priority = priority;
2095: this.validator = validator;
2096: }
2097:
2098: public int compareTo (Object o)
2099: {
2100: ValidatorAndPriority vap = (ValidatorAndPriority)o;
2101: return this.priority - vap.priority;
2102: }
2103: }
2104: }