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