diff --git a/src/one/nio/serial/EnumSerializer.java b/src/one/nio/serial/EnumSerializer.java index f3566fb..7d223bd 100755 --- a/src/one/nio/serial/EnumSerializer.java +++ b/src/one/nio/serial/EnumSerializer.java @@ -28,51 +28,55 @@ public class EnumSerializer extends Serializer { static final AtomicInteger enumCountMismatches = new AtomicInteger(); static final AtomicInteger enumMissedConstants = new AtomicInteger(); + private String[] names; private Enum[] values; EnumSerializer(Class cls) { super(cls); this.values = cls().getEnumConstants(); + this.names = new String[values.length]; + for (int i = 0; i < names.length; i++) { + names[i] = values[i].name(); + } } @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); - Enum[] ownValues = cls().getEnumConstants(); - out.writeShort(ownValues.length); - for (Enum v : ownValues) { - out.writeUTF(v.name()); + out.writeShort(names.length); + for (String name : names) { + out.writeUTF(name); } } @Override @SuppressWarnings("unchecked") public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - String[] constants = new String[in.readUnsignedShort()]; - for (int i = 0; i < constants.length; i++) { - constants[i] = in.readUTF(); + this.names = new String[in.readUnsignedShort()]; + for (int i = 0; i < names.length; i++) { + names[i] = in.readUTF(); } try { super.readExternal(in); } catch (ClassNotFoundException e) { if ((Repository.getOptions() & Repository.ENUM_STUBS) == 0) throw e; - this.cls = StubGenerator.generateEnum(uniqueName("Enum"), constants); + this.cls = StubGenerator.generateEnum(uniqueName("Enum"), names); this.origin = Origin.GENERATED; } Enum[] ownValues = cls().getEnumConstants(); - if (ownValues.length != constants.length) { + if (ownValues.length != names.length) { Repository.log.warn("[" + Long.toHexString(uid) + "] Enum count mismatch for " + descriptor + ": " + - ownValues.length + " local vs. " + constants.length + " stream constants"); + ownValues.length + " local vs. " + names.length + " stream constants"); enumCountMismatches.incrementAndGet(); } // 1. Find exact matches EnumSet usedConstants = EnumSet.noneOf(cls); - this.values = new Enum[constants.length]; - for (int i = 0; i < constants.length; i++) { - values[i] = findMatch(constants[i], usedConstants); + this.values = new Enum[names.length]; + for (int i = 0; i < names.length; i++) { + values[i] = findMatch(names[i], usedConstants); } // 2. Handle renaming diff --git a/test/one/nio/serial/SerializationTest.java b/test/one/nio/serial/SerializationTest.java index 55e49dc..7515007 100755 --- a/test/one/nio/serial/SerializationTest.java +++ b/test/one/nio/serial/SerializationTest.java @@ -18,6 +18,7 @@ import one.nio.serial.sample.Sample; import one.nio.util.Base64; +import one.nio.util.Utf8; import org.junit.Test; import java.io.IOException; @@ -242,6 +243,27 @@ public void testEnum() throws IOException, ClassNotFoundException { checkSerialize(new EnumSerializer(ComplexEnum.class)); } + private enum MagicEnum { + MAGIC1, MAGIC2, MAGIC3 + } + + @Test + public void testEnumDoubleConvert() throws IOException, ClassNotFoundException { + Serializer enumSerializer = Repository.get(MagicEnum.class); + byte[] bytes = Serializer.serialize(enumSerializer); + + Repository.removeSerializer(enumSerializer.uid); + + // Exchange the order of MAGIC1 and MAGIC3 in the serialized form + int m1 = Utf8.indexOf(MagicEnum.MAGIC1.name().getBytes(), bytes); + int m3 = Utf8.indexOf(MagicEnum.MAGIC3.name().getBytes(), bytes); + bytes[m1 + 5] = '3'; + bytes[m3 + 5] = '1'; + + byte[] copy = Serializer.serialize(Serializer.deserialize(bytes)); + assertArrayEquals(bytes, copy); + } + @Test public void testUrls() throws IOException, ClassNotFoundException, URISyntaxException { checkSerialize(new URI("socket://192.168.0.1:2222/?param1=value1¶m2=value2"));