/** * Deserializes an object from the given stream. * * @param in the data input stream, from which the object is deserialized * @return the serializable object * @throws IOException when serialization data could not be read or the Serializable class could * not get instantiated */ public static Object deserialize(DataInputStream in) throws IOException { byte version = in.readByte(); // #if polish.debug.warn if (version > VERSION) { // #debug warn System.out.println( "Warning: trying to deserialize class that has been serialized with a newer version (" + version + ">" + VERSION + ")."); } // #endif boolean isNull = in.readBoolean(); if (isNull) { return null; } byte type = in.readByte(); switch (type) { case TYPE_EXTERNALIZABLE: String className = in.readUTF(); // #if polish.JavaSE if (obfuscationDeserializeMap != null) { String fullClassName = (String) obfuscationDeserializeMap.get(className); if (fullClassName != null) { // System.out.println("Serializer.deserialize: translating classname from " + className // + " to " + fullClassName ); className = fullClassName; } } // #endif // #debug debug // #= System.out.println("deserialize " + className + "..."); Externalizable extern = null; try { extern = (Externalizable) Class.forName(className).newInstance(); } catch (Exception e) { // #debug error System.out.println("Unable to instantiate serializable \"" + className + "\"" + e); throw new IOException(e.toString()); } extern.read(in); return extern; case TYPE_EXTERNALIZABLE_ARRAY: String cn = in.readUTF(); // #if polish.JavaSE if (obfuscationDeserializeMap != null) { String fullClassName = (String) obfuscationDeserializeMap.get(cn); if (fullClassName != null) { // System.out.println("Serializer.deserialize: translating classname from " + cn + " to // " + fullClassName ); cn = fullClassName; } } // #endif int length = in.readInt(); Externalizable[] externalizables; // #if !polish.JavaSE externalizables = new Externalizable[length]; // #else try { // #if false externalizables = null; // #else // # externalizables = (Externalizable[]) Array.newInstance(Class.forName( cn ), length); // #endif } catch (Exception e) { // #debug error System.out.println("Unable to instantiate Serializable \"" + cn + "\"" + e); throw new IOException(e.toString()); } // #endif Class[] classes = new Class[Math.min(length, 7)]; Class currentClass; byte idCounter = 0; for (int i = 0; i < externalizables.length; i++) { int classId = in.readByte(); if (classId == 0) { // new class name className = in.readUTF(); // #if polish.JavaSE if (obfuscationDeserializeMap != null) { String fullClassName = (String) obfuscationDeserializeMap.get(className); if (fullClassName != null) { // System.out.println("Serializer.deserialize: translating classname from " + // className + " to " + fullClassName ); className = fullClassName; } } // #endif try { currentClass = Class.forName(className); } catch (ClassNotFoundException e) { // #debug error System.out.println("Unable to load Serializable class \"" + className + "\"" + e); throw new IOException(e.toString()); } if (idCounter > classes.length) { Class[] newClasses = new Class[classes.length + 7]; System.arraycopy(classes, 0, newClasses, 0, classes.length); classes = newClasses; } classes[idCounter] = currentClass; idCounter++; } else { currentClass = classes[classId - 1]; } Externalizable externalizable; try { externalizable = (Externalizable) currentClass.newInstance(); externalizable.read(in); externalizables[i] = externalizable; } catch (Exception e) { // #debug error System.out.println( "Unable to instantiate Serializable \"" + currentClass.getName() + "\"" + e); throw new IOException(e.toString()); } } return externalizables; case TYPE_OBJECT_ARRAY: length = in.readInt(); Object[] objects = new Object[length]; for (int i = 0; i < objects.length; i++) { objects[i] = deserialize(in); } return objects; case TYPE_BYTE: return new Byte(in.readByte()); case TYPE_SHORT: return new Short(in.readShort()); case TYPE_INTEGER: return new Integer(in.readInt()); case TYPE_LONG: return new Long(in.readLong()); // #if polish.hasFloatingPoint case TYPE_FLOAT: return new Float(in.readFloat()); case TYPE_DOUBLE: return new Double(in.readDouble()); // #endif case TYPE_STRING: return in.readUTF(); case TYPE_STRING_BUFFER: return new StringBuffer(in.readUTF()); case TYPE_CHARACTER: return new Character(in.readChar()); case TYPE_BOOLEAN: return new Boolean(in.readBoolean()); case TYPE_DATE: return new Date(in.readLong()); case TYPE_CALENDAR: Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date(in.readLong())); return calendar; case TYPE_RANDOM: return new Random(); case TYPE_HASHTABLE: int size = in.readInt(); Hashtable hashtable = new Hashtable(size); for (int i = 0; i < size; i++) { Object key = deserialize(in); Object value = deserialize(in); hashtable.put(key, value); } return hashtable; case TYPE_STACK: case TYPE_VECTOR: size = in.readInt(); Vector vector; if (type == TYPE_STACK) { vector = new Stack(); } else { vector = new Vector(size); } for (int i = 0; i < size; i++) { Object value = deserialize(in); vector.addElement(value); } return vector; // #if polish.midp2 case TYPE_IMAGE: byte subType = in.readByte(); if (subType == TYPE_IMAGE_RGB) { int width = in.readInt(); int height = in.readInt(); int[] rgb = new int[width * height]; for (int i = 0; i < rgb.length; i++) { rgb[i] = in.readInt(); } return Image.createRGBImage(rgb, width, height, true); } // this is a bytes based format like png: int bytesLength = in.readInt(); byte[] buffer = new byte[bytesLength]; in.readFully(buffer); return Image.createImage(buffer, 0, bytesLength); // #endif // #if polish.midp case TYPE_FONT: int face = in.readInt(); int style = in.readInt(); size = in.readInt(); return Font.getFont(face, style, size); case TYPE_COMMAND: int cmdType = in.readInt(); int priority = in.readInt(); String label = in.readUTF(); return new Command(label, cmdType, priority); // #endif case TYPE_BYTE_ARRAY: length = in.readInt(); byte[] byteNumbers = new byte[length]; in.readFully(byteNumbers); return byteNumbers; case TYPE_SHORT_ARRAY: length = in.readInt(); short[] shortNumbers = new short[length]; for (int i = 0; i < length; i++) { shortNumbers[i] = in.readShort(); } return shortNumbers; case TYPE_INT_ARRAY: length = in.readInt(); int[] intNumbers = new int[length]; for (int i = 0; i < length; i++) { intNumbers[i] = in.readInt(); } return intNumbers; case TYPE_LONG_ARRAY: length = in.readInt(); long[] longNumbers = new long[length]; for (int i = 0; i < length; i++) { longNumbers[i] = in.readLong(); } return longNumbers; // #if polish.hasFloatingPoint case TYPE_FLOAT_ARRAY: length = in.readInt(); float[] floatNumbers = new float[length]; for (int i = 0; i < length; i++) { floatNumbers[i] = in.readFloat(); } return floatNumbers; case TYPE_DOUBLE_ARRAY: length = in.readInt(); double[] doubleNumbers = new double[length]; for (int i = 0; i < length; i++) { doubleNumbers[i] = in.readDouble(); } return doubleNumbers; // #endif case TYPE_CHAR_ARRAY: length = in.readInt(); char[] characters = new char[length]; for (int i = 0; i < length; i++) { characters[i] = in.readChar(); } return characters; case TYPE_BOOLEAN_ARRAY: length = in.readInt(); boolean[] bools = new boolean[length]; for (int i = 0; i < length; i++) { bools[i] = in.readBoolean(); } return bools; case TYPE_STRING_ARRAY: length = in.readInt(); String[] strings = new String[length]; for (int i = 0; i < length; i++) { strings[i] = in.readUTF(); } return strings; default: throw new IOException("Unknown type: " + type); } }
/** * Reads an object directly from a byte array * * @param data the serialized data * @return the original object * @throws IOException when serialization fails * @see #serialize(Object, boolean) */ public static void deserialize(byte[] data, Externalizable object) throws IOException { ByteArrayInputStream byteIn = new ByteArrayInputStream(data); DataInputStream in = new DataInputStream(byteIn); object.read(in); }