writeNewClassDescFor((Class<?>)obj);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
return;
} else if (obj instanceof ObjectStreamClass) {
throw new NotSerializableException(ObjectStreamClass.class.getName());
}
// - next check for replacements
// - first, check for implemented writeReplace method on the object
final SerializableClassRegistry registry = this.registry;
for (;;) {
final Class<? extends Object> objClass = obj.getClass();
final SerializableClass sc = registry.lookup(objClass);
if (!sc.hasWriteReplace()) {
break;
}
final Object replacement = sc.callWriteReplace(obj);
try {
if (replacement == null || replacement == obj || obj.getClass() == objClass) {
break;
}
} finally {
obj = replacement;
}
}
obj = objectResolver.writeReplace(obj);
// - next, if the object was replaced we do our original checks again...
if (obj != orig) {
// cache the replacement
replacementCache.put(orig, obj);
if (obj == null) {
write(TC_NULL);
return;
} else if (! unshared && (v = instanceCache.get(obj, -1)) != -1) {
write(TC_REFERENCE);
writeInt(v);
return;
} else if (obj instanceof Class) {
write(TC_CLASS);
writeNewClassDescFor((Class<?>)obj);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
return;
} else if (obj instanceof ObjectStreamClass) {
throw new NotSerializableException(ObjectStreamClass.class.getName());
}
}
// - next check for other special types
if (obj instanceof String) {
final String string = (String) obj;
final long len = UTFUtils.getLongUTFLength(string);
if (len < 65536L) {
write(TC_STRING);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
writeShort((int) len);
UTFUtils.writeUTFBytes(this, string);
return;
} else {
write(TC_LONGSTRING);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
writeLong(len);
UTFUtils.writeUTFBytes(this, string);
return;
}
}
final Class<?> objClass = obj.getClass();
if (obj instanceof Enum) {
write(TC_ENUM);
final Enum theEnum = (Enum) obj;
writeClassDescFor(theEnum.getDeclaringClass());
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
doWriteObject(theEnum.name(), false);
return;
} else if (objClass.isArray()) {
write(TC_ARRAY);
writeClassDescFor(objClass);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
if (obj instanceof byte[]) {
final byte[] bytes = (byte[]) obj;
writeInt(bytes.length);
write(bytes);
} else if (obj instanceof short[]) {
final short[] shorts = (short[]) obj;
writeInt(shorts.length);
for (short s : shorts) {
writeShort(s);
}
} else if (obj instanceof int[]) {
final int[] ints = (int[]) obj;
writeInt(ints.length);
for (int s : ints) {
writeInt(s);
}
} else if (obj instanceof long[]) {
final long[] longs = (long[]) obj;
writeInt(longs.length);
for (long s : longs) {
writeLong(s);
}
} else if (obj instanceof float[]) {
final float[] floats = (float[]) obj;
writeInt(floats.length);
for (float s : floats) {
writeFloat(s);
}
} else if (obj instanceof double[]) {
final double[] doubles = (double[]) obj;
writeInt(doubles.length);
for (double s : doubles) {
writeDouble(s);
}
} else if (obj instanceof boolean[]) {
final boolean[] booleans = (boolean[]) obj;
writeInt(booleans.length);
for (boolean s : booleans) {
writeBoolean(s);
}
} else if (obj instanceof char[]) {
final char[] chars = (char[]) obj;
writeInt(chars.length);
for (char s : chars) {
writeChar(s);
}
} else {
final Object[] objs = (Object[]) obj;
writeInt(objs.length);
for (Object o : objs) {
doWriteObject(o, false);
}
}
return;
}
Externalizer externalizer;
if (externalizers.containsKey(objClass)) {
externalizer = externalizers.get(objClass);
} else {
externalizer = classExternalizerFactory.getExternalizer(objClass);
externalizers.put(objClass, externalizer);
}
if (externalizer != null) {
final ExternalizedObject eo = new ExternalizedObject(externalizer, obj);
doWriteObject(eo, unshared);
replacementCache.put(obj, eo);
return;
} else if (obj instanceof Externalizable) {
write(TC_OBJECT);
writeClassDescFor(objClass);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
final Externalizable externalizable = (Externalizable) obj;
externalizable.writeExternal(blockMarshaller);
doEndBlock();
return;
} else if (serializabilityChecker.isSerializable(objClass)) {
write(TC_OBJECT);
writeClassDescFor(objClass);
final int id = instanceSeq++;
if (! unshared) instanceCache.put(obj, id);
writeSerialData(objClass, obj);
return;
} else {
throw new NotSerializableException(objClass.getName());
}
}