From 5cf5d04edeed8a3d3fa72c9ee713d647e72e6fa8 Mon Sep 17 00:00:00 2001 From: Alexandre C Date: Wed, 10 Aug 2022 05:04:10 -0300 Subject: [PATCH] serialization/deserialization fixes and new features --- .../dev/oak3/sbs4j/DeserializerBuffer.java | 201 ++++++++++++------ .../java/dev/oak3/sbs4j/SerializerBuffer.java | 2 +- .../exception/InvalidByteStringException.java | 12 -- .../java/dev/oak3/sbs4j/util/ByteUtils.java | 90 ++++++++ .../oak3/sbs4j/DeserializerBufferTest.java | 31 ++- src/test/java/dev/oak3/sbs4j/model/Point.java | 3 +- .../java/dev/oak3/sbs4j/model/Polygon.java | 3 +- .../java/dev/oak3/sbs4j/model/Sphere.java | 3 +- 8 files changed, 243 insertions(+), 102 deletions(-) delete mode 100644 src/main/java/dev/oak3/sbs4j/exception/InvalidByteStringException.java diff --git a/src/main/java/dev/oak3/sbs4j/DeserializerBuffer.java b/src/main/java/dev/oak3/sbs4j/DeserializerBuffer.java index 25f7038..0c912a7 100644 --- a/src/main/java/dev/oak3/sbs4j/DeserializerBuffer.java +++ b/src/main/java/dev/oak3/sbs4j/DeserializerBuffer.java @@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; @@ -21,8 +22,8 @@ public class DeserializerBuffer { private static final Logger LOGGER = LoggerFactory.getLogger(DeserializerBuffer.class); - private static final String LOG_BUFFER_INIT_MESSAGE_HEX_STRING = "Initializing with hexString: {} and byte order {}"; - private static final String LOG_BUFFER_INIT_MESSAGE = "Initializing with bytes: {} and byte order {}"; + private static final String LOG_BUFFER_INIT_MESSAGE_HEX_STRING = "Initializing DeserializerBuffer with hexString: {} and byte order {}"; + private static final String LOG_BUFFER_INIT_MESSAGE = "Initializing DeserializerBuffer with bytes: {} and byte order {}"; private static final String LOG_BUFFER_VALUE_MESSAGE_STRING = "Buffer value: {}"; private static final String LOG_SERIALIZED_VALUE_MESSAGE_STRING = "Deserialized value for {}: {}"; private static final String SERIALIZE_EXCEPTION_OUT_OF_BOUNDS_MESSAGE_STRING = "Value %s out of bounds for expected type %s"; @@ -33,7 +34,7 @@ public class DeserializerBuffer { * @param hexString hex-encoded {@link String} to deserialize and read from */ public DeserializerBuffer(String hexString) { - this(hexString.length() != 0 ? new BigInteger(hexString, 16).toByteArray() : new byte[]{}); + this(hexString.length() != 0 ? ByteUtils.parseHexString(hexString) : new byte[]{}); } /** @@ -43,7 +44,7 @@ public DeserializerBuffer(String hexString) { * @param byteOrder the byte order to be using */ public DeserializerBuffer(String hexString, ByteOrder byteOrder) { - this(hexString.length() != 0 ? new BigInteger(hexString, 16).toByteArray() : new byte[]{}, byteOrder); + this(hexString.length() != 0 ? ByteUtils.parseHexString(hexString) : new byte[]{}, byteOrder); LOGGER.debug(LOG_BUFFER_INIT_MESSAGE_HEX_STRING, hexString, byteOrder); } @@ -78,17 +79,21 @@ public DeserializerBuffer(byte[] bytes, ByteOrder byteOrder) { * @throws ValueDeserializationException exception holding information of failure to deserialize a value */ public Boolean readBool() throws ValueDeserializationException { - byte buf = this.buffer.get(); - - LOGGER.debug(LOG_BUFFER_VALUE_MESSAGE_STRING, buf); - - if (buf == 1) { - return true; - } else if (buf == 0) { - return false; - } else { - throw new ValueDeserializationException( - String.format(SERIALIZE_EXCEPTION_OUT_OF_BOUNDS_MESSAGE_STRING, buf, Boolean.class.getSimpleName())); + try { + byte buf = this.buffer.get(); + + LOGGER.debug(LOG_BUFFER_VALUE_MESSAGE_STRING, buf); + + if (buf == 1) { + return true; + } else if (buf == 0) { + return false; + } else { + throw new ValueDeserializationException( + String.format(SERIALIZE_EXCEPTION_OUT_OF_BOUNDS_MESSAGE_STRING, buf, Boolean.class.getSimpleName())); + } + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading boolean from buffer", bufferUnderflowException); } } @@ -97,12 +102,16 @@ public Boolean readBool() throws ValueDeserializationException { * * @return the byte */ - public byte readU8() { - byte u8 = this.buffer.get(); + public byte readU8() throws ValueDeserializationException { + try { + byte u8 = this.buffer.get(); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Byte.class.getSimpleName(), u8); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Byte.class.getSimpleName(), u8); - return u8; + return u8; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading U8 from buffer", bufferUnderflowException); + } } /** @@ -111,12 +120,16 @@ public byte readU8() { * @param length the length of the array * @return the byte array as byte[] */ - public byte[] readByteArray(int length) { - byte[] bytes = readBytes(length); + public byte[] readByteArray(int length) throws ValueDeserializationException { + try { + byte[] bytes = readBytes(length); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Byte.class.getSimpleName(), bytes); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Byte.class.getSimpleName(), bytes); - return bytes; + return bytes; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading byte array from buffer", bufferUnderflowException); + } } /** @@ -124,12 +137,16 @@ public byte[] readByteArray(int length) { * * @return the number as a float */ - public float readF32() { - float floatNumber = this.buffer.getFloat(); + public float readF32() throws ValueDeserializationException { + try { + float floatNumber = this.buffer.getFloat(); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Float.class.getSimpleName(), floatNumber); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Float.class.getSimpleName(), floatNumber); - return floatNumber; + return floatNumber; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading F32 from buffer", bufferUnderflowException); + } } /** @@ -137,12 +154,16 @@ public float readF32() { * * @return the number as a double */ - public double readF64() { - double doubleNumber = this.buffer.getDouble(); + public double readF64() throws ValueDeserializationException { + try { + double doubleNumber = this.buffer.getDouble(); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Double.class.getSimpleName(), doubleNumber); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Double.class.getSimpleName(), doubleNumber); - return doubleNumber; + return doubleNumber; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading F64 from buffer", bufferUnderflowException); + } } /** @@ -150,12 +171,16 @@ public double readF64() { * * @return the number as an int */ - public int readI32() { - int integerNumber = this.buffer.getInt(); + public int readI32() throws ValueDeserializationException { + try { + int integerNumber = this.buffer.getInt(); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Integer.class.getSimpleName(), integerNumber); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Integer.class.getSimpleName(), integerNumber); - return integerNumber; + return integerNumber; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading I32 from buffer", bufferUnderflowException); + } } /** @@ -163,12 +188,16 @@ public int readI32() { * * @return the number as a long */ - public long readU32() { - long unsignedInteger = this.buffer.getLong(); + public long readU32() throws ValueDeserializationException { + try { + long unsignedInteger = this.buffer.getLong(); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Long.class.getSimpleName(), unsignedInteger); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Long.class.getSimpleName(), unsignedInteger); - return unsignedInteger; + return unsignedInteger; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading U32 from buffer", bufferUnderflowException); + } } /** @@ -176,12 +205,16 @@ public long readU32() { * * @return the number as a long */ - public long readI64() { - long longNumber = this.buffer.getLong(); + public long readI64() throws ValueDeserializationException { + try { + long longNumber = this.buffer.getLong(); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Long.class.getSimpleName(), longNumber); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, Long.class.getSimpleName(), longNumber); - return longNumber; + return longNumber; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading I64 from buffer", bufferUnderflowException); + } } /** @@ -189,17 +222,21 @@ public long readI64() { * * @return the number as a BigInteger */ - public BigInteger readU64() { - // Since this is a positive (unsigned) number, we should prefix with a zero - // byte to parse correctly - ByteBuffer bb = ByteBuffer.allocate(9); - bb.put((byte) 0); - bb.putLong(this.buffer.getLong()); - BigInteger unsignedLong = new BigInteger(bb.array()); - - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, BigInteger.class.getSimpleName(), unsignedLong); - - return unsignedLong; + public BigInteger readU64() throws ValueDeserializationException { + try { + // Since this is a positive (unsigned) number, we should prefix with a zero + // byte to parse correctly + ByteBuffer bb = ByteBuffer.allocate(9); + bb.put((byte) 0); + bb.putLong(this.buffer.getLong()); + BigInteger unsignedLong = new BigInteger(bb.array()); + + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, BigInteger.class.getSimpleName(), unsignedLong); + + return unsignedLong; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading U64 from buffer", bufferUnderflowException); + } } /** @@ -207,8 +244,12 @@ public BigInteger readU64() { * * @return the number as a BigInteger */ - public BigInteger readU128() { - return this.readBigInteger(); + public BigInteger readU128() throws ValueDeserializationException { + try { + return this.readBigInteger(); + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading U128 from buffer", bufferUnderflowException); + } } /** @@ -216,8 +257,12 @@ public BigInteger readU128() { * * @return the number as a BigInteger */ - public BigInteger readU256() { - return this.readBigInteger(); + public BigInteger readU256() throws ValueDeserializationException { + try { + return this.readBigInteger(); + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading U256 from buffer", bufferUnderflowException); + } } /** @@ -225,8 +270,12 @@ public BigInteger readU256() { * * @return the number as a BigInteger */ - public BigInteger readU512() { - return this.readBigInteger(); + public BigInteger readU512() throws ValueDeserializationException { + try { + return this.readBigInteger(); + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading U512 from buffer", bufferUnderflowException); + } } /** @@ -263,22 +312,36 @@ protected BigInteger readBigInteger() { * * @return the String read */ - public String readString() { - int length = this.buffer.getInt(); + public String readString() throws ValueDeserializationException { + try { + int length = this.buffer.getInt(); + + LOGGER.debug("Reading string of length: {}", length); - LOGGER.debug("Reading string of length: {}", length); + byte[] bufString = new byte[length]; - byte[] bufString = new byte[length]; + this.buffer.get(bufString, 0, length); - this.buffer.get(bufString, 0, length); + LOGGER.debug(LOG_BUFFER_VALUE_MESSAGE_STRING, bufString); - LOGGER.debug(LOG_BUFFER_VALUE_MESSAGE_STRING, bufString); + String string = new String(bufString); - String string = new String(bufString); + LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, String.class.getSimpleName(), string); - LOGGER.debug(LOG_SERIALIZED_VALUE_MESSAGE_STRING, String.class.getSimpleName(), string); + return string; + } catch (BufferUnderflowException bufferUnderflowException) { + throw new ValueDeserializationException("Error while reading String from buffer", bufferUnderflowException); + } - return string; + } + + /** + * Retrieves the backing buffer + * + * @return the Deserializer ByteBuffer + */ + public ByteBuffer getBuffer() { + return this.buffer; } /** diff --git a/src/main/java/dev/oak3/sbs4j/SerializerBuffer.java b/src/main/java/dev/oak3/sbs4j/SerializerBuffer.java index 870f750..e28f09b 100644 --- a/src/main/java/dev/oak3/sbs4j/SerializerBuffer.java +++ b/src/main/java/dev/oak3/sbs4j/SerializerBuffer.java @@ -220,7 +220,7 @@ protected void writeBigInteger(BigInteger value, int size) throws ValueSerializa LOGGER.debug(LOG_BUFFER_WRITE_TYPE_VALUE_MESSAGE_STRING, BigInteger.class.getSimpleName(), value); - byte bigIntegerLength = (byte) (Math.ceil(value.add(BigInteger.ONE).bitLength() / 8.0)); + byte bigIntegerLength = (byte) (Math.ceil(value.bitLength() / 8.0)); byte[] byteArray = value.toByteArray(); diff --git a/src/main/java/dev/oak3/sbs4j/exception/InvalidByteStringException.java b/src/main/java/dev/oak3/sbs4j/exception/InvalidByteStringException.java deleted file mode 100644 index c803b63..0000000 --- a/src/main/java/dev/oak3/sbs4j/exception/InvalidByteStringException.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.oak3.sbs4j.exception; - -/** - * Thrown in case of an invalid (unparseable) serialized byte string - * - * @since 0.1.0 - */ -public class InvalidByteStringException extends ValueDeserializationException { - public InvalidByteStringException(String message) { - super(message); - } -} diff --git a/src/main/java/dev/oak3/sbs4j/util/ByteUtils.java b/src/main/java/dev/oak3/sbs4j/util/ByteUtils.java index 2c4d7aa..05df4d3 100644 --- a/src/main/java/dev/oak3/sbs4j/util/ByteUtils.java +++ b/src/main/java/dev/oak3/sbs4j/util/ByteUtils.java @@ -3,9 +3,32 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Utilities class for Byte related operations + * + * @since 0.1.0 + */ public final class ByteUtils { private static final Logger LOGGER = LoggerFactory.getLogger(ByteUtils.class); + /** + * Hex string code case selector + */ + public enum HexCase { + LOWER("0123456789abcdef".toCharArray()), + UPPER("0123456789ABCDEF".toCharArray()); + + private final char[] hexCodes; + + public char[] getHexCodes() { + return this.hexCodes; + } + + HexCase(char[] hexCodes) { + this.hexCodes = hexCodes; + } + } + /** * Reverses a byte array, used to change endian * @@ -31,4 +54,71 @@ public static void reverse(byte[] bytes, int from, int to) { } LOGGER.debug("Reversed {}", bytes); } + + /** + * Parses a hex string to byte array + * + * @param hexString the hex string to parse + * @return the encoded byte array + * @throws IllegalArgumentException thrown if hexString is invalid + */ + public static byte[] parseHexString(String hexString) throws IllegalArgumentException { + final int len = hexString.length(); + + // "111" is not a valid hex encoding. + if (len % 2 != 0) + throw new IllegalArgumentException("hexBinary needs to be even-length: " + hexString); + + byte[] out = new byte[len / 2]; + + for (int i = 0; i < len; i += 2) { + int h = hexToByte(hexString.charAt(i)); + int l = hexToByte(hexString.charAt(i + 1)); + if (h == -1 || l == -1) + throw new IllegalArgumentException("contains illegal character for hexBinary: " + hexString); + + out[i / 2] = (byte) (h * 16 + l); + } + + return out; + } + + /** + * Converts hex characters to int value of byte + * + * @param charToConvert the char to convert to byte + * @return the int value of the converted byte + */ + private static int hexToByte(char charToConvert) { + if ('0' <= charToConvert && charToConvert <= '9') return charToConvert - '0'; + if ('A' <= charToConvert && charToConvert <= 'F') return charToConvert - 'A' + 10; + if ('a' <= charToConvert && charToConvert <= 'f') return charToConvert - 'a' + 10; + return -1; + } + + /** + * Encodes a byte array to an hex string in lower case as default + * + * @param byteArray the byte array to encode + * @return the encoded hex string + */ + public static String encodeHexString(byte[] byteArray) { + return encodeHexString(byteArray, HexCase.LOWER); + } + + /** + * Encodes a byte array to an hex string + * + * @param byteArray the byte array to encode + * @param hexCase upper or lower hex code case to use + * @return the encoded hex string + */ + public static String encodeHexString(byte[] byteArray, HexCase hexCase) { + StringBuilder r = new StringBuilder(byteArray.length * 2); + for (byte b : byteArray) { + r.append(hexCase.getHexCodes()[(b >> 4) & 0xF]); + r.append(hexCase.getHexCodes()[(b & 0xF)]); + } + return r.toString(); + } } diff --git a/src/test/java/dev/oak3/sbs4j/DeserializerBufferTest.java b/src/test/java/dev/oak3/sbs4j/DeserializerBufferTest.java index 2275a6f..cf03425 100644 --- a/src/test/java/dev/oak3/sbs4j/DeserializerBufferTest.java +++ b/src/test/java/dev/oak3/sbs4j/DeserializerBufferTest.java @@ -10,19 +10,16 @@ import org.slf4j.LoggerFactory; import java.math.BigInteger; -import java.nio.BufferUnderflowException; import java.nio.ByteOrder; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; class DeserializerBufferTest { private static final Logger LOGGER = LoggerFactory.getLogger(DeserializerBufferTest.class); @Test - void deserializePoint_should_match_expected_object() { + void deserializePoint_should_match_expected_object() throws ValueDeserializationException { byte[] serializedBytes = new byte[]{4, 0, 0, 0, 2, 0, 0, 0, 9, 0, 0, 0}; DeserializerBuffer deserializerBuffer = new DeserializerBuffer(serializedBytes); @@ -36,7 +33,7 @@ void deserializePoint_should_match_expected_object() { } @Test - void deserializeCircle_should_match_expected_object() { + void deserializeCircle_should_match_expected_object() throws ValueDeserializationException { byte[] serializedBytes = new byte[]{4, 0, 0, 0, 2, 0, 0, 0, 9, 0, 0, 0, 0, 0, -96, 64}; DeserializerBuffer deserializerBuffer = new DeserializerBuffer(serializedBytes); @@ -50,7 +47,7 @@ void deserializeCircle_should_match_expected_object() { } @Test - void deserializePolygon_should_match_expected_object() { + void deserializePolygon_should_match_expected_object() throws ValueDeserializationException { byte[] serializedBytes = new byte[]{4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0}; DeserializerBuffer deserializerBuffer = new DeserializerBuffer(serializedBytes); @@ -235,21 +232,21 @@ void validateDeserialize_BIG_ENDIAN_with_SampleData() throws ValueDeserializatio void dataWithWrongInputLength_should_throw_BufferUnderflowException() { DeserializerBuffer deserializerBuffer1 = new DeserializerBuffer(""); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readBool); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readU32); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readU64); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readU128); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readU256); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readU512); - assertThrows(BufferUnderflowException.class, deserializerBuffer1::readString); - assertThrows(BufferUnderflowException.class, () -> deserializerBuffer1.readByteArray(32)); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readBool); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readU32); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readU64); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readU128); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readU256); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readU512); + assertThrows(ValueDeserializationException.class, deserializerBuffer1::readString); + assertThrows(ValueDeserializationException.class, () -> deserializerBuffer1.readByteArray(32)); DeserializerBuffer deserializerBuffer2 = new DeserializerBuffer("01"); - assertThrows(BufferUnderflowException.class, deserializerBuffer2::readU512); + assertThrows(ValueDeserializationException.class, deserializerBuffer2::readU512); DeserializerBuffer deserializerBuffer3 = new DeserializerBuffer("01"); - assertThrows(BufferUnderflowException.class, deserializerBuffer3::readString); + assertThrows(ValueDeserializationException.class, deserializerBuffer3::readString); } } \ No newline at end of file diff --git a/src/test/java/dev/oak3/sbs4j/model/Point.java b/src/test/java/dev/oak3/sbs4j/model/Point.java index a782c5f..8f93525 100644 --- a/src/test/java/dev/oak3/sbs4j/model/Point.java +++ b/src/test/java/dev/oak3/sbs4j/model/Point.java @@ -2,6 +2,7 @@ import dev.oak3.sbs4j.DeserializerBuffer; import dev.oak3.sbs4j.SerializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import dev.oak3.sbs4j.interfaces.DeserializableObject; import dev.oak3.sbs4j.interfaces.SerializableObject; @@ -40,7 +41,7 @@ public void serialize(SerializerBuffer serializer) { } @Override - public void deserialize(DeserializerBuffer deserializer) { + public void deserialize(DeserializerBuffer deserializer) throws ValueDeserializationException { // ...defines the read order this.x = deserializer.readI32(); this.y = deserializer.readI32(); diff --git a/src/test/java/dev/oak3/sbs4j/model/Polygon.java b/src/test/java/dev/oak3/sbs4j/model/Polygon.java index 6b5e908..96b01e8 100644 --- a/src/test/java/dev/oak3/sbs4j/model/Polygon.java +++ b/src/test/java/dev/oak3/sbs4j/model/Polygon.java @@ -2,6 +2,7 @@ import dev.oak3.sbs4j.DeserializerBuffer; import dev.oak3.sbs4j.SerializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import dev.oak3.sbs4j.interfaces.DeserializableObject; import dev.oak3.sbs4j.interfaces.SerializableObject; @@ -36,7 +37,7 @@ public void serialize(SerializerBuffer serializerBuffer) { } @Override - public void deserialize(DeserializerBuffer deserializerBuffer) { + public void deserialize(DeserializerBuffer deserializerBuffer) throws ValueDeserializationException { int length = deserializerBuffer.readI32(); this.vertices = new ArrayList<>(); for (int i = 0; i < length; i++) { diff --git a/src/test/java/dev/oak3/sbs4j/model/Sphere.java b/src/test/java/dev/oak3/sbs4j/model/Sphere.java index 30324f6..a52be02 100644 --- a/src/test/java/dev/oak3/sbs4j/model/Sphere.java +++ b/src/test/java/dev/oak3/sbs4j/model/Sphere.java @@ -2,6 +2,7 @@ import dev.oak3.sbs4j.DeserializerBuffer; import dev.oak3.sbs4j.SerializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import dev.oak3.sbs4j.interfaces.DeserializableObject; import dev.oak3.sbs4j.interfaces.SerializableObject; @@ -27,7 +28,7 @@ public void serialize(SerializerBuffer serializerBuffer) { } @Override - public void deserialize(DeserializerBuffer deserializerBuffer) { + public void deserialize(DeserializerBuffer deserializerBuffer) throws ValueDeserializationException { // ...defines the read order this.center = new Point(); this.center.deserialize(deserializerBuffer);