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: {
360: if(dump) dumpElement("STRING=");
361: String s = this.realInputStream.readUTF();
362: if(dump) dumpElementln(s);
363: ret_val = processResolution(null, s, assignNewHandle(s,shared),
364: shared);
365: break;
366: }
367:
368: case TC_LONGSTRING:
369: {
370: if(dump) dumpElement("STRING=");
371: String s = this.realInputStream.readUTFLong();
372: if(dump) dumpElementln(s);
373: ret_val = processResolution(null, s, assignNewHandle(s,shared),
374: shared);
375: break;
376: }
377:
378: case TC_ARRAY:
379: {
380: if(dump) dumpElementln("ARRAY");
381: ObjectStreamClass osc = (ObjectStreamClass)readObject();
382: Class componentType = osc.forClass().getComponentType();
383: if(dump) dumpElement("ARRAY LENGTH=");
384: int length = this.realInputStream.readInt();
385: if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
386: Object array = Array.newInstance(componentType, length);
387: int handle = assignNewHandle(array,shared);
388: readArrayElements(array, componentType);
389: if(dump)
390: for (int i = 0, len = Array.getLength(array); i < len; i++)
391: dumpElementln(" ELEMENT[" + i + "]=", Array.get(array, i));
392: ret_val = processResolution(null, array, handle, shared);
393: break;
394: }
395:
396: case TC_OBJECT:
397: {
398: if(dump) dumpElementln("OBJECT");
399: ObjectStreamClass osc = (ObjectStreamClass)readObject();
400: Class clazz = osc.forClass();
401:
402: if (!osc.realClassIsSerializable)
403: throw new NotSerializableException
404: (clazz + " is not Serializable, and thus cannot be deserialized.");
405:
406: if (osc.realClassIsExternalizable)
407: {
408: Externalizable obj = osc.newInstance();
409:
410: int handle = assignNewHandle(obj,shared);
411:
412: boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
413:
414: boolean oldmode = this.readDataFromBlock;
415: if (read_from_blocks)
416: setBlockDataMode(true);
417:
418: obj.readExternal(this);
419:
420: if (read_from_blocks)
421: {
422: setBlockDataMode(oldmode);
423: if (!oldmode)
424: if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
425: throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
426: }
427:
428: ret_val = processResolution(osc, obj, handle,shared);
429: break;
430:
431: }
432:
433: Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
434:
435: int handle = assignNewHandle(obj,shared);
436: Object prevObject = this.currentObject;
437: ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
438: TreeSet<ValidatorAndPriority> prevObjectValidators =
439: this.currentObjectValidators;
440:
441: this.currentObject = obj;
442: this.currentObjectValidators = null;
443: ObjectStreamClass[] hierarchy = hierarchy(clazz);
444:
445: for (int i = 0; i < hierarchy.length; i++)
446: {
447: this.currentObjectStreamClass = hierarchy[i];
448: if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
449:
450:
451:
452:
453:
454:
455: Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
456: if (readObjectMethod != null)
457: {
458: fieldsAlreadyRead = false;
459: boolean oldmode = setBlockDataMode(true);
460: callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
461: setBlockDataMode(oldmode);
462: }
463: else
464: {
465: readFields(obj, currentObjectStreamClass);
466: }
467:
468: if (this.currentObjectStreamClass.hasWriteMethod())
469: {
470: if(dump) dumpElement("ENDBLOCKDATA? ");
471: try
472: {
473:
474: byte writeMarker = this.realInputStream.readByte();
475: while (writeMarker != TC_ENDBLOCKDATA)
476: {
477: parseContent(writeMarker, shared);
478: writeMarker = this.realInputStream.readByte();
479: }
480: if(dump) dumpElementln("yes");
481: }
482: catch (EOFException e)
483: {
484: throw (IOException) new IOException
485: ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e);
486: }
487: }
488: }
489:
490: this.currentObject = prevObject;
491: this.currentObjectStreamClass = prevObjectStreamClass;
492: ret_val = processResolution(osc, obj, handle, shared);
493: if (currentObjectValidators != null)
494: invokeValidators();
495: this.currentObjectValidators = prevObjectValidators;
496:
497: break;
498: }
499:
500: case TC_RESET:
501: if(dump) dumpElementln("RESET");
502: clearHandles();
503: ret_val = readObject();
504: break;
505:
506: case TC_EXCEPTION:
507: {
508: if(dump) dumpElement("EXCEPTION=");
509: Exception e = (Exception)readObject();
510: if(dump) dumpElementln(e.toString());
511: clearHandles();
512: throw new WriteAbortedException("Exception thrown during writing of stream", e);
513: }
514:
515: case TC_ENUM:
516: {
517:
518: if (dump)
519: dumpElementln("ENUM=");
520: ObjectStreamClass osc = (ObjectStreamClass) readObject();
521: String constantName = (String) readObject();
522: if (dump)
523: dumpElementln("CONSTANT NAME = " + constantName);
524: Class clazz = osc.forClass();
525: Enum instance = Enum.valueOf(clazz, constantName);
526: assignNewHandle(instance,shared);
527: ret_val = instance;
528: break;
529: }
530:
531: default:
532: throw new IOException("Unknown marker on stream: " + marker);
533: }
534: return ret_val;
535: }
536:
537:
550: private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
551: throws InvalidClassException
552: {
553: int nonPrimitive = 0;
554:
555: for (nonPrimitive = 0;
556: nonPrimitive < fields1.length
557: && fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
558: {
559: }
560:
561: if (nonPrimitive == fields1.length)
562: return;
563:
564: int i = 0;
565: ObjectStreamField f1;
566: ObjectStreamField f2;
567:
568: while (i < fields2.length
569: && nonPrimitive < fields1.length)
570: {
571: f1 = fields1[nonPrimitive];
572: f2 = fields2[i];
573:
574: if (!f2.isPrimitive())
575: break;
576:
577: int compVal = f1.getName().compareTo (f2.getName());
578:
579: if (compVal < 0)
580: {
581: nonPrimitive++;
582: }
583: else if (compVal > 0)
584: {
585: i++;
586: }
587: else
588: {
589: throw new InvalidClassException
590: ("invalid field type for " + f2.getName() +
591: " in class " + name);
592: }
593: }
594: }
595:
596:
612: protected ObjectStreamClass readClassDescriptor()
613: throws ClassNotFoundException, IOException
614: {
615: if(dump) dumpElement("CLASSDESC NAME=");
616: String name = this.realInputStream.readUTF();
617: if(dump) dumpElement(name + "; UID=");
618: long uid = this.realInputStream.readLong ();
619: if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");
620: byte flags = this.realInputStream.readByte ();
621: if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");
622: short field_count = this.realInputStream.readShort();
623: if(dump) dumpElementln(Short.toString(field_count));
624: ObjectStreamField[] fields = new ObjectStreamField[field_count];
625: ObjectStreamClass osc = new ObjectStreamClass(name, uid,
626: flags, fields);
627: assignNewHandle(osc,true);
628:
629: for (int i = 0; i < field_count; i++)
630: {
631: if(dump) dumpElement(" TYPE CODE=");
632: char type_code = (char)this.realInputStream.readByte();
633: if(dump) dumpElement(type_code + "; FIELD NAME=");
634: String field_name = this.realInputStream.readUTF();
635: if(dump) dumpElementln(field_name);
636: String class_name;
637:
638:
639:
640:
641:
642: if (type_code == 'L' || type_code == '[')
643: class_name = (String)readObject();
644: else
645: class_name = String.valueOf(type_code);
646:
647: fields[i] =
648: new ObjectStreamField(field_name, class_name);
649: }
650:
651:
653: Class clazz = resolveClass(osc);
654: ClassLoader loader = clazz.getClassLoader();
655: for (int i = 0; i < field_count; i++)
656: {
657: fields[i].resolveType(loader);
658: }
659: boolean oldmode = setBlockDataMode(true);
660: osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
661: classLookupTable.put(clazz, osc);
662: setBlockDataMode(oldmode);
663:
664:
665: Class first_nonserial = clazz.getSuperclass();
666:
667:
668:
669:
670: if (first_nonserial == null)
671: first_nonserial = clazz;
672: else
673: while (Serializable.class.isAssignableFrom(first_nonserial))
674: first_nonserial = first_nonserial.getSuperclass();
675:
676: final Class local_constructor_class = first_nonserial;
677:
678: osc.firstNonSerializableParentConstructor =
679: (Constructor)AccessController.doPrivileged(new PrivilegedAction()
680: {
681: public Object run()
682: {
683: try
684: {
685: Constructor c = local_constructor_class.
686: getDeclaredConstructor(new Class[0]);
687: if (Modifier.isPrivate(c.getModifiers()))
688: return null;
689: return c;
690: }
691: catch (NoSuchMethodException e)
692: {
693:
694: return null;
695: }
696: }
697: });
698:
699: osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);
700: osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);
701:
702: ObjectStreamField[] stream_fields = osc.fields;
703: ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;
704: ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];
705:
706: int stream_idx = 0;
707: int real_idx = 0;
708: int map_idx = 0;
709:
710:
715: checkTypeConsistency(name, real_fields, stream_fields);
716: checkTypeConsistency(name, stream_fields, real_fields);
717:
718:
719: while (stream_idx < stream_fields.length
720: || real_idx < real_fields.length)
721: {
722: ObjectStreamField stream_field = null;
723: ObjectStreamField real_field = null;
724:
725: if (stream_idx == stream_fields.length)
726: {
727: real_field = real_fields[real_idx++];
728: }
729: else if (real_idx == real_fields.length)
730: {
731: stream_field = stream_fields[stream_idx++];
732: }
733: else
734: {
735: int comp_val =
736: real_fields[real_idx].compareTo (stream_fields[stream_idx]);
737:
738: if (comp_val < 0)
739: {
740: real_field = real_fields[real_idx++];
741: }
742: else if (comp_val > 0)
743: {
744: stream_field = stream_fields[stream_idx++];
745: }
746: else
747: {
748: stream_field = stream_fields[stream_idx++];
749: real_field = real_fields[real_idx++];
750: if (stream_field.getType() != real_field.getType())
751: throw new InvalidClassException
752: ("invalid field type for " + real_field.getName() +
753: " in class " + name);
754: }
755: }
756:
757:
760: if (map_idx == fieldmapping.length)
761: {
762: ObjectStreamField[] newfieldmapping =
763: new ObjectStreamField[fieldmapping.length + 2];
764: System.arraycopy(fieldmapping, 0,
765: newfieldmapping, 0, fieldmapping.length);
766: fieldmapping = newfieldmapping;
767: }
768: fieldmapping[map_idx++] = stream_field;
769: fieldmapping[map_idx++] = real_field;
770: }
771: osc.fieldMapping = fieldmapping;
772:
773: return osc;
774: }
775:
776:
795: public void defaultReadObject()
796: throws ClassNotFoundException, IOException, NotActiveException
797: {
798: if (this.currentObject == null || this.currentObjectStreamClass == null)
799: throw new NotActiveException("defaultReadObject called by non-active"
800: + " class and/or object");
801:
802: if (fieldsAlreadyRead)
803: throw new NotActiveException("defaultReadObject called but fields "
804: + "already read from stream (by "
805: + "defaultReadObject or readFields)");
806:
807: boolean oldmode = setBlockDataMode(false);
808: readFields(this.currentObject, this.currentObjectStreamClass);
809: setBlockDataMode(oldmode);
810:
811: fieldsAlreadyRead = true;
812: }
813:
814:
815:
833: public void registerValidation(ObjectInputValidation validator,
834: int priority)
835: throws InvalidObjectException, NotActiveException
836: {
837: if (this.currentObject == null || this.currentObjectStreamClass == null)
838: throw new NotActiveException("registerValidation called by non-active "
839: + "class and/or object");
840:
841: if (validator == null)
842: throw new InvalidObjectException("attempt to add a null "
843: + "ObjectInputValidation object");
844:
845: if (currentObjectValidators == null)
846: currentObjectValidators = new TreeSet<ValidatorAndPriority>();
847:
848: currentObjectValidators.add(new ValidatorAndPriority(validator, priority));
849: }
850:
851:
852:
868: protected Class<?> resolveClass(ObjectStreamClass osc)
869: throws ClassNotFoundException, IOException
870: {
871: String name = osc.getName();
872: try
873: {
874: return Class.forName(name, true, currentLoader());
875: }
876: catch(ClassNotFoundException x)
877: {
878: if (name.equals("void"))
879: return Void.TYPE;
880: else if (name.equals("boolean"))
881: return Boolean.TYPE;
882: else if (name.equals("byte"))
883: return Byte.TYPE;
884: else if (name.equals("char"))
885: return Character.TYPE;
886: else if (name.equals("short"))
887: return Short.TYPE;
888: else if (name.equals("int"))
889: return Integer.TYPE;
890: else if (name.equals("long"))
891: return Long.TYPE;
892: else if (name.equals("float"))
893: return Float.TYPE;
894: else if (name.equals("double"))
895: return Double.TYPE;
896: else
897: throw x;
898: }
899: }
900:
901:
905: private ClassLoader currentLoader()
906: {
907: return VMStackWalker.firstNonNullClassLoader();
908: }
909:
910:
921: private ObjectStreamClass lookupClass(Class clazz)
922: {
923: if (clazz == null)
924: return null;
925:
926: ObjectStreamClass oclazz;
927: oclazz = classLookupTable.get(clazz);
928: if (oclazz == null)
929: return ObjectStreamClass.lookup(clazz);
930: else
931: return oclazz;
932: }
933:
934:
944: private ObjectStreamClass[] hierarchy(Class clazz)
945: {
946: ObjectStreamClass osc = lookupClass(clazz);
947:
948: return osc == null ? new ObjectStreamClass[0] : osc.hierarchy();
949: }
950:
951:
964: protected Object resolveObject(Object obj) throws IOException
965: {
966: return obj;
967: }
968:
969:
970: protected Class<?> resolveProxyClass(String[] intfs)
971: throws IOException, ClassNotFoundException
972: {
973: ClassLoader cl = currentLoader();
974:
975: Class<?>[] clss = new Class<?>[intfs.length];
976: if(cl == null)
977: {
978: for (int i = 0; i < intfs.length; i++)
979: clss[i] = Class.forName(intfs[i]);
980: cl = ClassLoader.getSystemClassLoader();
981: }
982: else
983: for (int i = 0; i < intfs.length; i++)
984: clss[i] = Class.forName(intfs[i], false, cl);
985: try
986: {
987: return Proxy.getProxyClass(cl, clss);
988: }
989: catch (IllegalArgumentException e)
990: {
991: throw new ClassNotFoundException(null, e);
992: }
993: }
994:
995:
1003: protected boolean enableResolveObject (boolean enable)
1004: throws SecurityException
1005: {
1006: if (enable)
1007: {
1008: SecurityManager sm = System.getSecurityManager();
1009: if (sm != null)
1010: sm.checkPermission(new SerializablePermission("enableSubstitution"));
1011: }
1012:
1013: boolean old_val = this.resolveEnabled;
1014: this.resolveEnabled = enable;
1015: return old_val;
1016: }
1017:
1018:
1027: protected void readStreamHeader()
1028: throws IOException, StreamCorruptedException
1029: {
1030: if(dump) dumpElement("STREAM MAGIC ");
1031: if (this.realInputStream.readShort() != STREAM_MAGIC)
1032: throw new StreamCorruptedException("Invalid stream magic number");
1033:
1034: if(dump) dumpElementln("STREAM VERSION ");
1035: if (this.realInputStream.readShort() != STREAM_VERSION)
1036: throw new StreamCorruptedException("Invalid stream version number");
1037: }
1038:
1039: public int read() throws IOException
1040: {
1041: if (this.readDataFromBlock)
1042: {
1043: if (this.blockDataPosition >= this.blockDataBytes)
1044: readNextBlock();
1045: return (this.blockData[this.blockDataPosition++] & 0xff);
1046: }
1047: else
1048: return this.realInputStream.read();
1049: }
1050:
1051: public int read(byte[] data, int offset, int length) throws IOException
1052: {
1053: if (this.readDataFromBlock)
1054: {
1055: int remain = this.blockDataBytes - this.blockDataPosition;
1056: if (remain == 0)
1057: {
1058: readNextBlock();
1059: remain = this.blockDataBytes - this.blockDataPosition;
1060: }
1061: length = Math.min(length, remain);
1062: System.arraycopy(this.blockData, this.blockDataPosition,
1063: data, offset, length);
1064: this.blockDataPosition += length;
1065:
1066: return length;
1067: }
1068: else
1069: return this.realInputStream.read(data, offset, length);
1070: }
1071:
1072: public int available() throws IOException
1073: {
1074: if (this.readDataFromBlock)
1075: {
1076: if (this.blockDataPosition >= this.blockDataBytes)
1077: readNextBlock ();
1078:
1079: return this.blockDataBytes - this.blockDataPosition;
1080: }
1081: else
1082: return this.realInputStream.available();
1083: }
1084:
1085: public void close() throws IOException
1086: {
1087: this.realInputStream.close();
1088: }
1089:
1090: public boolean readBoolean() throws IOException
1091: {
1092: boolean switchmode = true;
1093: boolean oldmode = this.readDataFromBlock;
1094: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1095: switchmode = false;
1096: if (switchmode)
1097: oldmode = setBlockDataMode (true);
1098: boolean value = this.dataInputStream.readBoolean ();
1099: if (switchmode)
1100: setBlockDataMode (oldmode);
1101: return value;
1102: }
1103:
1104: public byte readByte() throws IOException
1105: {
1106: boolean switchmode = true;
1107: boolean oldmode = this.readDataFromBlock;
1108: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1109: switchmode = false;
1110: if (switchmode)
1111: oldmode = setBlockDataMode(true);
1112: byte value = this.dataInputStream.readByte();
1113: if (switchmode)
1114: setBlockDataMode(oldmode);
1115: return value;
1116: }
1117:
1118: public int readUnsignedByte() throws IOException
1119: {
1120: boolean switchmode = true;
1121: boolean oldmode = this.readDataFromBlock;
1122: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
1123: switchmode = false;
1124: if (switchmode)
1125: oldmode = setBlockDataMode(true);
1126: int value = this.dataInputStream.readUnsignedByte();
1127: if (switchmode)
1128: setBlockDataMode(oldmode);
1129: return value;
1130: }
1131:
1132: public short readShort() throws IOException
1133: {
1134: boolean switchmode = true;
1135: boolean oldmode = this.readDataFromBlock;
1136: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1137: switchmode = false;
1138: if (switchmode)
1139: oldmode = setBlockDataMode(true);
1140: short value = this.dataInputStream.readShort();
1141: if (switchmode)
1142: setBlockDataMode(oldmode);
1143: return value;
1144: }
1145:
1146: public int readUnsignedShort() throws IOException
1147: {
1148: boolean switchmode = true;
1149: boolean oldmode = this.readDataFromBlock;
1150: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1151: switchmode = false;
1152: if (switchmode)
1153: oldmode = setBlockDataMode(true);
1154: int value = this.dataInputStream.readUnsignedShort();
1155: if (switchmode)
1156: setBlockDataMode(oldmode);
1157: return value;
1158: }
1159:
1160: public char readChar() throws IOException
1161: {
1162: boolean switchmode = true;
1163: boolean oldmode = this.readDataFromBlock;
1164: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
1165: switchmode = false;
1166: if (switchmode)
1167: oldmode = setBlockDataMode(true);
1168: char value = this.dataInputStream.readChar();
1169: if (switchmode)
1170: setBlockDataMode(oldmode);
1171: return value;
1172: }
1173:
1174: public int readInt() throws IOException
1175: {
1176: boolean switchmode = true;
1177: boolean oldmode = this.readDataFromBlock;
1178: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1179: switchmode = false;
1180: if (switchmode)
1181: oldmode = setBlockDataMode(true);
1182: int value = this.dataInputStream.readInt();
1183: if (switchmode)
1184: setBlockDataMode(oldmode);
1185: return value;
1186: }
1187:
1188: public long readLong() throws IOException
1189: {
1190: boolean switchmode = true;
1191: boolean oldmode = this.readDataFromBlock;
1192: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1193: switchmode = false;
1194: if (switchmode)
1195: oldmode = setBlockDataMode(true);
1196: long value = this.dataInputStream.readLong();
1197: if (switchmode)
1198: setBlockDataMode(oldmode);
1199: return value;
1200: }
1201:
1202: public float readFloat() throws IOException
1203: {
1204: boolean switchmode = true;
1205: boolean oldmode = this.readDataFromBlock;
1206: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
1207: switchmode = false;
1208: if (switchmode)
1209: oldmode = setBlockDataMode(true);
1210: float value = this.dataInputStream.readFloat();
1211: if (switchmode)
1212: setBlockDataMode(oldmode);
1213: return value;
1214: }
1215:
1216: public double readDouble() throws IOException
1217: {
1218: boolean switchmode = true;
1219: boolean oldmode = this.readDataFromBlock;
1220: if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
1221: switchmode = false;
1222: if (switchmode)
1223: oldmode = setBlockDataMode(true);
1224: double value = this.dataInputStream.readDouble();
1225: if (switchmode)
1226: setBlockDataMode(oldmode);
1227: return value;
1228: }
1229:
1230: public void readFully(byte data[]) throws IOException
1231: {
1232: this.dataInputStream.readFully(data);
1233: }
1234:
1235: public void readFully(byte data[], int offset, int size)
1236: throws IOException
1237: {
1238: this.dataInputStream.readFully(data, offset, size);
1239: }
1240:
1241: public int skipBytes(int len) throws IOException
1242: {
1243: return this.dataInputStream.skipBytes(len);
1244: }
1245:
1246:
1250: public String readLine() throws IOException
1251: {
1252: return this.dataInputStream.readLine();
1253: }
1254:
1255: public String readUTF() throws IOException
1256: {
1257: return this.dataInputStream.readUTF();
1258: }
1259:
1260:
1266: public abstract static class GetField
1267: {
1268: public abstract ObjectStreamClass getObjectStreamClass();
1269:
1270: public abstract boolean defaulted(String name)
1271: throws IOException, IllegalArgumentException;
1272:
1273: public abstract boolean get(String name, boolean defvalue)
1274: throws IOException, IllegalArgumentException;
1275:
1276: public abstract char get(String name, char defvalue)
1277: throws IOException, IllegalArgumentException;
1278:
1279: public abstract byte get(String name, byte defvalue)
1280: throws IOException, IllegalArgumentException;
1281:
1282: public abstract short get(String name, short defvalue)
1283: throws IOException, IllegalArgumentException;
1284:
1285: public abstract int get(String name, int defvalue)
1286: throws IOException, IllegalArgumentException;
1287:
1288: public abstract long get(String name, long defvalue)
1289: throws IOException, IllegalArgumentException;
1290:
1291: public abstract float get(String name, float defvalue)
1292: throws IOException, IllegalArgumentException;
1293:
1294: public abstract double get(String name, double defvalue)
1295: throws IOException, IllegalArgumentException;
1296:
1297: public abstract Object get(String name, Object defvalue)
1298: throws IOException, IllegalArgumentException;
1299: }
1300:
1301:
1314: public GetField readFields()
1315: throws IOException, ClassNotFoundException, NotActiveException
1316: {
1317: if (this.currentObject == null || this.currentObjectStreamClass == null)
1318: throw new NotActiveException("readFields called by non-active class and/or object");
1319:
1320: if (prereadFields != null)
1321: return prereadFields;
1322:
1323: if (fieldsAlreadyRead)
1324: throw new NotActiveException("readFields called but fields already read from"
1325: + " stream (by defaultReadObject or readFields)");
1326:
1327: final ObjectStreamClass clazz = this.currentObjectStreamClass;
1328: final byte[] prim_field_data = new byte[clazz.primFieldSize];
1329: final Object[] objs = new Object[clazz.objectFieldCount];
1330:
1331:
1332:
1333:
1334: boolean oldmode = setBlockDataMode(false);
1335: readFully(prim_field_data);
1336: for (int i = 0; i < objs.length; ++ i)
1337: objs[i] = readObject();
1338: setBlockDataMode(oldmode);
1339:
1340: prereadFields = new GetField()
1341: {
1342: public ObjectStreamClass getObjectStreamClass()
1343: {
1344: return clazz;
1345: }
1346:
1347: public boolean defaulted(String name)
1348: throws IOException, IllegalArgumentException
1349: {
1350: ObjectStreamField f = clazz.getField(name);
1351:
1352:
1353: if (f != null)
1354: {
1355:
1358: if (f.isPersistent() && !f.isToSet())
1359: return true;
1360:
1361: return false;
1362: }
1363:
1364:
1367: try
1368: {
1369: return (clazz.forClass().getDeclaredField (name) != null);
1370: }
1371: catch (NoSuchFieldException e)
1372: {
1373: throw new IllegalArgumentException(e);
1374: }
1375: }
1376:
1377: public boolean get(String name, boolean defvalue)
1378: throws IOException, IllegalArgumentException
1379: {
1380: ObjectStreamField field = getField(name, Boolean.TYPE);
1381:
1382: if (field == null)
1383: return defvalue;
1384:
1385: return prim_field_data[field.getOffset()] == 0 ? false : true;
1386: }
1387:
1388: public char get(String name, char defvalue)
1389: throws IOException, IllegalArgumentException
1390: {
1391: ObjectStreamField field = getField(name, Character.TYPE);
1392:
1393: if (field == null)
1394: return defvalue;
1395:
1396: int off = field.getOffset();
1397:
1398: return (char)(((prim_field_data[off++] & 0xFF) << 8)
1399: | (prim_field_data[off] & 0xFF));
1400: }
1401:
1402: public byte get(String name, byte defvalue)
1403: throws IOException, IllegalArgumentException
1404: {
1405: ObjectStreamField field = getField(name, Byte.TYPE);
1406:
1407: if (field == null)
1408: return defvalue;
1409:
1410: return prim_field_data[field.getOffset()];
1411: }
1412:
1413: public short get(String name, short defvalue)
1414: throws IOException, IllegalArgumentException
1415: {
1416: ObjectStreamField field = getField(name, Short.TYPE);
1417:
1418: if (field == null)
1419: return defvalue;
1420:
1421: int off = field.getOffset();
1422:
1423: return (short)(((prim_field_data[off++] & 0xFF) << 8)
1424: | (prim_field_data[off] & 0xFF));
1425: }
1426:
1427: public int get(String name, int defvalue)
1428: throws IOException, IllegalArgumentException
1429: {
1430: ObjectStreamField field = getField(name, Integer.TYPE);
1431:
1432: if (field == null)
1433: return defvalue;
1434:
1435: int off = field.getOffset();
1436:
1437: return ((prim_field_data[off++] & 0xFF) << 24)
1438: | ((prim_field_data[off++] & 0xFF) << 16)
1439: | ((prim_field_data[off++] & 0xFF) << 8)
1440: | (prim_field_data[off] & 0xFF);
1441: }
1442:
1443: public long get(String name, long defvalue)
1444: throws IOException, IllegalArgumentException
1445: {
1446: ObjectStreamField field = getField(name, Long.TYPE);
1447:
1448: if (field == null)
1449: return defvalue;
1450:
1451: int off = field.getOffset();
1452:
1453: return (long)(((prim_field_data[off++] & 0xFFL) << 56)
1454: | ((prim_field_data[off++] & 0xFFL) << 48)
1455: | ((prim_field_data[off++] & 0xFFL) << 40)
1456: | ((prim_field_data[off++] & 0xFFL) << 32)
1457: | ((prim_field_data[off++] & 0xFF) << 24)
1458: | ((prim_field_data[off++] & 0xFF) << 16)
1459: | ((prim_field_data[off++] & 0xFF) << 8)
1460: | (prim_field_data[off] & 0xFF));
1461: }
1462:
1463: public float get(String name, float defvalue)
1464: throws IOException, IllegalArgumentException
1465: {
1466: ObjectStreamField field = getField(name, Float.TYPE);
1467:
1468: if (field == null)
1469: return defvalue;
1470:
1471: int off = field.getOffset();
1472:
1473: return Float.intBitsToFloat(((prim_field_data[off++] & 0xFF) << 24)
1474: | ((prim_field_data[off++] & 0xFF) << 16)
1475: | ((prim_field_data[off++] & 0xFF) << 8)
1476: | (prim_field_data[off] & 0xFF));
1477: }
1478:
1479: public double get(String name, double defvalue)
1480: throws IOException, IllegalArgumentException
1481: {
1482: ObjectStreamField field = getField(name, Double.TYPE);
1483:
1484: if (field == null)
1485: return defvalue;
1486:
1487: int off = field.getOffset();
1488:
1489: return Double.longBitsToDouble
1490: ( (long) (((prim_field_data[off++] & 0xFFL) << 56)
1491: | ((prim_field_data[off++] & 0xFFL) << 48)
1492: | ((prim_field_data[off++] & 0xFFL) << 40)
1493: | ((prim_field_data[off++] & 0xFFL) << 32)
1494: | ((prim_field_data[off++] & 0xFF) << 24)
1495: | ((prim_field_data[off++] & 0xFF) << 16)
1496: | ((prim_field_data[off++] & 0xFF) << 8)
1497: | (prim_field_data[off] & 0xFF)));
1498: }
1499:
1500: public Object get(String name, Object defvalue)
1501: throws IOException, IllegalArgumentException
1502: {
1503: ObjectStreamField field =
1504: getField(name, defvalue == null ? null : defvalue.getClass ());
1505:
1506: if (field == null)
1507: return defvalue;
1508:
1509: return objs[field.getOffset()];
1510: }
1511:
1512: private ObjectStreamField getField(String name, Class type)
1513: throws IllegalArgumentException
1514: {
1515: ObjectStreamField field = clazz.getField(name);
1516: boolean illegal = false;
1517:
1518:
1519: try
1520: {
1521: try
1522: {
1523: Class field_type = field.getType();
1524:
1525: if (type == field_type ||
1526: (type == null && !field_type.isPrimitive()))
1527: {
1528:
1529: return field;
1530: }
1531:
1532: illegal = true;
1533: throw new IllegalArgumentException
1534: ("Field requested is of type "
1535: + field_type.getName()
1536: + ", but requested type was "
1537: + (type == null ? "Object" : type.getName()));
1538: }
1539: catch (NullPointerException _)
1540: {
1541:
1546: }
1547: catch (IllegalArgumentException e)
1548: {
1549: throw e;
1550: }
1551:
1552: return null;
1553: }
1554: finally
1555: {
1556:
1559: if (!illegal && field != null && !field.isToSet() && field.isPersistent())
1560: return null;
1561:
1562:
1565: try
1566: {
1567: Field f = clazz.forClass().getDeclaredField(name);
1568: if (Modifier.isTransient(f.getModifiers()))
1569: throw new IllegalArgumentException
1570: ("no such field (non transient) " + name);
1571: if (field == null && f.getType() != type)
1572: throw new IllegalArgumentException
1573: ("Invalid requested type for field " + name);
1574: }
1575: catch (NoSuchFieldException e)
1576: {
1577: if (field == null)
1578: throw new IllegalArgumentException(e);
1579: }
1580:
1581: }
1582: }
1583: };
1584:
1585: fieldsAlreadyRead = true;
1586: return prereadFields;
1587: }
1588:
1589:
1600: protected ObjectInputStream()
1601: throws IOException, SecurityException
1602: {
1603: SecurityManager sec_man = System.getSecurityManager();
1604: if (sec_man != null)
1605: sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1606: this.useSubclassMethod = true;
1607: }
1608:
1609:
1618: protected Object readObjectOverride()
1619: throws ClassNotFoundException, IOException, OptionalDataException
1620: {
1621: throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");
1622: }
1623:
1624:
1632: private int assignNewHandle(Object obj, boolean shared)
1633: {
1634: int handle = this.nextOID;
1635: this.nextOID = handle + 1;
1636: rememberHandle(obj,shared,handle);
1637: return handle;
1638: }
1639:
1640:
1650: private void rememberHandle(Object obj, boolean shared,
1651: int handle)
1652: {
1653: handles.put(handle, new Pair<Boolean,Object>(shared, obj));
1654: }
1655:
1656:
1665: private Object lookupHandle(int handle)
1666: throws ObjectStreamException
1667: {
1668: Pair<Boolean,Object> result = handles.get(handle);
1669: if (result == null)
1670: throw new StreamCorruptedException("The handle, " +
1671: Integer.toHexString(handle) +
1672: ", is invalid.");
1673: if (!result.getLeft())
1674: throw new InvalidObjectException("The handle, " +
1675: Integer.toHexString(handle) +
1676: ", is not shared.");
1677: return result.getRight();
1678: }
1679:
1680: private Object processResolution(ObjectStreamClass osc, Object obj, int handle,
1681: boolean shared)
1682: throws IOException
1683: {
1684: if (osc != null && obj instanceof Serializable)
1685: {
1686: try
1687: {
1688: Method m = osc.readResolveMethod;
1689: if(m != null)
1690: {
1691: obj = m.invoke(obj, new Object[] {});
1692: }
1693: }
1694: catch (IllegalAccessException ignore)
1695: {
1696: }
1697: catch (InvocationTargetException exception)
1698: {
1699: Throwable cause = exception.getCause();
1700: if (cause instanceof ObjectStreamException)
1701: throw (ObjectStreamException) cause;
1702: else if (cause instanceof RuntimeException)
1703: throw (RuntimeException) cause;
1704: else if (cause instanceof Error)
1705: throw (Error) cause;
1706: }
1707: }
1708:
1709: if (this.resolveEnabled)
1710: obj = resolveObject(obj);
1711:
1712: rememberHandle(obj, shared, handle);
1713: if (!shared)
1714: {
1715: if (obj instanceof byte[])
1716: return ((byte[]) obj).clone();
1717: if (obj instanceof short[])
1718: return ((short[]) obj).clone();
1719: if (obj instanceof int[])
1720: return ((int[]) obj).clone();
1721: if (obj instanceof long[])
1722: return ((long[]) obj).clone();
1723: if (obj instanceof char[])
1724: return ((char[]) obj).clone();
1725: if (obj instanceof boolean[])
1726: return ((boolean[]) obj).clone();
1727: if (obj instanceof float[])
1728: return ((float[]) obj).clone();
1729: if (obj instanceof double[])
1730: return ((double[]) obj).clone();
1731: if (obj instanceof Object[])
1732: return ((Object[]) obj).clone();
1733: }
1734: return obj;
1735: }
1736:
1737: private void clearHandles()
1738: {
1739: handles.clear();
1740: this.nextOID = baseWireHandle;
1741: }
1742:
1743: private void readNextBlock() throws IOException
1744: {
1745: byte marker = this.realInputStream.readByte();
1746: while (marker == TC_RESET)
1747: {
1748: if(dump) dumpElementln("RESET");
1749: clearHandles();
1750: marker = this.realInputStream.readByte();
1751: }
1752: readNextBlock(marker);
1753: }
1754:
1755: private void readNextBlock(byte marker) throws IOException
1756: {
1757: if (marker == TC_BLOCKDATA)
1758: {
1759: if(dump) dumpElement("BLOCK DATA SIZE=");
1760: this.blockDataBytes = this.realInputStream.readUnsignedByte();
1761: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1762: }
1763: else if (marker == TC_BLOCKDATALONG)
1764: {
1765: if(dump) dumpElement("BLOCK DATA LONG SIZE=");
1766: this.blockDataBytes = this.realInputStream.readInt();
1767: if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
1768: }
1769: else
1770: {
1771: throw new EOFException("Attempt to read primitive data, but no data block is active.");
1772: }
1773:
1774: if (this.blockData.length < this.blockDataBytes)
1775: this.blockData = new byte[this.blockDataBytes];
1776:
1777: this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
1778: this.blockDataPosition = 0;
1779: }
1780:
1781: private void readArrayElements (Object array, Class clazz)
1782: throws ClassNotFoundException, IOException
1783: {
1784: if (clazz.isPrimitive())
1785: {
1786: if (clazz == Boolean.TYPE)
1787: {
1788: boolean[] cast_array = (boolean[])array;
1789: for (int i=0; i < cast_array.length; i++)
1790: cast_array[i] = this.realInputStream.readBoolean();
1791: return;
1792: }
1793: if (clazz == Byte.TYPE)
1794: {
1795: byte[] cast_array = (byte[])array;
1796: for (int i=0; i < cast_array.length; i++)
1797: cast_array[i] = this.realInputStream.readByte();
1798: return;
1799: }
1800: if (clazz == Character.TYPE)
1801: {
1802: char[] cast_array = (char[])array;
1803: for (int i=0; i < cast_array.length; i++)
1804: cast_array[i] = this.realInputStream.readChar();
1805: return;
1806: }
1807: if (clazz == Double.TYPE)
1808: {
1809: double[] cast_array = (double[])array;
1810: for (int i=0; i < cast_array.length; i++)
1811: cast_array[i] = this.realInputStream.readDouble();
1812: return;
1813: }
1814: if (clazz == Float.TYPE)
1815: {
1816: float[] cast_array = (float[])array;
1817: for (int i=0; i < cast_array.length; i++)
1818: cast_array[i] = this.realInputStream.readFloat();
1819: return;
1820: }
1821: if (clazz == Integer.TYPE)
1822: {
1823: int[] cast_array = (int[])array;
1824: for (int i=0; i < cast_array.length; i++)
1825: cast_array[i] = this.realInputStream.readInt();
1826: return;
1827: }
1828: if (clazz == Long.TYPE)
1829: {
1830: long[] cast_array = (long[])array;
1831: for (int i=0; i < cast_array.length; i++)
1832: cast_array[i] = this.realInputStream.readLong();
1833: return;
1834: }
1835: if (clazz == Short.TYPE)
1836: {
1837: short[] cast_array = (short[])array;
1838: for (int i=0; i < cast_array.length; i++)
1839: cast_array[i] = this.realInputStream.readShort();
1840: return;
1841: }
1842: }
1843: else
1844: {
1845: Object[] cast_array = (Object[])array;
1846: for (int i=0; i < cast_array.length; i++)
1847: cast_array[i] = readObject();
1848: }
1849: }
1850:
1851: private void readFields (Object obj, ObjectStreamClass stream_osc)
1852: throws ClassNotFoundException, IOException
1853: {
1854: ObjectStreamField[] fields = stream_osc.fieldMapping;
1855:
1856: for (int i = 0; i < fields.length; i += 2)
1857: {
1858: ObjectStreamField stream_field = fields[i];
1859: ObjectStreamField real_field = fields[i + 1];
1860: boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
1861: boolean set_value = (real_field != null && real_field.isToSet());
1862: String field_name;
1863: char type;
1864:
1865: if (stream_field != null)
1866: {
1867: field_name = stream_field.getName();
1868: type = stream_field.getTypeCode();
1869: }
1870: else
1871: {
1872: field_name = real_field.getName();
1873: type = real_field.getTypeCode();
1874: }
1875:
1876: switch(type)
1877: {
1878: case 'Z':
1879: {
1880: boolean value =
1881: read_value ? this.realInputStream.readBoolean() : false;
1882: if (dump && read_value && set_value)
1883: dumpElementln(" " + field_name + ": " + value);
1884: if (set_value)
1885: real_field.setBooleanField(obj, value);
1886: break;
1887: }
1888: case 'B':
1889: {
1890: byte value =
1891: read_value ? this.realInputStream.readByte() : 0;
1892: if (dump && read_value && set_value)
1893: dumpElementln(" " + field_name + ": " + value);
1894: if (set_value)
1895: real_field.setByteField(obj, value);
1896: break;
1897: }
1898: case 'C':
1899: {
1900: char value =
1901: read_value ? this.realInputStream.readChar(): 0;
1902: if (dump && read_value && set_value)
1903: dumpElementln(" " + field_name + ": " + value);
1904: if (set_value)
1905: real_field.setCharField(obj, value);
1906: break;
1907: }
1908: case 'D':
1909: {
1910: double value =
1911: read_value ? this.realInputStream.readDouble() : 0;
1912: if (dump && read_value && set_value)
1913: dumpElementln(" " + field_name + ": " + value);
1914: if (set_value)
1915: real_field.setDoubleField(obj, value);
1916: break;
1917: }
1918: case 'F':
1919: {
1920: float value =
1921: read_value ? this.realInputStream.readFloat() : 0;
1922: if (dump && read_value && set_value)
1923: dumpElementln(" " + field_name + ": " + value);
1924: if (set_value)
1925: real_field.setFloatField(obj, value);
1926: break;
1927: }
1928: case 'I':
1929: {
1930: int value =
1931: read_value ? this.realInputStream.readInt() : 0;
1932: if (dump && read_value && set_value)
1933: dumpElementln(" " + field_name + ": " + value);
1934: if (set_value)
1935: real_field.setIntField(obj, value);
1936: break;
1937: }
1938: case 'J':
1939: {
1940: long value =
1941: read_value ? this.realInputStream.readLong() : 0;
1942: if (dump && read_value && set_value)
1943: dumpElementln(" " + field_name + ": " + value);
1944: if (set_value)
1945: real_field.setLongField(obj, value);
1946: break;
1947: }
1948: case 'S':
1949: {
1950: short value =
1951: read_value ? this.realInputStream.readShort() : 0;
1952: if (dump && read_value && set_value)
1953: dumpElementln(" " + field_name + ": " + value);
1954: if (set_value)
1955: real_field.setShortField(obj, value);
1956: break;
1957: }
1958: case 'L':
1959: case '[':
1960: {
1961: Object value =
1962: read_value ? readObject() : null;
1963: if (set_value)
1964: real_field.setObjectField(obj, value);
1965: break;
1966: }
1967: default:
1968: throw new InternalError("Invalid type code: " + type);
1969: }
1970: }
1971: }
1972:
1973:
1974: private boolean setBlockDataMode (boolean on)
1975: {
1976: boolean oldmode = this.readDataFromBlock;
1977: this.readDataFromBlock = on;
1978:
1979: if (on)
1980: this.dataInputStream = this.blockDataInput;
1981: else
1982: this.dataInputStream = this.realInputStream;
1983: return oldmode;
1984: }
1985:
1986:
1987:
1988: private Object newObject (Class real_class, Constructor constructor)
1989: throws ClassNotFoundException, IOException
1990: {
1991: if (constructor == null)
1992: throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
1993: try
1994: {
1995: return VMObjectInputStream.allocateObject(real_class, constructor.getDeclaringClass(), constructor);
1996: }
1997: catch (InstantiationException e)
1998: {
1999: throw (ClassNotFoundException) new ClassNotFoundException
2000: ("Instance of " + real_class + " could not be created").initCause(e);
2001: }
2002: }
2003:
2004:
2005:
2006: private void invokeValidators() throws InvalidObjectException
2007: {
2008: try
2009: {
2010: Iterator<ValidatorAndPriority> it = currentObjectValidators.iterator();
2011: while(it.hasNext())
2012: {
2013: ValidatorAndPriority vap = it.next();
2014: ObjectInputValidation validator = vap.validator;
2015: validator.validateObject();
2016: }
2017: }
2018: finally
2019: {
2020: currentObjectValidators = null;
2021: }
2022: }
2023:
2024: private void callReadMethod (Method readObject, Class klass, Object obj)
2025: throws ClassNotFoundException, IOException
2026: {
2027: try
2028: {
2029: readObject.invoke(obj, new Object[] { this });
2030: }
2031: catch (InvocationTargetException x)
2032: {
2033:
2034: Throwable exception = x.getTargetException();
2035: if (exception instanceof RuntimeException)
2036: throw (RuntimeException) exception;
2037: if (exception instanceof IOException)
2038: throw (IOException) exception;
2039: if (exception instanceof ClassNotFoundException)
2040: throw (ClassNotFoundException) exception;
2041:
2042: throw (IOException) new IOException(
2043: "Exception thrown from readObject() on " + klass).initCause(x);
2044: }
2045: catch (Exception x)
2046: {
2047: throw (IOException) new IOException(
2048: "Failure invoking readObject() on " + klass).initCause(x);
2049: }
2050:
2051:
2052: prereadFields = null;
2053: }
2054:
2055: private static final int BUFFER_SIZE = 1024;
2056:
2057: private DataInputStream realInputStream;
2058: private DataInputStream dataInputStream;
2059: private DataInputStream blockDataInput;
2060: private int blockDataPosition;
2061: private int blockDataBytes;
2062: private byte[] blockData;
2063: private boolean useSubclassMethod;
2064: private int nextOID;
2065: private boolean resolveEnabled;
2066: private Map<Integer,Pair<Boolean,Object>> handles;
2067: private Object currentObject;
2068: private ObjectStreamClass currentObjectStreamClass;
2069: private TreeSet<ValidatorAndPriority> currentObjectValidators;
2070: private boolean readDataFromBlock;
2071: private boolean fieldsAlreadyRead;
2072: private Hashtable<Class,ObjectStreamClass> classLookupTable;
2073: private GetField prereadFields;
2074:
2075: private static boolean dump;
2076:
2077:
2078: private int depth = 0;
2079:
2080: private static final boolean DEBUG = false;
2081:
2082: private void dumpElement (String msg)
2083: {
2084: System.out.print(msg);
2085: }
2086:
2087: private void dumpElementln (String msg)
2088: {
2089: System.out.println(msg);
2090: for (int i = 0; i < depth; i++)
2091: System.out.print (" ");
2092: System.out.print (Thread.currentThread() + ": ");
2093: }
2094:
2095: private void dumpElementln (String msg, Object obj)
2096: {
2097: try
2098: {
2099: System.out.print(msg);
2100: if (java.lang.reflect.Proxy.isProxyClass(obj.getClass()))
2101: System.out.println(obj.getClass());
2102: else
2103: System.out.println(obj);
2104: }
2105: catch (Exception _)
2106: {
2107: }
2108: for (int i = 0; i < depth; i++)
2109: System.out.print (" ");
2110: System.out.print (Thread.currentThread() + ": ");
2111: }
2112:
2113:
2114: private static final class ValidatorAndPriority implements Comparable
2115: {
2116: int priority;
2117: ObjectInputValidation validator;
2118:
2119: ValidatorAndPriority (ObjectInputValidation validator, int priority)
2120: {
2121: this.priority = priority;
2122: this.validator = validator;
2123: }
2124:
2125: public int compareTo (Object o)
2126: {
2127: ValidatorAndPriority vap = (ValidatorAndPriority)o;
2128: return this.priority - vap.priority;
2129: }
2130: }
2131: }