diff --git a/src/main/java/com/eprosima/fastdds/fastddsgen.java b/src/main/java/com/eprosima/fastdds/fastddsgen.java index c4334d46..76534356 100644 --- a/src/main/java/com/eprosima/fastdds/fastddsgen.java +++ b/src/main/java/com/eprosima/fastdds/fastddsgen.java @@ -25,6 +25,7 @@ import com.eprosima.idl.generator.manager.TemplateManager; import com.eprosima.idl.parser.grammar.IDLLexer; import com.eprosima.idl.parser.grammar.IDLParser; +import com.eprosima.idl.parser.tree.Annotation; import com.eprosima.idl.parser.tree.AnnotationDeclaration; import com.eprosima.idl.parser.tree.AnnotationMember; import com.eprosima.idl.parser.tree.Specification; @@ -308,6 +309,33 @@ else if (arg.equals("-cs")) { m_case_sensitive = true; } + else if (arg.equals("-de") || arg.equals("-default_extensibility")) + { + if (count < args.length) + { + String extensibility = args[count++]; + if (extensibility.equals(Annotation.final_str)) + { + TypeCode.default_extensibility = TypeCode.ExtensibilityKind.FINAL; + } + else if (extensibility.equals(Annotation.appendable_str)) + { + TypeCode.default_extensibility = TypeCode.ExtensibilityKind.APPENDABLE; + } + else if (extensibility.equals(Annotation.mutable_str)) + { + TypeCode.default_extensibility = TypeCode.ExtensibilityKind.MUTABLE; + } + else + { + throw new BadArgumentException("Extensibility value " + extensibility + " is not valid"); + } + } + else + { + throw new BadArgumentException("No extensibility value after -default_extensibility argument"); + } + } else // TODO: More options: -rpm, -debug { throw new BadArgumentException("Unknown argument " + arg); @@ -512,6 +540,12 @@ public static void printHelp() System.out.println("\t\t-cs: IDL grammar apply case sensitive matching."); System.out.println("\t\t-test: executes FastDDSGen tests."); System.out.println("\t\t-python: generates python bindings for the generated types."); + System.out.print("\t\t-default_extensibility | -de : sets the default extensibility for types without"); + System.out.println(" the @extensibility annotation."); + System.out.println("\t\t Values:"); + System.out.println("\t\t\t* " + Annotation.final_str); + System.out.println("\t\t\t* " + Annotation.appendable_str + " (default)"); + System.out.println("\t\t\t* " + Annotation.mutable_str); System.out.println("\tand the supported input files are:"); System.out.println("\t* IDL files."); diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/AliasTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/AliasTypeCode.java index b7eb2d08..fea3d1c8 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/AliasTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/AliasTypeCode.java @@ -14,6 +14,8 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; + public class AliasTypeCode extends com.eprosima.idl.parser.typecode.AliasTypeCode implements TypeCode { @@ -31,6 +33,14 @@ public long maxSerializedSize( return ((TypeCode) getTypedefContentTypeCode()).maxSerializedSize(current_alignment); } + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + return ((TypeCode) getTypedefContentTypeCode()).maxPlainTypeSerializedSize(current_alignment, align64); + } + public boolean isNotZeroArray() { if (super.getContentTypeCode() instanceof ArrayTypeCode) diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/ArrayTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/ArrayTypeCode.java index 6a1aa96f..185ee2be 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/ArrayTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/ArrayTypeCode.java @@ -14,6 +14,8 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; + public class ArrayTypeCode extends com.eprosima.idl.parser.typecode.ArrayTypeCode implements TypeCode { @@ -37,9 +39,44 @@ public long maxSerializedSize( size *= Long.parseLong(getDimensions().get(count), 10); } - for (long count = 0; count < size; ++count) + if (0 < size) { current_alignment += ((TypeCode)getContentTypeCode()).maxSerializedSize(current_alignment); + + if (1 < size) + { + long element_size_after_first = ((TypeCode)getContentTypeCode()).maxSerializedSize(current_alignment); + current_alignment += element_size_after_first * (size - 1); + } + } + + return current_alignment - initial_alignment; + } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + long initial_alignment = current_alignment; + + long size = 1; + for (int count = 0; count < getDimensions().size(); ++count) + { + size *= Long.parseLong(getDimensions().get(count), 10); + } + + if (0 < size) + { + current_alignment += ((TypeCode)getContentTypeCode()).maxPlainTypeSerializedSize( + current_alignment, align64); + + if (1 < size) + { + long element_size_after_first = ((TypeCode)getContentTypeCode()).maxPlainTypeSerializedSize( + current_alignment, align64); + current_alignment += element_size_after_first * (size - 1); + } } return current_alignment - initial_alignment; diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitmaskTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitmaskTypeCode.java index 7bad39fb..aa4297ba 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitmaskTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitmaskTypeCode.java @@ -35,13 +35,20 @@ public BitmaskTypeCode( @Override public long maxSerializedSize( long current_alignment) + { + return maxPlainTypeSerializedSize(current_alignment, 8); + } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) { long initial_alignment = current_alignment; long size = Long.parseLong(getSize(), 10); - current_alignment += size + TypeCode.cdr_alignment(current_alignment, size); + current_alignment += size + TypeCode.cdr_alignment(current_alignment, 4 < size ? align64 : size); return current_alignment - initial_alignment; } - } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitsetTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitsetTypeCode.java index 60fd18a6..75c158bc 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitsetTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/BitsetTypeCode.java @@ -30,6 +30,14 @@ public BitsetTypeCode( @Override public long maxSerializedSize( long current_alignment) + { + return maxPlainTypeSerializedSize(current_alignment, 8); + } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) { long initial_alignment = current_alignment; @@ -49,7 +57,7 @@ else if (33 > full_bit_size) } else { - current_alignment += 8 + TypeCode.cdr_alignment(current_alignment, 8); + current_alignment += 8 + TypeCode.cdr_alignment(current_alignment, align64); } return current_alignment - initial_alignment; diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/EnumTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/EnumTypeCode.java index d99a4a15..4f45c97c 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/EnumTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/EnumTypeCode.java @@ -27,6 +27,14 @@ public EnumTypeCode( @Override public long maxSerializedSize( long current_alignment) + { + return maxPlainTypeSerializedSize(current_alignment, 8); + } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) { long initial_alignment = current_alignment; @@ -34,5 +42,4 @@ public long maxSerializedSize( return current_alignment - initial_alignment; } - } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/MapTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/MapTypeCode.java index d9ba3f05..dd836248 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/MapTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/MapTypeCode.java @@ -14,6 +14,8 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; + public class MapTypeCode extends com.eprosima.idl.parser.typecode.MapTypeCode implements TypeCode { @@ -40,13 +42,28 @@ public long maxSerializedSize( current_alignment += 4 + TypeCode.cdr_alignment(current_alignment, 4); - for (long count = 0; count < maxsize; ++count) + if (0 < maxsize) { current_alignment += ((TypeCode)getKeyTypeCode()).maxSerializedSize(current_alignment); current_alignment += ((TypeCode)getValueTypeCode()).maxSerializedSize(current_alignment); + + if (1 < maxsize) + { + long element_size_after_first = ((TypeCode)getKeyTypeCode()).maxSerializedSize(current_alignment); + element_size_after_first += ((TypeCode)getValueTypeCode()).maxSerializedSize( + current_alignment + element_size_after_first); + current_alignment += element_size_after_first * (maxsize - 1); + } } return current_alignment - initial_alignment; } + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + throw new RuntimeGenerationException("MapTypeCode::maxPlainTypeSerializedSize(): Maps are not plain types."); + } } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/PrimitiveTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/PrimitiveTypeCode.java index d8a5f6fd..1a9fad72 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/PrimitiveTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/PrimitiveTypeCode.java @@ -27,18 +27,26 @@ public PrimitiveTypeCode( @Override public long maxSerializedSize( long current_alignment) + { + return maxPlainTypeSerializedSize(current_alignment, 8); + } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) { long initial_alignment = current_alignment; switch (getKind()) { case com.eprosima.idl.parser.typecode.Kind.KIND_LONGDOUBLE: - current_alignment += 16 + TypeCode.cdr_alignment(current_alignment, 8); + current_alignment += 16 + TypeCode.cdr_alignment(current_alignment, align64); break; case com.eprosima.idl.parser.typecode.Kind.KIND_DOUBLE: case com.eprosima.idl.parser.typecode.Kind.KIND_LONGLONG: case com.eprosima.idl.parser.typecode.Kind.KIND_ULONGLONG: - current_alignment += 8 + TypeCode.cdr_alignment(current_alignment, 8); + current_alignment += 8 + TypeCode.cdr_alignment(current_alignment, align64); break; case com.eprosima.idl.parser.typecode.Kind.KIND_LONG: case com.eprosima.idl.parser.typecode.Kind.KIND_ULONG: @@ -61,5 +69,4 @@ public long maxSerializedSize( return current_alignment - initial_alignment; } - } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SequenceTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SequenceTypeCode.java index 24b1040c..fbb40db0 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SequenceTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SequenceTypeCode.java @@ -14,6 +14,8 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; + public class SequenceTypeCode extends com.eprosima.idl.parser.typecode.SequenceTypeCode implements TypeCode { @@ -48,9 +50,15 @@ public long maxSerializedSize( current_alignment += 4 + TypeCode.cdr_alignment(current_alignment, 4); - for (long count = 0; count < maxsize; ++count) + if (0 < maxsize) { current_alignment += ((TypeCode)getContentTypeCode()).maxSerializedSize(current_alignment); + + if (1 < maxsize) + { + long element_size_after_first = ((TypeCode)getContentTypeCode()).maxSerializedSize(current_alignment); + current_alignment += element_size_after_first * (maxsize - 1); + } } if (should_set_and_unset) @@ -61,4 +69,12 @@ public long maxSerializedSize( return current_alignment - initial_alignment; } + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + throw new RuntimeGenerationException("MapTypeCode::maxPlainTypeSerializedSize(): Sequences are not plain types."); + } + } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SetTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SetTypeCode.java index b839fddc..4403bd15 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SetTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/SetTypeCode.java @@ -14,6 +14,8 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; + public class SetTypeCode extends com.eprosima.idl.parser.typecode.SetTypeCode implements TypeCode { @@ -32,12 +34,26 @@ public long maxSerializedSize( current_alignment += 4 + TypeCode.cdr_alignment(current_alignment, 4); - for (long count = 0; count < maxsize; ++count) + if (0 < maxsize) { current_alignment += ((TypeCode)getContentTypeCode()).maxSerializedSize(current_alignment); + + if (1 < maxsize) + { + long element_size_after_first = ((TypeCode)getContentTypeCode()).maxSerializedSize(current_alignment); + current_alignment += element_size_after_first * (maxsize - 1); + } } return current_alignment - initial_alignment; } + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + throw new RuntimeGenerationException("MapTypeCode::maxPlainTypeSerializedSize(): Sets are not plain types."); + } + } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StringTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StringTypeCode.java index 60a5f3c9..dfebf3b6 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StringTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StringTypeCode.java @@ -14,6 +14,7 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.typecode.Kind; public class StringTypeCode extends com.eprosima.idl.parser.typecode.StringTypeCode @@ -46,4 +47,12 @@ public long maxSerializedSize( return current_alignment - initial_alignment; } + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + throw new RuntimeGenerationException("StringTypeCode::maxPlainTypeSerializedSize(): Strings are not plain types."); + } + } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StructTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StructTypeCode.java index 6ac23165..0cf6ec87 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/StructTypeCode.java @@ -14,6 +14,7 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.typecode.Member; import com.eprosima.idl.parser.tree.Annotation; @@ -118,6 +119,53 @@ public String getMaxKeySerializedSize() com.eprosima.idl.parser.typecode.TypeCode.ExtensibilityKind.FINAL)); } + public String getMaxXCDRv1PlainTypeSerializedSize() throws RuntimeGenerationException + { + return Long.toString(maxPlainTypeSerializedSize(0, 8)); + } + + public String getMaxXCDRv2PlainTypeSerializedSize() throws RuntimeGenerationException + { + return Long.toString(maxPlainTypeSerializedSize(0, 4)); + } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + if (ExtensibilityKind.FINAL != get_extensibility()) + { + throw new RuntimeGenerationException("StructTypeCode::maxPlainTypeSerializedSize(): only FINAL structures can be plain."); + } + + long initial_alignment = current_alignment; + + for (com.eprosima.idl.parser.typecode.TypeCode parent : getInheritances()) + { + current_alignment += ((StructTypeCode)parent).maxPlainTypeSerializedSize(current_alignment, align64); + } + + for (Member member : getMembers()) + { + if (member.isAnnotationNonSerialized()) + { + continue; + } + + if (member.isIsPlain()) + { + current_alignment += ((TypeCode)member.getTypecode()).maxPlainTypeSerializedSize(current_alignment, align64); + } + else + { + throw new RuntimeGenerationException("StructTypeCode::maxPlainTypeSerializedSize(): A member returned being non-plain."); + } + } + + return current_alignment - initial_alignment; + } + public void setIsTopic( boolean value) { diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/TypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/TypeCode.java index 3e9136be..22b057ff 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/TypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/TypeCode.java @@ -14,6 +14,8 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; + public interface TypeCode { static long cdr_alignment( @@ -28,4 +30,11 @@ static long cdr_alignment( */ public long maxSerializedSize( long current_alignment); + + /* + * Returns the maximum serialized size for a plain Type + */ + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException; } diff --git a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/UnionTypeCode.java b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/UnionTypeCode.java index dd3160d3..9d6c6763 100644 --- a/src/main/java/com/eprosima/fastdds/idl/parser/typecode/UnionTypeCode.java +++ b/src/main/java/com/eprosima/fastdds/idl/parser/typecode/UnionTypeCode.java @@ -14,6 +14,7 @@ package com.eprosima.fastdds.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.typecode.Member; public class UnionTypeCode extends com.eprosima.idl.parser.typecode.UnionTypeCode @@ -61,4 +62,12 @@ public long maxSerializedSize( return current_alignment - initial_alignment; } + + @Override + public long maxPlainTypeSerializedSize( + long current_alignment, + long align64) throws RuntimeGenerationException + { + throw new RuntimeGenerationException("UnionTypeCode::maxPlainTypeSerializedSize(): Unions are not plain types."); + } } diff --git a/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg b/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg index d3c23ebe..fb0ef26b 100644 --- a/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg +++ b/src/main/java/com/eprosima/fastdds/idl/templates/DDSPubSubTypeHeader.stg @@ -182,7 +182,25 @@ public: #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN eProsima_user_DllExport inline bool is_plain() const override { - return $if(struct.isPlain)$is_plain_impl()$else$false$endif$; + return $if(struct.isPlain)$is_plain_xcdrv1_impl()$else$false$endif$; + } + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + $if(struct.isPlain)$ + if(data_representation == eprosima::fastdds::dds::DataRepresentationId_t::XCDR2_DATA_REPRESENTATION) + { + return is_plain_xcdrv2_impl(); + } + else + { + return is_plain_xcdrv1_impl(); + } + $else$ + static_cast(data_representation); + return false; + $endif$ } #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN @@ -203,15 +221,34 @@ public: $if(struct.isPlain)$ private: - static constexpr bool is_plain_impl() + static constexpr bool is_plain_xcdrv1_impl() + { + $if(struct.members)$ + return $struct.maxXCDRv1PlainTypeSerializedSize$ULL == + (detail::$struct.name$_offset_of<$struct.name$, detail::$struct.name$_f>() + + sizeof($last(struct.members).typecode.cppTypename$)); + $elseif(struct.inheritances)$ + $if(last(struct.inheritances).isPlain)$ + return $struct.maxXCDRv1PlainTypeSerializedSize$ULL == + (detail::$last(struct.inheritances).name$_offset_of<$last(struct.inheritances).name$, detail::$last(struct.inheritances).name$_f>() + + sizeof($last(last(struct.inheritances).members).typecode.cppTypename$)); + $else$ + return true; + $endif$ + $else$ + return true; + $endif$ + } + + static constexpr bool is_plain_xcdrv2_impl() { $if(struct.members)$ - return $struct.maxSerializedSize$ULL == + return $struct.maxXCDRv2PlainTypeSerializedSize$ULL == (detail::$struct.name$_offset_of<$struct.name$, detail::$struct.name$_f>() + sizeof($last(struct.members).typecode.cppTypename$)); $elseif(struct.inheritances)$ $if(last(struct.inheritances).isPlain)$ - return $struct.maxSerializedSize$ULL == + return $struct.maxXCDRv2PlainTypeSerializedSize$ULL == (detail::$last(struct.inheritances).name$_offset_of<$last(struct.inheritances).name$, detail::$last(struct.inheritances).name$_f>() + sizeof($last(last(struct.inheritances).members).typecode.cppTypename$)); $else$ diff --git a/thirdparty/idl-parser b/thirdparty/idl-parser index 0dec761f..b6248caa 160000 --- a/thirdparty/idl-parser +++ b/thirdparty/idl-parser @@ -1 +1 @@ -Subproject commit 0dec761fad8e25c48d4a865d8fcb9b9f9429f94e +Subproject commit b6248caa354247de3ee354fe78fe91798f830b43