From 5eb62535f5c0bc1278b5826bb4c8b1d3bbdc6c22 Mon Sep 17 00:00:00 2001 From: bergtwvd Date: Sat, 21 Mar 2026 01:25:36 +0100 Subject: [PATCH] Added exception for null value in encoding. --- .../ooencoder/omtcodec/HLAenumCodec.java | 4 +- .../HLAextendableVariantRecordCodec.java | 8 + .../omtcodec/HLAfixedArrayCodec.java | 8 + .../omtcodec/HLAfixedRecordCodec.java | 46 ++++- .../ooencoder/omtcodec/HLAfloat32BECodec.java | 20 ++- .../ooencoder/omtcodec/HLAfloat64BECodec.java | 20 ++- .../omtcodec/HLAinteger16BECodec.java | 20 ++- .../omtcodec/HLAinteger32BECodec.java | 20 ++- .../omtcodec/HLAinteger64BECodec.java | 20 ++- .../ooencoder/omtcodec/HLAoctetCodec.java | 20 ++- .../omtcodec/HLAoctetPairBECodec.java | 20 ++- .../omtcodec/HLAvariableArrayCodec.java | 8 + .../omtcodec/HLAvariantRecordCodec.java | 47 +++++- .../RPRextendedVariantRecordCodec.java | 9 + .../omtcodec/RPRlengthlessArrayCodec.java | 8 + .../omtcodec/RPRnullTerminatedArrayCodec.java | 10 +- .../test/omtcodec/TestHLAfixedRecord.java | 104 +++++++----- .../test/omtcodec/TestHLAvariantRecord1.java | 159 ++++++++++++------ 18 files changed, 432 insertions(+), 119 deletions(-) diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAenumCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAenumCodec.java index 3902884..e6c952a 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAenumCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAenumCodec.java @@ -185,7 +185,7 @@ public final int getOctetBoundary() { @Override public final int getEncodedLength(int position, Object value) throws OOcodecException { if (value == null) { - throw new InvalidValue("Invalid null value for enumerator"); + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); } // not allowed to encode the HLA_UNKNOWN_ENUM @@ -213,7 +213,7 @@ public final int getEncodedLength(int position, Object value) throws OOcodecExce @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { if (value == null) { - throw new InvalidValue("Invalid null value for enumerator"); + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); } if (value == this.unknownEnum) { diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAextendableVariantRecordCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAextendableVariantRecordCodec.java index ff7b59c..31870da 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAextendableVariantRecordCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAextendableVariantRecordCodec.java @@ -36,6 +36,10 @@ class HLAextendableVariantRecordCodec extends HLAvariantRecordCodec { @Override public int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { // save start position int offset = position; @@ -77,6 +81,10 @@ public int getOctetBoundary() { @Override public void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { // save start position int offset = byteWrapper.getPos(); diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedArrayCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedArrayCodec.java index 80e9f3a..e7b9c85 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedArrayCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedArrayCodec.java @@ -179,6 +179,10 @@ public final int getOctetBoundary() { @Override public final int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + this.componentName); + } + switch (this.datatype) { default: case ARRAY: @@ -250,6 +254,10 @@ public final int getEncodedLength(int position, Object value) throws OOcodecExce @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + this.componentName); + } + switch (this.datatype) { default: case ARRAY: diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedRecordCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedRecordCodec.java index 77cbdb6..aa24c70 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedRecordCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfixedRecordCodec.java @@ -11,6 +11,7 @@ import nl.tno.omt.helpers.OmtJavaMapping; import nl.tno.oorti.ooencoder.exceptions.InvalidClassStructure; import nl.tno.oorti.ooencoder.exceptions.InvalidType; +import nl.tno.oorti.ooencoder.exceptions.InvalidValue; import nl.tno.oorti.ooencoder.exceptions.OOcodecException; /** @@ -149,14 +150,33 @@ public final int getOctetBoundary() { @Override public final int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { if (memberAccessors.length > 0) { for (int i = 0; i < memberFieldCodecs.length - 1; i++) { // add size of component i OmtDatatypeCodec codec = memberFieldCodecs[i]; Accessor accessor = this.memberAccessors[i]; - position = - codec.getEncodedLength(position, accessor == null ? null : accessor.get(value)); + + if (accessor != null) { + Object fieldValue = accessor.get(value); + if (fieldValue == null) { + throw new InvalidValue( + "Invalid null value for field " + + this.memberNames[i] + + " of datatype " + + dt.getName().getValue()); + } + + position = codec.getEncodedLength(position, fieldValue); + } else { + // this is a field with a padding encoding, use a null value + // and the padding codec must return the padding length + position = codec.getEncodedLength(position, null); + } // add padding position += this.paddingSize(position, memberFieldCodecs[i + 1].getOctetBoundary()); @@ -165,7 +185,23 @@ public final int getEncodedLength(int position, Object value) throws OOcodecExce // add size of last component OmtDatatypeCodec codec = memberFieldCodecs[memberFieldCodecs.length - 1]; Accessor accessor = this.memberAccessors[memberFieldCodecs.length - 1]; - position = codec.getEncodedLength(position, accessor == null ? null : accessor.get(value)); + + if (accessor != null) { + Object fieldValue = accessor.get(value); + if (fieldValue == null) { + throw new InvalidValue( + "Invalid null value for field " + + this.memberNames[memberFieldCodecs.length - 1] + + " of datatype " + + dt.getName().getValue()); + } + + position = codec.getEncodedLength(position, fieldValue); + } else { + // this is a field with a padding encoding, use a null value + // and the padding codec must return the padding length + position = codec.getEncodedLength(position, null); + } } return position; @@ -176,6 +212,10 @@ public final int getEncodedLength(int position, Object value) throws OOcodecExce @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { if (memberAccessors.length > 0) { for (int i = 0; i < memberAccessors.length - 1; i++) { diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat32BECodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat32BECodec.java index 3ef0bfc..d8c146b 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat32BECodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat32BECodec.java @@ -16,6 +16,8 @@ class HLAfloat32BECodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 4; static final int ENCODEDLENGTH = 4; + final BasicData dt; + HLAfloat32BECodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { Class clazz = (Class) type; @@ -24,9 +26,15 @@ class HLAfloat32BECodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Float.class) && !clazz.equals(float.class)) { throw new InvalidType("Expected Float class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.putFloat((float) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat64BECodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat64BECodec.java index fb4586b..7b3714f 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat64BECodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAfloat64BECodec.java @@ -16,6 +16,8 @@ class HLAfloat64BECodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 8; static final int ENCODEDLENGTH = 8; + final BasicData dt; + HLAfloat64BECodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { Class clazz = (Class) type; @@ -24,9 +26,15 @@ class HLAfloat64BECodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Double.class) && !clazz.equals(double.class)) { throw new InvalidType("Expected Double class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.putDouble((double) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger16BECodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger16BECodec.java index a4f5065..0a01171 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger16BECodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger16BECodec.java @@ -15,6 +15,8 @@ class HLAinteger16BECodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 2; static final int ENCODEDLENGTH = 2; + + final BasicData dt; HLAinteger16BECodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { @@ -24,9 +26,15 @@ class HLAinteger16BECodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Short.class) && !clazz.equals(short.class)) { throw new InvalidType("Expected Short class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.putShort((short) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger32BECodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger32BECodec.java index 3255271..13406ba 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger32BECodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger32BECodec.java @@ -15,6 +15,8 @@ class HLAinteger32BECodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 4; static final int ENCODEDLENGTH = 4; + + final BasicData dt; HLAinteger32BECodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { @@ -24,9 +26,15 @@ class HLAinteger32BECodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Integer.class) && !clazz.equals(int.class)) { throw new InvalidType("Expected Integer class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.putInt((int) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger64BECodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger64BECodec.java index 54af4bb..ee0ea8e 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger64BECodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAinteger64BECodec.java @@ -15,6 +15,8 @@ class HLAinteger64BECodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 8; static final int ENCODEDLENGTH = 8; + + final BasicData dt; HLAinteger64BECodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { @@ -24,9 +26,15 @@ class HLAinteger64BECodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Long.class) && !clazz.equals(long.class)) { throw new InvalidType("Expected Long class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.putLong((long) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetCodec.java index b25049c..f867e6e 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetCodec.java @@ -15,6 +15,8 @@ class HLAoctetCodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 1; static final int ENCODEDLENGTH = 1; + + final BasicData dt; HLAoctetCodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { @@ -24,9 +26,15 @@ class HLAoctetCodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Byte.class) && !clazz.equals(byte.class)) { throw new InvalidType("Expected Byte class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.put((byte) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetPairBECodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetPairBECodec.java index 6093e5b..7db2ada 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetPairBECodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAoctetPairBECodec.java @@ -15,6 +15,8 @@ class HLAoctetPairBECodec implements OmtBasicDatatypeCodec { static final int OCTETBOUNDARY = 2; static final int ENCODEDLENGTH = 2; + + final BasicData dt; HLAoctetPairBECodec(OmtCodecFactory codecFactory, Type type, BasicData dt) throws InvalidType, InvalidClassStructure { @@ -24,9 +26,15 @@ class HLAoctetPairBECodec implements OmtBasicDatatypeCodec { throw new InvalidClassStructure("Missing Type"); } + if (dt == null) { + throw new InvalidType("Missing OMT datatype"); + } + if (!clazz.equals(Character.class) && !clazz.equals(char.class)) { throw new InvalidType("Expected Character class, but got " + clazz.getSimpleName()); } + + this.dt = dt; } @Override @@ -53,13 +61,21 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ENCODEDLENGTH; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) - throws ByteWrapperOutOfBoundsException { + throws ByteWrapperOutOfBoundsException, InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + byteWrapper.putShort((short) (char) value); } diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariableArrayCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariableArrayCodec.java index 2f3e0d8..0d32b8f 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariableArrayCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariableArrayCodec.java @@ -162,6 +162,10 @@ public final int getOctetBoundary() { @Override public final int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + this.componentName); + } + switch (this.datatype) { default: case ARRAY: @@ -200,6 +204,10 @@ public final int getEncodedLength(int position, Object value) throws OOcodecExce @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + this.componentName); + } + switch (this.datatype) { default: case ARRAY: diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariantRecordCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariantRecordCodec.java index 2690bdd..8fc5a9a 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariantRecordCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/HLAvariantRecordCodec.java @@ -31,10 +31,12 @@ class HLAvariantRecordCodec extends HLAdataElementCodec implements OmtDatatypeCo class AccessorCodec { + String name; Accessor accessor; OmtDatatypeCodec codec; - AccessorCodec(Accessor accessor, OmtDatatypeCodec codec) { + AccessorCodec(String name, Accessor accessor, OmtDatatypeCodec codec) { + this.name = name; this.accessor = accessor; this.codec = codec; } @@ -135,7 +137,7 @@ class AccessorCodec { OmtDatatypeCodec codec = codecFactory.createDatatype(field.getGenericType(), alternative.getDataType().getValue()); - AccessorCodec accessorCodec = new AccessorCodec(accessor, codec); + AccessorCodec accessorCodec = new AccessorCodec(alternativeName, accessor, codec); // For this alternative, add for each enumerator the accessorCodec to the lookup map. // The format for enumerator values is: 'HLAother' | | '[' .. ']' | @@ -246,12 +248,24 @@ public int getOctetBoundary() { @Override public int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { // save start position int offset = position; Object discriminant = this.discriminantAccessor.get(value); + if (discriminant == null) { + throw new InvalidValue( + "Invalid null value for discrimant " + + OmtJavaMapping.toJavaName(dt.getDiscriminant().getValue()) + + " of datatype " + + dt.getName().getValue()); + } + // add the encoded length of the discriminant position = this.discriminantCodec.getEncodedLength(position, discriminant); @@ -261,8 +275,16 @@ public int getEncodedLength(int position, Object value) throws OOcodecException position += this.paddingSize(position - offset, this.maxVariantOctetBoundary); // ... plus the encoded length of the variant - position = - accessorCodec.codec.getEncodedLength(position, accessorCodec.accessor.get(value)); + Object variant = accessorCodec.accessor.get(value); + if (variant == null) { + throw new InvalidValue( + "Invalid null value for variant " + + accessorCodec.name + + " of datatype " + + dt.getName().getValue()); + } + + position = accessorCodec.codec.getEncodedLength(position, variant); } else { if (discriminant.equals(hlaUnknownEnum) || this.hlaOtherAccessorCodec == null) { throw new InvalidValue( @@ -272,9 +294,16 @@ public int getEncodedLength(int position, Object value) throws OOcodecException position += this.paddingSize(position - offset, this.maxVariantOctetBoundary); // ... plus the encoded length of the variant - position = - hlaOtherAccessorCodec.codec.getEncodedLength( - position, hlaOtherAccessorCodec.accessor.get(value)); + Object variant = hlaOtherAccessorCodec.accessor.get(value); + if (variant == null) { + throw new InvalidValue( + "Invalid null value for variant " + + hlaOtherAccessorCodec.name + + " of datatype " + + dt.getName().getValue()); + } + + position = hlaOtherAccessorCodec.codec.getEncodedLength(position, variant); } } @@ -286,6 +315,10 @@ public int getEncodedLength(int position, Object value) throws OOcodecException @Override public void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { int offset = byteWrapper.getPos(); Object discriminant = this.discriminantAccessor.get(value); diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRextendedVariantRecordCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRextendedVariantRecordCodec.java index e58219b..0994837 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRextendedVariantRecordCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRextendedVariantRecordCodec.java @@ -3,6 +3,7 @@ import java.lang.reflect.Type; import nl.tno.omt.VariantRecordDataTypesType; import nl.tno.oorti.ooencoder.exceptions.InvalidClassStructure; +import nl.tno.oorti.ooencoder.exceptions.InvalidValue; import nl.tno.oorti.ooencoder.exceptions.OOcodecException; /** @@ -21,6 +22,10 @@ class RPRextendedVariantRecordCodec extends HLAvariantRecordCodec { @Override public int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { Object discriminant = this.discriminantAccessor.get(value); @@ -46,6 +51,10 @@ public int getEncodedLength(int position, Object value) throws OOcodecException @Override public void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + try { Object discriminant = this.discriminantAccessor.get(value); diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRlengthlessArrayCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRlengthlessArrayCodec.java index a4c0609..47496fc 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRlengthlessArrayCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRlengthlessArrayCodec.java @@ -187,6 +187,10 @@ public final int getOctetBoundary() { @Override public final int getEncodedLength(int position, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + switch (this.datatype) { default: case ARRAY: @@ -216,6 +220,10 @@ public final int getEncodedLength(int position, Object value) throws OOcodecExce @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + switch (this.datatype) { default: case ARRAY: diff --git a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRnullTerminatedArrayCodec.java b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRnullTerminatedArrayCodec.java index 5c3044f..8b7899c 100644 --- a/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRnullTerminatedArrayCodec.java +++ b/src/main/java/nl/tno/oorti/ooencoder/omtcodec/RPRnullTerminatedArrayCodec.java @@ -66,12 +66,20 @@ public final int getOctetBoundary() { } @Override - public final int getEncodedLength(int position, Object value) { + public final int getEncodedLength(int position, Object value) throws InvalidValue { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + return position + ((String) value).length() + 1; } @Override public final void encode(ByteArrayWrapper byteWrapper, Object value) throws OOcodecException { + if (value == null) { + throw new InvalidValue("Invalid null value for datatype " + dt.getName().getValue()); + } + String asciiString = ((String) value); if (asciiString.length() < this.minCardinality || asciiString.length() > this.maxCardinality) { diff --git a/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAfixedRecord.java b/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAfixedRecord.java index d4bf990..5247814 100644 --- a/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAfixedRecord.java +++ b/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAfixedRecord.java @@ -6,6 +6,7 @@ import nl.tno.oorti.ooencoder.OOencoder; import nl.tno.oorti.ooencoder.OOencoderFactory; import nl.tno.oorti.ooencoder.OOencoderFactoryFactory; +import nl.tno.oorti.ooencoder.exceptions.InvalidValue; import nl.tno.oorti.ooencoder.exceptions.OOcodecException; import nl.tno.oorti.test.omtcodec.beans.FixedRecordType1; import org.junit.jupiter.api.AfterAll; @@ -16,62 +17,87 @@ import org.junit.jupiter.api.Test; /** - * * @author bergtwvd */ public class TestHLAfixedRecord { - static ObjectModelType module; - static ObjectModelType mim; - static OOencoderFactory factory; + static ObjectModelType module; + static ObjectModelType mim; + static OOencoderFactory factory; - @BeforeAll - public static void setUpClass() throws IOException { - module = OmtFunctions.readOmt(TestOMTcodecFactoryClassStructure.class.getResource("/foms/Test.xml")); - mim = OmtFunctions.readOmt(TestOMTcodecFactoryClassStructure.class.getResource("/foms/HLAstandardMIM.xml")); - factory = OOencoderFactoryFactory.getOOencoderFactory(new ObjectModelType[]{module, mim}); - } + @BeforeAll + public static void setUpClass() throws IOException { + module = + OmtFunctions.readOmt(TestOMTcodecFactoryClassStructure.class.getResource("/foms/Test.xml")); + mim = + OmtFunctions.readOmt( + TestOMTcodecFactoryClassStructure.class.getResource("/foms/HLAstandardMIM.xml")); + factory = OOencoderFactoryFactory.getOOencoderFactory(new ObjectModelType[] {module, mim}); + } - @AfterAll - public static void tearDownClass() { - } + @AfterAll + public static void tearDownClass() {} - @BeforeEach - public void setUp() { - } + @BeforeEach + public void setUp() {} - @AfterEach - public void tearDown() { - } + @AfterEach + public void tearDown() {} - @Test - public void testFixedRecordType1() throws OOcodecException { - OOencoder codec = factory.createOOencoder(FixedRecordType1.class); + @Test + public void testFixedRecordType1() throws OOcodecException { + OOencoder codec = factory.createOOencoder(FixedRecordType1.class); - FixedRecordType1 in = new FixedRecordType1(); - in.setField1("Hello"); - in.setField2(12); + FixedRecordType1 in = new FixedRecordType1(); + in.setField1("Hello"); + in.setField2(12); - FixedRecordType1 out = codec.decode(codec.encode(in)); + FixedRecordType1 out = codec.decode(codec.encode(in)); - if (out == null || !in.getField1().equals(out.getField1()) || in.getField2() != out.getField2()) { - Assertions.fail(); - } + if (out == null + || !in.getField1().equals(out.getField1()) + || in.getField2() != out.getField2()) { + Assertions.fail(); } + } - @Test - public void testFixedRecordType2() throws OOcodecException { - OOencoder codec = factory.createOOencoder(FixedRecordType1.class, "FixedRecordType1"); + @Test + public void testFixedRecordType2() throws OOcodecException { + OOencoder codec = + factory.createOOencoder(FixedRecordType1.class, "FixedRecordType1"); - FixedRecordType1 in = new FixedRecordType1(); - in.setField1("Hello"); - in.setField2(12); + FixedRecordType1 in = new FixedRecordType1(); + in.setField1("Hello"); + in.setField2(12); - FixedRecordType1 out = codec.decode(codec.encode(in)); + FixedRecordType1 out = codec.decode(codec.encode(in)); - if (out == null || !in.getField1().equals(out.getField1()) || in.getField2() != out.getField2()) { - Assertions.fail(); - } + if (out == null + || !in.getField1().equals(out.getField1()) + || in.getField2() != out.getField2()) { + Assertions.fail(); } + } + + @Test + public void testFixedRecordType3() throws OOcodecException { + OOencoder codec = + factory.createOOencoder(FixedRecordType1.class, "FixedRecordType1"); + + FixedRecordType1 in = new FixedRecordType1(); + in.setField1(null); + in.setField2(12); + + Exception exception = + Assertions.assertThrows( + InvalidValue.class, + () -> { + codec.encode(in); + }); + + String expectedMessage = "Invalid null value for field Field1 of datatype FixedRecordType1"; + String actualMessage = exception.getMessage(); + Assertions.assertTrue(actualMessage.equals(expectedMessage)); + } } diff --git a/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAvariantRecord1.java b/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAvariantRecord1.java index 0e49f4c..91eed74 100644 --- a/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAvariantRecord1.java +++ b/src/test/java/nl/tno/oorti/test/omtcodec/TestHLAvariantRecord1.java @@ -6,6 +6,7 @@ import nl.tno.oorti.ooencoder.OOencoder; import nl.tno.oorti.ooencoder.OOencoderFactory; import nl.tno.oorti.ooencoder.OOencoderFactoryFactory; +import nl.tno.oorti.ooencoder.exceptions.InvalidValue; import nl.tno.oorti.ooencoder.exceptions.OOcodecException; import nl.tno.oorti.test.omtcodec.beans.EnumType; import nl.tno.oorti.test.omtcodec.beans.FixedRecordType1; @@ -18,77 +19,129 @@ import org.junit.jupiter.api.Test; /** - * * @author bergtwvd */ public class TestHLAvariantRecord1 { - static ObjectModelType module; - static ObjectModelType mim; - static OOencoderFactory factory; + static ObjectModelType module; + static ObjectModelType mim; + static OOencoderFactory factory; - @BeforeAll - public static void setUpClass() throws IOException { - module = OmtFunctions.readOmt(TestOMTcodecFactoryClassStructure.class.getResource("/foms/Test.xml")); - mim = OmtFunctions.readOmt(TestOMTcodecFactoryClassStructure.class.getResource("/foms/HLAstandardMIM.xml")); - factory = OOencoderFactoryFactory.getOOencoderFactory(new ObjectModelType[]{module, mim}); - } + @BeforeAll + public static void setUpClass() throws IOException { + module = + OmtFunctions.readOmt(TestOMTcodecFactoryClassStructure.class.getResource("/foms/Test.xml")); + mim = + OmtFunctions.readOmt( + TestOMTcodecFactoryClassStructure.class.getResource("/foms/HLAstandardMIM.xml")); + factory = OOencoderFactoryFactory.getOOencoderFactory(new ObjectModelType[] {module, mim}); + } - @AfterAll - public static void tearDownClass() { - } + @AfterAll + public static void tearDownClass() {} - @BeforeEach - public void setUp() { - } + @BeforeEach + public void setUp() {} - @AfterEach - public void tearDown() { - } + @AfterEach + public void tearDown() {} - @Test - public void test1() throws OOcodecException { - OOencoder codec = factory.createOOencoder(VariantRecordType1.class); + @Test + public void test1() throws OOcodecException { + OOencoder codec = factory.createOOencoder(VariantRecordType1.class); - VariantRecordType1 in = new VariantRecordType1(); - in.setDiscriminant(EnumType.E5); - in.setA1(11); - in.setA2(3.0); + VariantRecordType1 in = new VariantRecordType1(); + in.setDiscriminant(EnumType.E5); + in.setA1(11); + in.setA2(3.0); - FixedRecordType1 f = new FixedRecordType1(); - f.setField1("Hello"); - f.setField2(12); - in.setA5(f); + FixedRecordType1 f = new FixedRecordType1(); + f.setField1("Hello"); + f.setField2(12); + in.setA5(f); - VariantRecordType1 out = (VariantRecordType1) codec.decode(codec.encode(in)); + VariantRecordType1 out = (VariantRecordType1) codec.decode(codec.encode(in)); - if (out == null) { - Assertions.fail(); - } + if (out == null) { + Assertions.fail(); + } - if (out.getDiscriminant() != EnumType.E5) { - Assertions.fail(); - } + if (out.getDiscriminant() != EnumType.E5) { + Assertions.fail(); + } - if (out.getA5() == null) { - Assertions.fail(); - } + if (out.getA5() == null) { + Assertions.fail(); + } - if (!out.getA5().getField1().equals("Hello")) { - Assertions.fail(); - } + if (!out.getA5().getField1().equals("Hello")) { + Assertions.fail(); + } - if (out.getA5().getField2() != 12) { - Assertions.fail(); - } + if (out.getA5().getField2() != 12) { + Assertions.fail(); + } - // check that the other fields have their default set 0 or null - if (out.getA1() != 0) { - Assertions.fail(); - } + // check that the other fields have their default set 0 or null + if (out.getA1() != 0) { + Assertions.fail(); + } - if (out.getA2() != 0) { - Assertions.fail(); - } + if (out.getA2() != 0) { + Assertions.fail(); } + } + + @Test + public void test2() throws OOcodecException { + OOencoder codec = + factory.createOOencoder(VariantRecordType1.class, "VariantRecordType1"); + + VariantRecordType1 in = new VariantRecordType1(); + in.setDiscriminant(null); + in.setA1(11); + in.setA2(3.0); + + FixedRecordType1 f = new FixedRecordType1(); + f.setField1("Hello"); + f.setField2(12); + in.setA5(f); + + Exception exception = + Assertions.assertThrows( + InvalidValue.class, + () -> { + codec.encode(in); + }); + + String expectedMessage = + "Invalid null value for discrimant Discriminant of datatype VariantRecordType1"; + String actualMessage = exception.getMessage(); + + Assertions.assertTrue(actualMessage.equals(expectedMessage)); + } + + @Test + public void test3() throws OOcodecException { + OOencoder codec = + factory.createOOencoder(VariantRecordType1.class, "VariantRecordType1"); + + VariantRecordType1 in = new VariantRecordType1(); + in.setDiscriminant(EnumType.E5); + in.setA5(null); + + Exception exception = + Assertions.assertThrows( + InvalidValue.class, + () -> { + codec.encode(in); + }); + + String expectedMessage = + "Invalid null value for variant A5 of datatype VariantRecordType1"; + String actualMessage = exception.getMessage(); + + Assertions.assertTrue(actualMessage.equals(expectedMessage)); + } + }