package NET.worlds.scape; import NET.worlds.network.URL; import java.io.DataOutput; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; public class Saver { static final String headerString = "PERSISTER Worlds, Inc."; static final String trailerString = "END PERSISTER"; private static int _version = 7; private DataOutput os; private boolean myFile; private Hashtable classTable; private Hashtable objectTable; private Hashtable cookieTable; private URL reference; public static int version() { return _version; } public URL getReferenceURL() { return this.reference; } public Saver(URL url) throws IOException { this(new DataOutputStream(new FileOutputStream(new File(url.unalias())))); this.reference = url; this.myFile = true; } public Saver(DataOutput os) throws IOException { this.os = os; this.saveString("PERSISTER Worlds, Inc."); this.saveInt(_version); this.classTable = new Hashtable(); this.objectTable = new Hashtable(); this.cookieTable = new Hashtable(); } public void saveVersion(int v, Object cookie) throws IOException { Integer oldv = (Integer)this.cookieTable.get(cookie); if (oldv == null) { this.saveInt(v); this.cookieTable.put(cookie, new Integer(v)); } else { assert oldv == v; } } public void save(Persister p) throws IOException { assert !(p instanceof NonPersister); int hashed = UniqueHasher.uh().hash(p); this.saveInt(hashed); if (!this.objectTable.containsKey(p)) { this.objectTable.put(p, p); this.saveClass(p.getClass()); p.saveState(this); } } public void saveVectorMaybeNull(Vector v) throws IOException { if (v == null) { this.saveBoolean(false); } else { this.saveBoolean(true); this.saveVector(v); } } public void saveMaybeNull(Persister p) throws IOException { if (p != null && !(p instanceof NonPersister)) { this.saveBoolean(false); this.save(p); } else { this.saveBoolean(true); } } public void saveClass(Class c) throws IOException { UniqueHasher uh = UniqueHasher.uh(); this.saveInt(uh.hash(c.toString())); if (!this.classTable.containsKey(c)) { this.saveString(c.getName()); this.classTable.put(c, c); } } public void saveArray(Persister[] pa) throws IOException { this.saveClass(pa.getClass()); this.saveInt(pa.length); for (int i = 0; i < pa.length; i++) { this.saveMaybeNull(pa[i]); } } public void saveVector(Vector v) throws IOException { synchronized (v) { Enumeration en = v.elements(); int length = 0; while (en.hasMoreElements()) { Object obj = en.nextElement(); if (obj instanceof Persister && !(obj instanceof NonPersister)) { length++; } } this.saveInt(length); en = v.elements(); while (en.hasMoreElements()) { Object obj = en.nextElement(); if (obj instanceof Persister && !(obj instanceof NonPersister)) { this.save((Persister)obj); } } } } public void saveString(String str) throws IOException { this.saveBoolean(str == null); if (str != null) { this.os.writeUTF(str); } } public void saveBoolean(boolean b) throws IOException { this.os.writeBoolean(b); } public void saveByte(byte b) throws IOException { this.os.writeByte(b); } public void saveShort(short s) throws IOException { this.os.writeShort(s); } public void saveInt(int i) throws IOException { this.os.writeInt(i); } public void saveLong(long g) throws IOException { this.os.writeLong(g); } public void saveFloat(float f) throws IOException { this.os.writeFloat(f); } public void saveDouble(double d) throws IOException { this.os.writeDouble(d); } public void done() throws IOException { this.saveString("END PERSISTER"); if (this.myFile) { ((DataOutputStream)this.os).close(); } this.classTable = null; this.objectTable = null; this.cookieTable = null; } }