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