From cf8f02cdad8ac66a5fbdb4cdb4a75be81f78eb11 Mon Sep 17 00:00:00 2001 From: Barend Garvelink Date: Tue, 10 Nov 2020 21:04:20 +0100 Subject: [PATCH] reduces size of serialised form by 15-20 percent This trims some overhead from the serialised form. The sample IBAN used in the unit test drops from 101 bytes to 82 bytes. The drop gets smaller the longer the IBAN, but this is a tidy percentage in all cases. Relates to #23. --- src/main/java/nl/garvelink/iban/IBAN.java | 21 ++++++++++++++++++- src/test/java/nl/garvelink/iban/IBANTest.java | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/java/nl/garvelink/iban/IBAN.java b/src/main/java/nl/garvelink/iban/IBAN.java index 3f4ad54..a0578c4 100644 --- a/src/main/java/nl/garvelink/iban/IBAN.java +++ b/src/main/java/nl/garvelink/iban/IBAN.java @@ -15,8 +15,11 @@ */ package nl.garvelink.iban; +import java.io.Externalizable; import java.io.IOException; import java.io.InvalidObjectException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; import java.util.Comparator; @@ -312,7 +315,7 @@ private void readObjectNoData() * * There should be no need to ever use IBAN.Memento in your code. */ - static final class Memento implements Serializable { + static final class Memento implements Externalizable { private static final long serialVersionUID = 1L; private String value; @@ -325,6 +328,22 @@ public Memento() { this.value = value; } + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeLong(serialVersionUID); + out.writeUTF(this.value); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + long serialUID = in.readLong(); + if (serialUID == 1L) { + this.value = in.readUTF(); + } else { + throw new InvalidObjectException("Unsupported serial version: " + serialUID); + } + } + private Object readResolve() throws ObjectStreamException { try { return IBAN.parse(this.value); diff --git a/src/test/java/nl/garvelink/iban/IBANTest.java b/src/test/java/nl/garvelink/iban/IBANTest.java index 6d7d6ad..78c9a90 100644 --- a/src/test/java/nl/garvelink/iban/IBANTest.java +++ b/src/test/java/nl/garvelink/iban/IBANTest.java @@ -164,7 +164,7 @@ public void testSerializationRoundTrip() throws IOException, ClassNotFoundExcept public void testSerializedFormCompatibility() throws IOException, ClassNotFoundException { // This was manually sampled from the preceding test. This test is to ensure that the serialised form remains // stable as the library evolves. - String serializedForm = "rO0ABXNyAB5ubC5nYXJ2ZWxpbmsuaWJhbi5JQkFOJE1lbWVudG8AAAAAAAAAAQIAAUwABXZhbHVldAASTGphdmEvbGFuZy9TdHJpbmc7eHB0ABJOTDkxQUJOQTA0MTcxNjQzMDA="; + String serializedForm = "rO0ABXNyAB5ubC5nYXJ2ZWxpbmsuaWJhbi5JQkFOJE1lbWVudG8AAAAAAAAAAQwAAHhwdxwAAAAAAAAAAQASTkw5MUFCTkEwNDE3MTY0MzAweA=="; ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(serializedForm))); IBAN copy = (IBAN) ois.readObject(); assertThat(copy.toPlainString(), is(equalTo(VALID_IBAN))); @@ -173,7 +173,7 @@ public void testSerializedFormCompatibility() throws IOException, ClassNotFoundE @Test public void testDeserializationPerformsValidation() throws IOException, ClassNotFoundException { // This is the same base64 blob as above, altered to put in a garbage IBAN value. - String serializedForm = "rO0ABXNyAB5ubC5nYXJ2ZWxpbmsuaWJhbi5JQkFOJE1lbWVudG8AAAAAAAAAAQIAAUwABXZhbHVldAASTGphdmEvbGFuZy9TdHJpbmc7eHB0ABJOTDkxQUJORTA0MTcxNjQzMDA="; + String serializedForm = "rO0ABXNyAB5ubC5nYXJ2ZWxpbmsuaWJhbi5JQkFOJE1lbWVudG8AAAAAAAAAAQwAAHhwdxwAAAAAAAAAAQASTkw5MUFCTkEwNEE3MTY0MzAweA=="; ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(serializedForm))); try { IBAN copy = (IBAN) ois.readObject();