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