Fixing the bug 157196: custom serialization of ScriptableObject not to save deleted/empty slot.

This commit is contained in:
igor%mir2.org 2002-07-16 21:15:51 +00:00
Родитель b9861f3df6
Коммит 05d4e426a8
1 изменённых файлов: 69 добавлений и 11 удалений

Просмотреть файл

@ -1355,8 +1355,10 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
* *
* @since 1.4R3 * @since 1.4R3
*/ */
public void sealObject() { public synchronized void sealObject() {
count = -1; if (count >= 0) {
count = -1 - count;
}
} }
/** /**
@ -1369,7 +1371,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
* @since 1.4R3 * @since 1.4R3
*/ */
public boolean isSealed() { public boolean isSealed() {
return count == -1; return count < 0;
} }
/** /**
@ -1565,7 +1567,8 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
Object fun = getProperty(obj, methodName); Object fun = getProperty(obj, methodName);
if (fun == NOT_FOUND) if (fun == NOT_FOUND)
fun = methodName; fun = methodName;
return ScriptRuntime.call(cx, fun, obj, args, getTopLevelScope(obj)); return ScriptRuntime.call(cx, fun, obj, args,
getTopLevelScope(obj));
} finally { } finally {
Context.exit(); Context.exit();
} }
@ -1684,7 +1687,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
* caused the table to grow while this thread was searching. * caused the table to grow while this thread was searching.
*/ */
private synchronized Slot addSlot(String id, int index, Slot newSlot) { private synchronized Slot addSlot(String id, int index, Slot newSlot) {
if (count == -1) if (count < 0)
throw Context.reportRuntimeError0("msg.add.sealed"); throw Context.reportRuntimeError0("msg.add.sealed");
if (slots == null) { slots = new Slot[5]; } if (slots == null) { slots = new Slot[5]; }
@ -1732,7 +1735,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
* deletes are not common. * deletes are not common.
*/ */
private synchronized void removeSlot(String name, int index) { private synchronized void removeSlot(String name, int index) {
if (count == -1) if (count < 0)
throw Context.reportRuntimeError0("msg.remove.sealed"); throw Context.reportRuntimeError0("msg.remove.sealed");
getSlot(name, index, true); getSlot(name, index, true);
} }
@ -1800,11 +1803,53 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
return result; return result;
} }
private synchronized void writeObject(ObjectOutputStream out)
throws IOException
{
out.defaultWriteObject();
int N = count;
if (N < 0) {
N = -1 - count;
}
Slot[] s = slots;
if (s == null) {
if (N != 0) Context.codeBug();
out.writeInt(0);
} else {
out.writeInt(s.length);
for (int i = 0; N != 0; ++i) {
Slot slot = s[i];
if (slot != null && slot != REMOVED) {
--N;
out.writeObject(slot);
}
}
}
}
private void readObject(ObjectInputStream in) private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
in.defaultReadObject(); in.defaultReadObject();
lastAccess = REMOVED; lastAccess = REMOVED;
int capacity = in.readInt();
if (capacity != 0) {
slots = new Slot[capacity];
int N = count;
boolean wasSealed = false;
if (N < 0) {
N = -1 - N; wasSealed = true;
}
count = 0;
for (int i = 0; i != N; ++i) {
Slot s = (Slot)in.readObject();
addSlotImpl(s.stringKey, s.intKey, s);
}
if (wasSealed) {
count = - 1 - count;
}
}
} }
/** /**
@ -1821,22 +1866,35 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
private static final Slot REMOVED = new Slot(); private static final Slot REMOVED = new Slot();
private static Hashtable exclusionList = null; private static Hashtable exclusionList = null;
private Slot[] slots; private transient Slot[] slots;
// If count >= 0, it gives number of keys or if count < 0,
// it indicates sealed object where -1 - count gives number of keys
private int count; private int count;
// cache; may be removed for smaller memory footprint // cache; may be removed for smaller memory footprint
transient private Slot lastAccess = REMOVED; private transient Slot lastAccess = REMOVED;
private static class Slot implements Serializable { private static class Slot implements Serializable {
static final int HAS_GETTER = 0x01; static final int HAS_GETTER = 0x01;
static final int HAS_SETTER = 0x02; static final int HAS_SETTER = 0x02;
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
if (stringKey != null) {
intKey = stringKey.hashCode();
}
}
static final long serialVersionUID = -2158009919774350004L;
int intKey; int intKey;
String stringKey; String stringKey;
Object value; Object value;
short attributes; short attributes;
byte flags; byte flags;
byte wasDeleted; transient byte wasDeleted;
} }
static class GetterSlot extends Slot implements Serializable { static class GetterSlot extends Slot implements Serializable {