This is an automated email from the ASF dual-hosted git repository.
jfeinauer pushed a commit to branch feature/plc4rs
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/plc4rs by this push:
new 57e5d0339f Rust Codegeneration generates Cargo file and lib.rs
57e5d0339f is described below
commit 57e5d0339f2d715a88b560b2726b464a57e8468e
Author: julian <[email protected]>
AuthorDate: Sun Jun 5 22:30:48 2022 +0200
Rust Codegeneration generates Cargo file and lib.rs
---
.../plc4x/language/rust/RustLanguageOutput.java | 49 ++
.../language/rust/RustLanguageTemplateHelper.java | 84 +-
.../src/main/resources/templates/rust/Cargo.toml | 26 +
.../templates/rust/complex-type-template.rs.ftlh | 49 +-
.../templates/rust/data-io-template.rs.ftlh | 907 +++++++++++----------
.../resources/templates/rust/enum-template.rs.ftlh | 13 +-
plc4rust/src/read_buffer.rs | 12 +-
7 files changed, 660 insertions(+), 480 deletions(-)
diff --git
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
index f155610ea7..8edf948337 100644
---
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
+++
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageOutput.java
@@ -20,14 +20,22 @@ package org.apache.plc4x.language.rust;
import freemarker.template.Configuration;
import freemarker.template.Template;
+import org.apache.commons.io.FileUtils;
import
org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageOutput;
import
org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageTemplateHelper;
import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+import
org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.file.StandardCopyOption;
import java.util.*;
public class RustLanguageOutput extends FreemarkerLanguageOutput {
@@ -94,4 +102,45 @@ public class RustLanguageOutput extends
FreemarkerLanguageOutput {
}
*/
}
+
+ @Override
+ public void generate(File outputDir, String languageName, String
protocolName, String outputFlavor, Map<String, TypeDefinition> types,
Map<String, String> options) throws GenerationException {
+ super.generate(outputDir, languageName, protocolName, outputFlavor,
types, options);
+ // Add post generation logic here
+ try {
+ InputStream inputStream =
this.getClass().getClassLoader().getResourceAsStream("templates/rust/Cargo.toml");
+ if (inputStream == null) {
+ throw new RuntimeException("Unable to generate Cargo.toml");
+ }
+ java.nio.file.Files.copy(
+ inputStream,
+ outputDir.toPath().resolve("Cargo.toml"),
+ StandardCopyOption.REPLACE_EXISTING);
+ inputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ // Generate lib.rs
+ try {
+ StringBuilder sb = new StringBuilder();
+
+ Collection<File> files =
FileUtils.listFiles(outputDir.toPath().resolve("src").toFile(), new
String[]{"rs"}, false);
+
+ for (File file : files) {
+ sb.append("mod " + file.getName().split("\\.")[0] + ";\n");
+ }
+ sb.append("\n");
+ sb.append("#[cfg(test)]\n" +
+ "mod test {\n" +
+ "\n" +
+ " #[test]\n" +
+ " fn test() {\n" +
+ " println!(\"Hello world!\");\n" +
+ " }\n" +
+ "}");
+
FileUtils.writeStringToFile(outputDir.toPath().resolve("src").resolve("lib.rs").toFile(),
sb.toString(), Charset.defaultCharset());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
index bafa9e6f55..0fbb1bdc54 100644
---
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
+++
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
@@ -25,6 +25,7 @@ import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.D
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultEnumTypeDefinition;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultDiscriminatorField;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultSwitchField;
+import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultArrayTypeReference;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultEnumTypeReference;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultBooleanLiteral;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultStringLiteral;
@@ -156,14 +157,27 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
return "";
}
- public List<String> generateImports(TypeDefinition typeDefinition) {
+ private static List<String[]> getParserArgsImports(TypeDefinition
typeDefinition) {
+ List<String[]> imports = new ArrayList<>();
+ if (typeDefinition.getParserArguments().isPresent()) {
+ for (Argument argument :
typeDefinition.getParserArguments().get()) {
+ TypeReference type = argument.getType();
+ if (type instanceof DefaultEnumTypeReference) {
+ imports.add(new String[]{((DefaultEnumTypeReference)
type).getName(), ((DefaultEnumTypeReference) type).getName()});
+ }
+ }
+ }
+ return imports;
+ }
+
+ public List<String[]> generateImports(TypeDefinition typeDefinition) {
// Iterate all Types to see what kind of other Enums / Objects are
references
- List<String> imports = new ArrayList<>();
+ List<String[]> imports = new ArrayList<>();
if (typeDefinition instanceof EnumTypeDefinition) {
for (String constantName : ((EnumTypeDefinition)
typeDefinition).getConstantNames()) {
TypeReference constantType = ((EnumTypeDefinition)
typeDefinition).getConstantType(constantName);
if (constantType instanceof DefaultEnumTypeReference) {
- imports.add(((DefaultEnumTypeReference)
constantType).getName());
+ imports.add(new String[]{((DefaultEnumTypeReference)
constantType).getName(), ((DefaultEnumTypeReference) constantType).getName()});
}
}
}
@@ -171,11 +185,43 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
for (Field field : ((DefaultComplexTypeDefinition)
typeDefinition).getFields()) {
if (field instanceof DefaultSwitchField) {
for (DiscriminatedComplexTypeDefinition subclass :
((DefaultSwitchField) field).getCases()) {
- imports.add(subclass.getName());
+ imports.add(new String[]{subclass.getName(),
subclass.getName()});
+ // Also add options type
+ imports.add(new String[]{subclass.getName(),
subclass.getName() + "Options"});
}
}
}
}
+ imports.addAll(getParserArgsImports(typeDefinition));
+ // If it has a parent type, also generate imports for the paraent type
+ if (typeDefinition instanceof ComplexTypeDefinition) {
+ if (((ComplexTypeDefinition)
typeDefinition).getParentType().isPresent()) {
+ imports.addAll(getParserArgsImports(((ComplexTypeDefinition)
typeDefinition).getParentType().get()));
+ }
+
+ // Add Imports for fields
+ for (Field field : ((ComplexTypeDefinition)
typeDefinition).getFields()) {
+ if (field instanceof TypedField) {
+ TypeReference type = ((TypedField) field).getType();
+ if (type instanceof ComplexTypeReference) {
+ String typeName = ((ComplexTypeReference)
type).getName();
+ imports.add(new String[]{typeName, typeName});
+ } else if (type instanceof DefaultArrayTypeReference) {
+ // TODO refactor to make this more elgant
+ TypeReference elementTypeReference =
((DefaultArrayTypeReference) type).getElementTypeReference();
+ if (elementTypeReference instanceof
ComplexTypeReference) {
+ String typeName = ((ComplexTypeReference)
elementTypeReference).getName();
+ imports.add(new String[]{typeName, typeName});
+ }
+ } else if (type instanceof DefaultEnumTypeReference) {
+ String typeName = ((DefaultEnumTypeReference)
type).getName();
+ imports.add(new String[]{typeName, typeName});
+ }
+ }
+ }
+ }
+
+
return imports;
}
@@ -314,15 +360,35 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
});
}
+ public String getReadFunctionCall(TypeReference typeReference) {
+ if (!(typeReference instanceof SimpleTypeReference)) {
+ throw new RuntimeException("Not implemented yet: " +
typeReference);
+ }
+ SimpleTypeReference simpleTypeReference = (SimpleTypeReference)
typeReference;
+ switch (simpleTypeReference.getBaseType()) {
+ case BIT:
+ return "read_bit()?";
+ case UINT:
+ IntegerTypeReference unsignedIntegerTypeReference =
(IntegerTypeReference) simpleTypeReference;
+ if (unsignedIntegerTypeReference.getSizeInBits() < 8) {
+ return "read_u_n(" +
unsignedIntegerTypeReference.getSizeInBits() + ")? as u8";
+ }
+ if (unsignedIntegerTypeReference.getSizeInBits() == 8) {
+ return "read_u8()?";
+ }
+ }
+ throw new RuntimeException("Not implemented yet: " + typeReference);
+ }
+
public String getLanguageTypeNameForTypeReference(TypeReference
typeReference, boolean allowPrimitive) {
Objects.requireNonNull(typeReference);
if (typeReference instanceof ArrayTypeReference) {
final ArrayTypeReference arrayTypeReference = (ArrayTypeReference)
typeReference;
- if (arrayTypeReference.getElementTypeReference().isByteBased()) {
- return
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
allowPrimitive) + "[]";
- } else {
- return "List<" +
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
false) + ">";
- }
+// if (arrayTypeReference.getElementTypeReference().isByteBased()) {
+ return "Vec<" +
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
allowPrimitive) + ">";
+// } else {
+// return "List<" +
getLanguageTypeNameForTypeReference(arrayTypeReference.getElementTypeReference(),
false) + ">";
+// }
}
// DataIo data-types always have properties of type PlcValue
if (typeReference.isDataIoTypeReference()) {
diff --git
a/code-generation/language-rust/src/main/resources/templates/rust/Cargo.toml
b/code-generation/language-rust/src/main/resources/templates/rust/Cargo.toml
new file mode 100644
index 0000000000..2014320c15
--- /dev/null
+++ b/code-generation/language-rust/src/main/resources/templates/rust/Cargo.toml
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+name = "plc4x"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at
https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+plc4rust = {path = "../../../../"}
\ No newline at end of file
diff --git
a/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
b/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
index 57913bb7de..bda8b5dfc6 100644
---
a/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
+++
b/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
@@ -26,7 +26,8 @@
<#-- @ftlvariable name="tracer"
type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
<#-- @ftlvariable name="type"
type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition"
-->
<#-- Declare the name and type of variables declared locally inside the
template -->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".",
"/")}/${type.name}.rs
+src/${type.name}.rs
+<#--${helper.packageName(protocolName, languageName,
outputFlavor)?replace(".", "/")}/${type.name}.rs-->
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -48,24 +49,30 @@ ${helper.packageName(protocolName, languageName,
outputFlavor)?replace(".", "/")
// package ${helper.packageName(protocolName, languageName, outputFlavor)};
// Code generated by code-generation. DO NOT EDIT.
+use std::io::{Error, ErrorKind, Read, Write};
+use plc4rust::{Message, NoOption};
+use plc4rust::read_buffer::ReadBuffer;
+use plc4rust::write_buffer::WriteBuffer;
+
<#list helper.generateImports(type) as import>
-<#if type.name != import>
+<#if type.name != import[import?size - 1]>
<#-- File -> Struct -->
-use crate::${import}::${import};
+use crate::<#list import as path>${path}<#sep>::</#sep></#list>;
</#if>
</#list>
<#--<#if helper.needsParserArguments(type)>-->
+#[derive(PartialEq, Debug, Clone)]
pub struct ${type.name}Options {
<#if type.parserArguments?? && !type.parserArguments.isEmpty()>
<#list type.parserArguments.orElseThrow() as arg>
- ${arg.name}:
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
+ pub ${arg.name}:
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
</#list>
</#if>
<#if !type.parentType.isEmpty()>
<#if type.parentType.get().parserArguments?? &&
!type.parentType.get().parserArguments.isEmpty()>
<#list type.parentType.get().parserArguments.orElseThrow() as arg>
- ${arg.name}:
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
+ pub ${arg.name}:
${helper.getLanguageTypeNameForTypeReference(arg.type)}<#sep>, </#sep>
</#list>
</#if>
</#if>
@@ -75,7 +82,7 @@ pub struct ${type.name}Options {
#[derive(PartialEq, Debug, Clone)]
pub enum ${type.name} {
<#list helper.getSubtypes(type) as subtype>
- ${subtype.name}(${subtype.name}::${subtype.name})<#sep>,</#sep>
+ ${subtype.name}(${subtype.name})<#sep>,</#sep>
</#list>
}
@@ -99,8 +106,9 @@ impl Message for ${type.name} {
fn parse<T: Read>(reader: &mut ReadBuffer<T>, parameter: Option<Self::P>)
-> Result<Self::M, Error> {
// (Re-)define the options
+ let parameter = parameter.unwrap();
<#list type.parserArguments.orElseThrow() as arg>
- let ${arg.name} = parameter.unwrap().${arg.name};
+ let ${arg.name} = parameter.${arg.name};
</#list>
<#list type.fields as field>
<#if helper.isSwitchField(field)>
@@ -108,7 +116,6 @@ impl Message for ${type.name} {
<#list field.cases as aCase>
<#assign n=aCase.discriminatorValueTerms?size - 1>
<#assign m=field.getDiscriminatorExpressions()?size - 1>
-<#-- ${helper.sink(n)}-->
(<#list 0..m as i><#if i <= n><#assign
caseType=field.getDiscriminatorExpressions()[i]><#assign
term=aCase.discriminatorValueTerms[i]>${helper.formatLiteral(caseType.typeReference,
term)}<#else>_</#if><#sep>, </#sep></#list>) => {
Ok(${type.name}::${aCase.name}(${aCase.name}::parse::<T>(reader,
Some(${aCase.name}Options {
<#if type.parserArguments?? && !type.parserArguments.isEmpty()>
@@ -120,16 +127,40 @@ impl Message for ${type.name} {
<#-- ${helper.sink(aCase)}-->
}
</#list>
+ _ => {
+ panic!("Unable to parse!");
+ }
}
<#else>
- read ${field}
+ let ${field.name} = reader.${helper.getReadFunctionCall(field.type)};
</#if>
<#-- ${helper.generateFieldParseCode(field)}-->
</#list>
}
}
<#else>
+#[derive(PartialEq, Debug, Clone)]
pub struct ${type.name} {
+ <#list type.fields as field>
+ pub ${field.name}:
${helper.getLanguageTypeNameForTypeReference(field.type)}<#sep>,</#sep>
+ </#list>
+}
+
+impl Message for ${type.name} {
+ type M = ${type.name};
+ type P = ${type.name}Options;
+
+ fn get_length_in_bits(&self) -> u32 {
+ todo!()
+ }
+
+ fn serialize<T: Write>(&self, writer: &mut WriteBuffer<T>) ->
Result<usize, Error> {
+ todo!()
+ }
+
+ fn parse<T: Read>(reader: &mut ReadBuffer<T>, parameter: Option<Self::P>)
-> Result<Self::M, Error> {
+ todo!()
+ }
}
</#if>
diff --git
a/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
b/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
index 3c9c9032e7..98e45e60e6 100644
---
a/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
+++
b/code-generation/language-rust/src/main/resources/templates/rust/data-io-template.rs.ftlh
@@ -25,7 +25,8 @@
<#-- @ftlvariable name="helper"
type="org.apache.plc4x.language.rust.RustLanguageTemplateHelper" -->
<#-- @ftlvariable name="tracer"
type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
<#-- @ftlvariable name="type"
type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition"
-->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".",
"/")}/${type.name}.rs
+src/${type.name}.rs
+<#--${helper.packageName(protocolName, languageName,
outputFlavor)?replace(".", "/")}/${type.name}.rs-->
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -44,477 +45,477 @@ ${helper.packageName(protocolName, languageName,
outputFlavor)?replace(".", "/")
* specific language governing permissions and limitations
* under the License.
*/
-package ${helper.packageName(protocolName, languageName, outputFlavor)};
+<#--package ${helper.packageName(protocolName, languageName, outputFlavor)};-->
-import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+<#--import static org.apache.plc4x.java.spi.generation.StaticHelper.*;-->
-import org.apache.plc4x.java.api.model.PlcField;
-import org.apache.plc4x.java.api.value.*;
-import org.apache.plc4x.java.spi.generation.EvaluationHelper;
-import org.apache.plc4x.java.spi.generation.ParseException;
-import org.apache.plc4x.java.spi.generation.SerializationException;
-import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-import org.apache.plc4x.java.spi.generation.ByteOrder;
-import ${helper.packageName(protocolName, languageName, outputFlavor)}.*;
-import org.apache.plc4x.java.spi.values.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+<#--import org.apache.plc4x.java.api.model.PlcField;-->
+<#--import org.apache.plc4x.java.api.value.*;-->
+<#--import org.apache.plc4x.java.spi.generation.EvaluationHelper;-->
+<#--import org.apache.plc4x.java.spi.generation.ParseException;-->
+<#--import org.apache.plc4x.java.spi.generation.SerializationException;-->
+<#--import org.apache.plc4x.java.spi.generation.ReadBuffer;-->
+<#--import org.apache.plc4x.java.spi.generation.WriteBuffer;-->
+<#--import org.apache.plc4x.java.spi.generation.ByteOrder;-->
+<#--import ${helper.packageName(protocolName, languageName,
outputFlavor)}.*;-->
+<#--import org.apache.plc4x.java.spi.values.*;-->
+<#--import org.slf4j.Logger;-->
+<#--import org.slf4j.LoggerFactory;-->
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigInteger;
-import java.time.*;
-import java.util.*;
-import java.util.function.Supplier;
+<#--import java.lang.reflect.InvocationTargetException;-->
+<#--import java.lang.reflect.Method;-->
+<#--import java.math.BigInteger;-->
+<#--import java.time.*;-->
+<#--import java.util.*;-->
+<#--import java.util.function.Supplier;-->
-// Code generated by code-generation. DO NOT EDIT.
+<#--// Code generated by code-generation. DO NOT EDIT.-->
-<#-- TODO: the code below implies that parserArguments will be null if not
present... not pretty -->
-<#if type.parserArguments.isPresent()><#assign
parserArguments=type.parserArguments.orElseThrow()></#if>
-public class ${type.name} {
+<#--<#– TODO: the code below implies that parserArguments will be
null if not present... not pretty –>-->
+<#--<#if type.parserArguments.isPresent()><#assign
parserArguments=type.parserArguments.orElseThrow()></#if>-->
+<#--public class ${type.name} {-->
- private static final Logger LOGGER =
LoggerFactory.getLogger(${type.name}.class);
- public static PlcValue staticParse(ReadBuffer readBuffer<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws
ParseException {
- <#assign defaultCaseOutput=false>
- <#assign
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
- <#list dataIoTypeDefinition.switchField.orElseThrow().cases as case>
- <@compress single_line=true>
- <#if case.discriminatorValueTerms?has_content>
- if(
- <#list case.discriminatorValueTerms as
discriminatorValueTerm>
- <#assign
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
- <#assign
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
- EvaluationHelper.equals(
-
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorExpression, parserArguments)},
- <#if discriminatorType.isEnumTypeReference()>
-
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}
- <#else>
-
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}
- </#if>
- )
- <#sep> && </#sep>
- </#list>
- )
- <#else>
- <#assign defaultCaseOutput=true>
- </#if>
- </@compress> { // ${case.name}
- <#assign valueDefined=false>
- <#list case.fields as field>
- <#switch field.typeName>
- <#case "array">
- <#assign arrayField =
field.asArrayField().orElseThrow()>
- <#assign
elementTypeReference=arrayField.type.elementTypeReference>
- // Array field (${arrayField.name})
- <#-- Only update curPos if the length expression uses it -->
- <#if arrayField.loopExpression.contains("curPos")>
- curPos = readBuffer.getPos() - startPos;
- </#if>
- <#-- If this is a count array, we can directly initialize an array
with the given size -->
- <#if field.isCountArrayField()>
- // Count array
- if(${helper.toParseExpression(arrayField, helper.intTypeReference,
arrayField.loopExpression,parserArguments)} > Integer.MAX_VALUE) {
- throw new ParseException("Array count of " +
(${helper.toParseExpression(arrayField, helper.intTypeReference,
arrayField.loopExpression,parserArguments)}) + " exceeds the maximum allowed
count of " + Integer.MAX_VALUE);
- }
- List<PlcValue> ${arrayField.name};
- {
- int itemCount = (int) ${helper.toParseExpression(arrayField,
helper.intTypeReference, arrayField.loopExpression,parserArguments)};
- ${arrayField.name} = new LinkedList<>();
- for(int curItem = 0; curItem < itemCount; curItem++) {
- ${arrayField.name}.add(new
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}((${helper.getLanguageTypeNameForTypeReference(elementTypeReference,
false)}) <#if
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"",
arrayField)})<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
elementTypeReference.params.isPresen [...]
- }
- }
- <#-- In all other cases do we have to work with a list, that is
later converted to an array -->
- <#else>
- <#-- For a length array, we read data till the read position of
the buffer reaches a given position -->
- <#if arrayField.isLengthArrayField()>
- // Length array
- long _${arrayField.name}Length =
${helper.toParseExpression(arrayField, helper.intTypeReference,
arrayField.loopExpression,parserArguments)};
- long ${arrayField.name}EndPos = readBuffer.getPos() +
_${arrayField.name}Length;
- List<PlcValue> value = new LinkedList<>();
- while(readBuffer.getPos() < ${arrayField.name}EndPos) {
- value.add(
- <#if elementTypeReference.isSimpleTypeReference()>
- new
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}(${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"", arrayField)})
-
<#else>${elementTypeReference.asNonSimpleTypeReference().orElseThrow().name}IO.staticParse(readBuffer
- <#if elementTypeReference.params.isPresent()>,
- <#list elementTypeReference.params.orElseThrow() as
parserArgument>
-
(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
parserArgument?index), true)}) (${helper.toParseExpression(arrayField,
elementTypeReference, parserArgument,parserArguments)})
- <#sep>, </#sep>
- </#list>
- </#if>
- )
- </#if>
- );
- }
- <#-- A terminated array keeps on reading data as long as the
termination expression evaluates to false -->
- <#elseif arrayField.isTerminatedArrayField()>
- // Terminated array
- ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}
${arrayField.name} = new LinkedList<>();
- while(!((boolean) (${helper.toParseExpression(arrayField,
helper.boolTypeReference, arrayField.loopExpression,parserArguments)}))) {
- ${arrayField.name}.add(<#if
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"",
arrayField)}<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as
parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
parser [...]
+<#-- private static final Logger LOGGER =
LoggerFactory.getLogger(${type.name}.class);-->
+<#-- public static PlcValue staticParse(ReadBuffer readBuffer<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws
ParseException {-->
+<#-- <#assign defaultCaseOutput=false>-->
+<#-- <#assign
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>-->
+<#-- <#list dataIoTypeDefinition.switchField.orElseThrow().cases as
case>-->
+<#-- <@compress single_line=true>-->
+<#-- <#if case.discriminatorValueTerms?has_content>-->
+<#-- if(-->
+<#-- <#list case.discriminatorValueTerms as
discriminatorValueTerm>-->
+<#-- <#assign
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>-->
+<#-- <#assign
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>-->
+<#-- EvaluationHelper.equals(-->
+<#--
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorExpression, parserArguments)},-->
+<#-- <#if discriminatorType.isEnumTypeReference()>-->
+<#--
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#-- <#else>-->
+<#--
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#-- </#if>-->
+<#-- )-->
+<#-- <#sep> && </#sep>-->
+<#-- </#list>-->
+<#-- )-->
+<#-- <#else>-->
+<#-- <#assign defaultCaseOutput=true>-->
+<#-- </#if>-->
+<#-- </@compress> { // ${case.name}-->
+<#-- <#assign valueDefined=false>-->
+<#-- <#list case.fields as field>-->
+<#-- <#switch field.typeName>-->
+<#-- <#case "array">-->
+<#-- <#assign arrayField =
field.asArrayField().orElseThrow()>-->
+<#-- <#assign
elementTypeReference=arrayField.type.elementTypeReference>-->
+<#-- // Array field (${arrayField.name})-->
+<#-- <#– Only update curPos if the length expression uses
it –>-->
+<#-- <#if
arrayField.loopExpression.contains("curPos")>-->
+<#-- curPos = readBuffer.getPos() - startPos;-->
+<#-- </#if>-->
+<#-- <#– If this is a count array, we can directly
initialize an array with the given size –>-->
+<#-- <#if field.isCountArrayField()>-->
+<#-- // Count array-->
+<#-- if(${helper.toParseExpression(arrayField,
helper.intTypeReference, arrayField.loopExpression,parserArguments)} >
Integer.MAX_VALUE) {-->
+<#-- throw new ParseException("Array count of " +
(${helper.toParseExpression(arrayField, helper.intTypeReference,
arrayField.loopExpression,parserArguments)}) + " exceeds the maximum allowed
count of " + Integer.MAX_VALUE);-->
+<#-- }-->
+<#-- List<PlcValue> ${arrayField.name};-->
+<#-- {-->
+<#-- int itemCount = (int)
${helper.toParseExpression(arrayField, helper.intTypeReference,
arrayField.loopExpression,parserArguments)};-->
+<#-- ${arrayField.name} = new LinkedList<>();-->
+<#-- for(int curItem = 0; curItem < itemCount; curItem++) {-->
+<#-- ${arrayField.name}.add(new
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}((${helper.getLanguageTypeNameForTypeReference(elementTypeReference,
false)}) <#if
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"",
arrayField)})<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
elementTypeReference.params.isPr [...]
+<#-- }-->
+<#-- }-->
+<#-- <#– In all other cases do we have to work with a
list, that is later converted to an array –>-->
+<#-- <#else>-->
+<#-- <#– For a length array, we read data till the read
position of the buffer reaches a given position –>-->
+<#-- <#if arrayField.isLengthArrayField()>-->
+<#-- // Length array-->
+<#-- long _${arrayField.name}Length =
${helper.toParseExpression(arrayField, helper.intTypeReference,
arrayField.loopExpression,parserArguments)};-->
+<#-- long ${arrayField.name}EndPos = readBuffer.getPos() +
_${arrayField.name}Length;-->
+<#-- List<PlcValue> value = new LinkedList<>();-->
+<#-- while(readBuffer.getPos() < ${arrayField.name}EndPos) {-->
+<#-- value.add(-->
+<#-- <#if elementTypeReference.isSimpleTypeReference()>-->
+<#-- new
${helper.getPlcValueTypeForTypeReference(elementTypeReference)}(${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"", arrayField)})-->
+<#--
<#else>${elementTypeReference.asNonSimpleTypeReference().orElseThrow().name}IO.staticParse(readBuffer-->
+<#-- <#if elementTypeReference.params.isPresent()>,-->
+<#-- <#list elementTypeReference.params.orElseThrow()
as parserArgument>-->
+<#--
(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
parserArgument?index), true)}) (${helper.toParseExpression(arrayField,
elementTypeReference, parserArgument,parserArguments)})-->
+<#-- <#sep>, </#sep>-->
+<#-- </#list>-->
+<#-- </#if>-->
+<#-- )-->
+<#-- </#if>-->
+<#-- );-->
+<#-- }-->
+<#-- <#– A terminated array keeps on reading data as long
as the termination expression evaluates to false –>-->
+<#-- <#elseif
arrayField.isTerminatedArrayField()>-->
+<#-- // Terminated array-->
+<#-- ${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}
${arrayField.name} = new LinkedList<>();-->
+<#-- while(!((boolean) (${helper.toParseExpression(arrayField,
helper.boolTypeReference, arrayField.loopExpression,parserArguments)}))) {-->
+<#-- ${arrayField.name}.add(<#if
elementTypeReference.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"",
arrayField)}<#else>${elementTypeReference.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
arrayField.params.isPresent()>, <#list arrayField.params.orElseThrow() as
parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(elementTypeReference,
pa [...]
- <#-- After parsing, update the current position, but only if
it's needed -->
- <#if
arrayField.loopExpression.contains("curPos")>
- curPos = readBuffer.getPos() - startPos;
- </#if>
- }
- </#if>
- </#if>
- <#if arrayField.name == "value">
- <#assign valueDefined=true>
- </#if>
- <#break>
- <#case "const">
- <#assign constField=field.asConstField().orElseThrow()>
+<#-- <#– After parsing, update the current position,
but only if it's needed –>-->
+<#-- <#if
arrayField.loopExpression.contains("curPos")>-->
+<#-- curPos = readBuffer.getPos() - startPos;-->
+<#-- </#if>-->
+<#-- }-->
+<#-- </#if>-->
+<#-- </#if>-->
+<#-- <#if arrayField.name == "value">-->
+<#-- <#assign valueDefined=true>-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- <#case "const">-->
+<#-- <#assign
constField=field.asConstField().orElseThrow()>-->
- // Const Field (${constField.name})
- ${helper.getNonPrimitiveLanguageTypeNameForField(constField)}
${constField.name} =
${helper.getReadBufferReadMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
"", constField)};
- if(${constField.name} !=
${dataIoTypeDefinition.name}.${constField.name?upper_case}) {
- throw new ParseException("Expected constant value " +
${dataIoTypeDefinition.name}.${constField.name?upper_case} + " but got " +
${constField.name});
- }
- <#if constField.name == "value">
- <#assign valueDefined=true>
- </#if>
- <#break>
- <#case "enum">
- <#assign enumField=field.asEnumField().orElseThrow()>
+<#-- // Const Field (${constField.name})-->
+<#-- ${helper.getNonPrimitiveLanguageTypeNameForField(constField)}
${constField.name} =
${helper.getReadBufferReadMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
"", constField)};-->
+<#-- if(${constField.name} !=
${dataIoTypeDefinition.name}.${constField.name?upper_case}) {-->
+<#-- throw new ParseException("Expected constant value " +
${dataIoTypeDefinition.name}.${constField.name?upper_case} + " but got " +
${constField.name});-->
+<#-- }-->
+<#-- <#if constField.name == "value">-->
+<#-- <#assign valueDefined=true>-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- <#case "enum">-->
+<#-- <#assign
enumField=field.asEnumField().orElseThrow()>-->
- // Enum field (${enumField.name})
- ${helper.getNonPrimitiveLanguageTypeNameForField(enumField)}
${enumField.name} =
${helper.getNonPrimitiveLanguageTypeNameForField(enumField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(enumField.type.asSimpleTypeReference().orElseThrow()),
"", enumField)});
- <#if enumField.name == "value">
- <#assign valueDefined=true>
- </#if>
- <#break>
- <#case "manual">
- <#assign
manualField=field.asManualField().orElseThrow()>
+<#-- // Enum field (${enumField.name})-->
+<#-- ${helper.getNonPrimitiveLanguageTypeNameForField(enumField)}
${enumField.name} =
${helper.getNonPrimitiveLanguageTypeNameForField(enumField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(enumField.type.asSimpleTypeReference().orElseThrow()),
"", enumField)});-->
+<#-- <#if enumField.name == "value">-->
+<#-- <#assign valueDefined=true>-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- <#case "manual">-->
+<#-- <#assign
manualField=field.asManualField().orElseThrow()>-->
- // Manual Field (${manualField.name})
- ${helper.getLanguageTypeNameForField(field)} ${manualField.name} =
(${helper.getLanguageTypeNameForField(manualField)})
(${helper.toParseExpression(manualField, manualField.type,
manualField.parseExpression,parserArguments)});
- <#if manualField.name == "value">
- <#assign valueDefined=true>
- </#if>
- <#break>
- <#case "reserved">
- <#assign
reservedField=field.asReservedField().orElseThrow()>
+<#-- // Manual Field (${manualField.name})-->
+<#-- ${helper.getLanguageTypeNameForField(field)}
${manualField.name} = (${helper.getLanguageTypeNameForField(manualField)})
(${helper.toParseExpression(manualField, manualField.type,
manualField.parseExpression,parserArguments)});-->
+<#-- <#if manualField.name == "value">-->
+<#-- <#assign valueDefined=true>-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- <#case "reserved">-->
+<#-- <#assign
reservedField=field.asReservedField().orElseThrow()>-->
- // Reserved Field (Compartmentalized so the "reserved" variable
can't leak)
- {
- ${helper.getLanguageTypeNameForField(field)} reserved =
${helper.getReadBufferReadMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
"", reservedField)};
- if(reserved != ${helper.getReservedValue(reservedField)}) {
- LOGGER.info("Expected constant value " +
${reservedField.referenceValue} + " but got " + reserved + " for reserved
field.");
- }
- }
- <#break>
- <#case "simple">
- <#assign
simpleField=field.asSimpleField().orElseThrow()>
+<#-- // Reserved Field (Compartmentalized so the "reserved"
variable can't leak)-->
+<#-- {-->
+<#-- ${helper.getLanguageTypeNameForField(field)} reserved =
${helper.getReadBufferReadMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
"", reservedField)};-->
+<#-- if(reserved != ${helper.getReservedValue(reservedField)})
{-->
+<#-- LOGGER.info("Expected constant value " +
${reservedField.referenceValue} + " but got " + reserved + " for reserved
field.");-->
+<#-- }-->
+<#-- }-->
+<#-- <#break>-->
+<#-- <#case "simple">-->
+<#-- <#assign
simpleField=field.asSimpleField().orElseThrow()>-->
- <#if helper.isEnumField(simpleField)>
- // Enum field (${simpleField.name})
- ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}
${simpleField.name} =
${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(simpleField.type),
"", simpleField)});
- <#else>
- // Simple Field (${simpleField.name})
- ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}
${simpleField.name} = <#if
simpleField.type.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
"",
simpleField)}<#else>${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
simpleField.params.isPresent()>, <#list field.params.orElseThrow() as
parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.g [...]
- </#if>
- <#if case.name == "Struct" ||
- ((case.name == "DATE_AND_TIME") &&
((simpleField.name == "year") || (simpleField.name == "month") ||
(simpleField.name == "day") || (simpleField.name == "hour") ||
(simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||
- ((case.name == "DATE_AND_TIME") &&
(simpleField.name == "secondsSinceEpoch")) ||
- ((case.name == "DATE") && ((simpleField.name ==
"year") || (simpleField.name == "month") || (simpleField.name == "day"))) ||
- ((case.name == "TIME_OF_DAY") &&
((simpleField.name == "hour") || (simpleField.name == "minutes") ||
(simpleField.name == "seconds"))) ||
- simpleField.name == "value">
- <#assign valueDefined=true>
- </#if>
- <#break>
- </#switch>
- </#list>
- <#if case.name == "Struct">
+<#-- <#if helper.isEnumField(simpleField)>-->
+<#-- // Enum field (${simpleField.name})-->
+<#-- ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}
${simpleField.name} =
${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}.enumForValue(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(simpleField.type),
"", simpleField)});-->
+<#-- <#else>-->
+<#-- // Simple Field (${simpleField.name})-->
+<#-- ${helper.getNonPrimitiveLanguageTypeNameForField(simpleField)}
${simpleField.name} = <#if
simpleField.type.isSimpleTypeReference()>${helper.getReadBufferReadMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
"",
simpleField)}<#else>${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticParse(readBuffer<#if
simpleField.params.isPresent()>, <#list field.params.orElseThrow() as
parserArgument>(${helper.getLanguageTypeNameForTypeReference(help [...]
+<#-- </#if>-->
+<#-- <#if case.name == "Struct" ||-->
+<#-- ((case.name == "DATE_AND_TIME") &&
((simpleField.name == "year") || (simpleField.name == "month") ||
(simpleField.name == "day") || (simpleField.name == "hour") ||
(simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||-->
+<#-- ((case.name == "DATE_AND_TIME") &&
(simpleField.name == "secondsSinceEpoch")) ||-->
+<#-- ((case.name == "DATE") && ((simpleField.name
== "year") || (simpleField.name == "month") || (simpleField.name == "day")))
||-->
+<#-- ((case.name == "TIME_OF_DAY") &&
((simpleField.name == "hour") || (simpleField.name == "minutes") ||
(simpleField.name == "seconds"))) ||-->
+<#-- simpleField.name == "value">-->
+<#-- <#assign valueDefined=true>-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- </#switch>-->
+<#-- </#list>-->
+<#-- <#if case.name == "Struct">-->
- <#-- In this case we need to wrap each field in a PlcValue
that matches it's natural type -->
- Map<String, PlcValue> _map = new HashMap<>();
- <#list case.fields as field>
- <#if field.isArrayField()>
- <#assign field=field.asArrayField().orElseThrow()>
- _map.put("${field.name}", new PlcList(${field.name}));
- <#elseif field.isPropertyField()>
- <#assign field=field.asPropertyField().orElseThrow()>
- <#switch
helper.getLanguageTypeNameForTypeReference(field.type)>
- <#case "Boolean">
- _map.put("${field.name}", new PlcBOOL(${field.name}));
- <#break>
- <#case "Byte">
- _map.put("${field.name}", new PlcSINT(${field.name}));
- <#break>
- <#case "Short">
- _map.put("${field.name}", new PlcINT(${field.name}));
- <#break>
- <#case "Integer">
- _map.put("${field.name}", new PlcDINT(${field.name}));
- <#break>
- <#case "Long">
- _map.put("${field.name}", new PlcLINT(${field.name}));
- <#break>
- <#case "BigInteger">
- _map.put("${field.name}", new PlcBigInteger(${field.name}));
- <#break>
- <#case "Float">
- _map.put("${field.name}", new PlcREAL(${field.name}));
- <#break>
- <#case "Double">
- _map.put("${field.name}", new PlcLREAL(${field.name}));
- <#break>
- <#case "BigDecimal">
- _map.put("${field.name}", new PlcBigDecimal(${field.name}));
- <#break>
- <#case "String">
- _map.put("${field.name}", new PlcSTRING(${field.name}));
- <#break>
- <#case "LocalTime">
- _map.put("${field.name}", new PlcTIME_OF_DAY(${field.name}));
- <#break>
- <#case "LocalDate">
- _map.put("${field.name}", new PlcDATE(${field.name}));
- <#break>
- <#case "LocalDateTime">
- _map.put("${field.name}", new PlcDATE_AND_TIME(${field.name}));
- <#break>
- </#switch>
- </#if>
- </#list>
- <#assign valueDefined=true>
- </#if>
+<#-- <#– In this case we need to wrap each field in a
PlcValue that matches it's natural type –>-->
+<#-- Map<String, PlcValue> _map = new HashMap<>();-->
+<#-- <#list case.fields as field>-->
+<#-- <#if field.isArrayField()>-->
+<#-- <#assign
field=field.asArrayField().orElseThrow()>-->
+<#-- _map.put("${field.name}", new PlcList(${field.name}));-->
+<#-- <#elseif field.isPropertyField()>-->
+<#-- <#assign
field=field.asPropertyField().orElseThrow()>-->
+<#-- <#switch
helper.getLanguageTypeNameForTypeReference(field.type)>-->
+<#-- <#case "Boolean">-->
+<#-- _map.put("${field.name}", new PlcBOOL(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "Byte">-->
+<#-- _map.put("${field.name}", new PlcSINT(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "Short">-->
+<#-- _map.put("${field.name}", new PlcINT(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "Integer">-->
+<#-- _map.put("${field.name}", new PlcDINT(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "Long">-->
+<#-- _map.put("${field.name}", new PlcLINT(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "BigInteger">-->
+<#-- _map.put("${field.name}", new PlcBigInteger(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "Float">-->
+<#-- _map.put("${field.name}", new PlcREAL(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "Double">-->
+<#-- _map.put("${field.name}", new PlcLREAL(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "BigDecimal">-->
+<#-- _map.put("${field.name}", new PlcBigDecimal(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "String">-->
+<#-- _map.put("${field.name}", new PlcSTRING(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "LocalTime">-->
+<#-- _map.put("${field.name}", new
PlcTIME_OF_DAY(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "LocalDate">-->
+<#-- _map.put("${field.name}", new PlcDATE(${field.name}));-->
+<#-- <#break>-->
+<#-- <#case "LocalDateTime">-->
+<#-- _map.put("${field.name}", new
PlcDATE_AND_TIME(${field.name}));-->
+<#-- <#break>-->
+<#-- </#switch>-->
+<#-- </#if>-->
+<#-- </#list>-->
+<#-- <#assign valueDefined=true>-->
+<#-- </#if>-->
- <#if valueDefined>
- <#switch case.name>
- <#case "TIME">
- return new PlcTIME(value);
- <#break>
- <#case "DATE">
- <#if helper.hasFieldsWithNames(case.fields, "year",
"month", "day")>
- LocalDate value = LocalDate.of(year.intValue(), (month == 0) ? 1 :
month.intValue(), (day == 0) ? 1 : day.intValue());
- </#if>
- return new PlcDATE(value);
- <#break>
- <#case "TIME_OF_DAY">
- <#if helper.hasFieldsWithNames(case.fields, "hour",
"minutes", "seconds", "nanos")>
- LocalTime value = LocalTime.of(hour.intValue(),
minutes.intValue(), seconds.intValue(), nanos.intValue());
- <#elseif helper.hasFieldsWithNames(case.fields, "hour",
"minutes", "seconds")>
- LocalTime value = LocalTime.of(hour.intValue(),
minutes.intValue(), seconds.intValue());
- </#if>
- return new PlcTIME_OF_DAY(value);
- <#break>
- <#case "DATE_AND_TIME">
- <#if helper.hasFieldsWithNames(case.fields, "year",
"month", "day", "hour", "minutes", "seconds", "nanos")>
- LocalDateTime value = LocalDateTime.of(year.intValue(), (month ==
0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(),
minutes.intValue(), seconds.intValue(), nanos.intValue());
- <#elseif helper.hasFieldsWithNames(case.fields, "year",
"month", "day", "hour", "minutes", "seconds")>
- LocalDateTime value = LocalDateTime.of(year.intValue(), (month ==
0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(),
minutes.intValue(), seconds.intValue());
- <#elseif helper.hasFieldsWithNames(case.fields,
"secondsSinceEpoch")>
- LocalDateTime value =
LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, ZoneOffset.UTC);
- </#if>
- return new PlcDATE_AND_TIME(value);
- <#break>
- <#case "Struct">
- return new PlcStruct(_map);
- <#break>
- <#case "List">
- return new PlcList(value);
- <#break>
- <#default>
- return new Plc${case.name}(value);
- </#switch>
- </#if>
- }<#sep> else </#sep></#list>
- <#if !defaultCaseOutput>
- return null;
- </#if>
- }
+<#-- <#if valueDefined>-->
+<#-- <#switch case.name>-->
+<#-- <#case "TIME">-->
+<#-- return new PlcTIME(value);-->
+<#-- <#break>-->
+<#-- <#case "DATE">-->
+<#-- <#if helper.hasFieldsWithNames(case.fields, "year",
"month", "day")>-->
+<#-- LocalDate value = LocalDate.of(year.intValue(), (month == 0) ?
1 : month.intValue(), (day == 0) ? 1 : day.intValue());-->
+<#-- </#if>-->
+<#-- return new PlcDATE(value);-->
+<#-- <#break>-->
+<#-- <#case "TIME_OF_DAY">-->
+<#-- <#if helper.hasFieldsWithNames(case.fields, "hour",
"minutes", "seconds", "nanos")>-->
+<#-- LocalTime value = LocalTime.of(hour.intValue(),
minutes.intValue(), seconds.intValue(), nanos.intValue());-->
+<#-- <#elseif helper.hasFieldsWithNames(case.fields,
"hour", "minutes", "seconds")>-->
+<#-- LocalTime value = LocalTime.of(hour.intValue(),
minutes.intValue(), seconds.intValue());-->
+<#-- </#if>-->
+<#-- return new PlcTIME_OF_DAY(value);-->
+<#-- <#break>-->
+<#-- <#case "DATE_AND_TIME">-->
+<#-- <#if helper.hasFieldsWithNames(case.fields, "year",
"month", "day", "hour", "minutes", "seconds", "nanos")>-->
+<#-- LocalDateTime value = LocalDateTime.of(year.intValue(), (month
== 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(),
minutes.intValue(), seconds.intValue(), nanos.intValue());-->
+<#-- <#elseif helper.hasFieldsWithNames(case.fields,
"year", "month", "day", "hour", "minutes", "seconds")>-->
+<#-- LocalDateTime value = LocalDateTime.of(year.intValue(), (month
== 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(),
minutes.intValue(), seconds.intValue());-->
+<#-- <#elseif helper.hasFieldsWithNames(case.fields,
"secondsSinceEpoch")>-->
+<#-- LocalDateTime value =
LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, ZoneOffset.UTC);-->
+<#-- </#if>-->
+<#-- return new PlcDATE_AND_TIME(value);-->
+<#-- <#break>-->
+<#-- <#case "Struct">-->
+<#-- return new PlcStruct(_map);-->
+<#-- <#break>-->
+<#-- <#case "List">-->
+<#-- return new PlcList(value);-->
+<#-- <#break>-->
+<#-- <#default>-->
+<#-- return new Plc${case.name}(value);-->
+<#-- </#switch>-->
+<#-- </#if>-->
+<#-- }<#sep> else </#sep></#list>-->
+<#-- <#if !defaultCaseOutput>-->
+<#-- return null;-->
+<#-- </#if>-->
+<#-- }-->
-<#if outputFlavor != "passive">
- public static void staticSerialize(WriteBuffer writeBuffer, PlcValue
_value<#if type.parserArguments.isPresent()>, <#list
type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws
SerializationException {
- staticSerialize(writeBuffer, _value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>,
ByteOrder.BIG_ENDIAN);
- }
+<#--<#if outputFlavor != "passive">-->
+<#-- public static void staticSerialize(WriteBuffer writeBuffer, PlcValue
_value<#if type.parserArguments.isPresent()>, <#list
type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws
SerializationException {-->
+<#-- staticSerialize(writeBuffer, _value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>,
ByteOrder.BIG_ENDIAN);-->
+<#-- }-->
- public static void staticSerialize(WriteBuffer writeBuffer, PlcValue
_value<#if type.parserArguments.isPresent()>, <#list
type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder
byteOrder) throws SerializationException {
- <#assign defaultCaseOutput=false>
- <#assign
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
- <#list dataIoTypeDefinition.switchField.orElseThrow().cases as case>
- <@compress single_line=true>
- <#if case.discriminatorValueTerms?has_content>
- if(
- <#list case.discriminatorValueTerms as discriminatorValueTerm>
- <#assign
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
- <#assign
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
- EvaluationHelper.equals(
-
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorExpression, parserArguments)},
- <#if discriminatorType.isEnumTypeReference()>
-
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}
- <#else>
-
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}
- </#if>
- )
- <#sep> && </#sep>
- </#list>
- )
- <#else>
- <#assign defaultCaseOutput=true>
- </#if>
- </@compress> { // ${case.name}
- <#list case.fields as field>
- <#switch field.typeName>
- <#case "array">
- <#assign arrayField=field.asArrayField().orElseThrow()>
- <#assign
elementTypeReference=arrayField.type.elementTypeReference>
- PlcList values = (PlcList) _value;
+<#-- public static void staticSerialize(WriteBuffer writeBuffer, PlcValue
_value<#if type.parserArguments.isPresent()>, <#list
type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>, ByteOrder
byteOrder) throws SerializationException {-->
+<#-- <#assign defaultCaseOutput=false>-->
+<#-- <#assign
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>-->
+<#-- <#list dataIoTypeDefinition.switchField.orElseThrow().cases as
case>-->
+<#-- <@compress single_line=true>-->
+<#-- <#if case.discriminatorValueTerms?has_content>-->
+<#-- if(-->
+<#-- <#list case.discriminatorValueTerms as
discriminatorValueTerm>-->
+<#-- <#assign
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>-->
+<#-- <#assign
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>-->
+<#-- EvaluationHelper.equals(-->
+<#--
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorExpression, parserArguments)},-->
+<#-- <#if discriminatorType.isEnumTypeReference()>-->
+<#--
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#-- <#else>-->
+<#--
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#-- </#if>-->
+<#-- )-->
+<#-- <#sep> && </#sep>-->
+<#-- </#list>-->
+<#-- )-->
+<#-- <#else>-->
+<#-- <#assign defaultCaseOutput=true>-->
+<#-- </#if>-->
+<#-- </@compress> { // ${case.name}-->
+<#-- <#list case.fields as field>-->
+<#-- <#switch field.typeName>-->
+<#-- <#case "array">-->
+<#-- <#assign
arrayField=field.asArrayField().orElseThrow()>-->
+<#-- <#assign
elementTypeReference=arrayField.type.elementTypeReference>-->
+<#-- PlcList values = (PlcList) _value;-->
- <#if case.name == "Struct">
- for (PlcValue val : ((List<PlcValue>)
values.getStruct().get("${arrayField.name}").getList())) {
- <#if elementTypeReference.isByteBased()>
- ${helper.getLanguageTypeNameForField(arrayField)} value =
(${helper.getLanguageTypeNameForField(arrayField)}) val.getRaw();
- writeBuffer.writeByteArray("", value);
- <#else>
- ${helper.getLanguageTypeNameForField(arrayField)} value =
(${helper.getLanguageTypeNameForField(arrayField)})
val.get${helper.getLanguageTypeNameForField(arrayField)?cap_first}();
-
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"value", arrayField)};
- </#if>
- }
- <#else>
- for (PlcValue val : ((List<PlcValue>) values.getList())) {
- <#if elementTypeReference.isByteBased()>
- byte[] value = (byte[]) val.getRaw();
- writeBuffer.writeByteArray("", value);
- <#else>
-
${helper.getLanguageTypeNameForTypeReference(elementTypeReference)} value =
(${helper.getLanguageTypeNameForTypeReference(elementTypeReference)})
val.get${helper.getLanguageTypeNameForTypeReference(elementTypeReference)?cap_first}();
-
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"(" + arrayField.name + ")", arrayField)};
- </#if>
- }
- </#if>
+<#-- <#if case.name == "Struct">-->
+<#-- for (PlcValue val : ((List<PlcValue>)
values.getStruct().get("${arrayField.name}").getList())) {-->
+<#-- <#if elementTypeReference.isByteBased()>-->
+<#-- ${helper.getLanguageTypeNameForField(arrayField)} value =
(${helper.getLanguageTypeNameForField(arrayField)}) val.getRaw();-->
+<#-- writeBuffer.writeByteArray("", value);-->
+<#-- <#else>-->
+<#-- ${helper.getLanguageTypeNameForField(arrayField)} value =
(${helper.getLanguageTypeNameForField(arrayField)})
val.get${helper.getLanguageTypeNameForField(arrayField)?cap_first}();-->
+<#--
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"value", arrayField)};-->
+<#-- </#if>-->
+<#-- }-->
+<#-- <#else>-->
+<#-- for (PlcValue val : ((List<PlcValue>) values.getList())) {-->
+<#-- <#if elementTypeReference.isByteBased()>-->
+<#-- byte[] value = (byte[]) val.getRaw();-->
+<#-- writeBuffer.writeByteArray("", value);-->
+<#-- <#else>-->
+<#--
${helper.getLanguageTypeNameForTypeReference(elementTypeReference)} value =
(${helper.getLanguageTypeNameForTypeReference(elementTypeReference)})
val.get${helper.getLanguageTypeNameForTypeReference(elementTypeReference)?cap_first}();-->
+<#--
${helper.getWriteBufferWriteMethodCall(elementTypeReference.asSimpleTypeReference().orElseThrow(),
"(" + arrayField.name + ")", arrayField)};-->
+<#-- </#if>-->
+<#-- }-->
+<#-- </#if>-->
- <#if case.name == "BOOL">
- while (writeBuffer.getPos() < writeBuffer.getData().length) {
- writeBuffer.writeBit(false);
- }
- </#if>
- <#break>
- <#case "const">
- <#assign constField=field.asConstField().orElseThrow()>
- // Const Field (${constField.name})
-
${helper.getWriteBufferWriteMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
constField.referenceValue, constField)};
- <#break>
- <#case "enum">
- <#assign enumField=field.asEnumField().orElseThrow()>
- // Enum field (${enumField.name})
- ${helper.getLanguageTypeNameForField(field)} ${enumField.name} =
(${helper.getLanguageTypeNameForField(field)})
_value.get${enumField.name?cap_first}();
-
${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(field.asTypedField().orElseThrow().type),
"(" + enumField.name + ".getValue())", enumField)};
- <#break>
- <#case "manual">
- <#assign
manualField=field.asManualField().orElseThrow()>
- // Manual Field (${manualField.name})
- ${helper.toSerializationExpression(manualField, manualField.type,
manualField.serializeExpression, type.parserArguments.orElse(null))};
- <#break>
- <#case "reserved">
- <#assign
reservedField=field.asReservedField().orElseThrow()>
- // Reserved Field
-
${helper.getWriteBufferWriteMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
helper.getReservedValue(reservedField), reservedField)};
- <#break>
- <#case "simple">
- <#assign
simpleField=field.asSimpleField().orElseThrow()>
- // Simple Field (${simpleField.name})
- <#if case.name == "Struct">
- ${helper.getLanguageTypeNameForField(simpleField)}
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)})
_value.getStruct().get("${simpleField.name}").get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();
- <#else>
- <#if simpleField.name == "value">
- ${helper.getLanguageTypeNameForField(simpleField)}
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)})
_value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();
- <#else>
- <#-- Just for now -->
- ${helper.getLanguageTypeNameForField(simpleField)}
${simpleField.name} = ${helper.getNullValueForTypeReference(simpleField.type)};
- </#if>
- </#if>
- <#if simpleField.type.isSimpleTypeReference()>
-
${helper.getWriteBufferWriteMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
"(" + simpleField.name + ")", simpleField)};
- <#else>
-
${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticSerialize(writeBuffer,
${simpleField.name});
- </#if>
- <#break>
- </#switch>
- </#list>
- }<#sep> else </#sep></#list>
- }
-</#if>
+<#-- <#if case.name == "BOOL">-->
+<#-- while (writeBuffer.getPos() < writeBuffer.getData().length)
{-->
+<#-- writeBuffer.writeBit(false);-->
+<#-- }-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- <#case "const">-->
+<#-- <#assign
constField=field.asConstField().orElseThrow()>-->
+<#-- // Const Field (${constField.name})-->
+<#--
${helper.getWriteBufferWriteMethodCall(constField.type.asSimpleTypeReference().orElseThrow(),
constField.referenceValue, constField)};-->
+<#-- <#break>-->
+<#-- <#case "enum">-->
+<#-- <#assign
enumField=field.asEnumField().orElseThrow()>-->
+<#-- // Enum field (${enumField.name})-->
+<#-- ${helper.getLanguageTypeNameForField(field)} ${enumField.name}
= (${helper.getLanguageTypeNameForField(field)})
_value.get${enumField.name?cap_first}();-->
+<#--
${helper.getWriteBufferWriteMethodCall(helper.getEnumBaseTypeReference(field.asTypedField().orElseThrow().type),
"(" + enumField.name + ".getValue())", enumField)};-->
+<#-- <#break>-->
+<#-- <#case "manual">-->
+<#-- <#assign
manualField=field.asManualField().orElseThrow()>-->
+<#-- // Manual Field (${manualField.name})-->
+<#-- ${helper.toSerializationExpression(manualField,
manualField.type, manualField.serializeExpression,
type.parserArguments.orElse(null))};-->
+<#-- <#break>-->
+<#-- <#case "reserved">-->
+<#-- <#assign
reservedField=field.asReservedField().orElseThrow()>-->
+<#-- // Reserved Field-->
+<#--
${helper.getWriteBufferWriteMethodCall(reservedField.type.asSimpleTypeReference().orElseThrow(),
helper.getReservedValue(reservedField), reservedField)};-->
+<#-- <#break>-->
+<#-- <#case "simple">-->
+<#-- <#assign
simpleField=field.asSimpleField().orElseThrow()>-->
+<#-- // Simple Field (${simpleField.name})-->
+<#-- <#if case.name == "Struct">-->
+<#-- ${helper.getLanguageTypeNameForField(simpleField)}
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)})
_value.getStruct().get("${simpleField.name}").get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();-->
+<#-- <#else>-->
+<#-- <#if simpleField.name == "value">-->
+<#-- ${helper.getLanguageTypeNameForField(simpleField)}
${simpleField.name} = (${helper.getLanguageTypeNameForField(field)})
_value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}();-->
+<#-- <#else>-->
+<#-- <#– Just for now –>-->
+<#-- ${helper.getLanguageTypeNameForField(simpleField)}
${simpleField.name} =
${helper.getNullValueForTypeReference(simpleField.type)};-->
+<#-- </#if>-->
+<#-- </#if>-->
+<#-- <#if simpleField.type.isSimpleTypeReference()>-->
+<#--
${helper.getWriteBufferWriteMethodCall(simpleField.type.asSimpleTypeReference().orElseThrow(),
"(" + simpleField.name + ")", simpleField)};-->
+<#-- <#else>-->
+<#--
${simpleField.type.asComplexTypeReference().orElseThrow().name}IO.staticSerialize(writeBuffer,
${simpleField.name});-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- </#switch>-->
+<#-- </#list>-->
+<#-- }<#sep> else </#sep></#list>-->
+<#-- }-->
+<#--</#if>-->
- public static int getLengthInBytes(PlcValue _value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
- return (int) Math.ceil((float) getLengthInBits(_value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>) / 8.0);
- }
+<#-- public static int getLengthInBytes(PlcValue _value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {-->
+<#-- return (int) Math.ceil((float) getLengthInBits(_value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>) / 8.0);-->
+<#-- }-->
- public static int getLengthInBits(PlcValue _value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
- int sizeInBits = 0;
- <#assign defaultCaseOutput=false>
- <#assign
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>
- <#list dataIoTypeDefinition.switchField.orElseThrow().cases as case>
- <@compress single_line=true>
- <#if case.discriminatorValueTerms?has_content>
- if(
- <#list case.discriminatorValueTerms as discriminatorValueTerm>
- <#assign
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
- <#assign
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>
- EvaluationHelper.equals(
-
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorExpression, parserArguments)},
- <#if discriminatorType.isEnumTypeReference()>
-
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}
- <#else>
-
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}
- </#if>
- )
- <#sep> && </#sep>
- </#list>
- )
- <#else>
- <#assign defaultCaseOutput=true>
- </#if>
- </@compress> { // ${case.name}
- <#list case.fields as field>
- <#switch field.typeName>
- <#case "array">
- <#assign arrayField=field.asArrayField().orElseThrow()>
- <#assign
elementTypeReference=arrayField.type.elementTypeReference>
- PlcList values = (PlcList) _value;
- <#if case.name == "Struct">
- // TODO: Finish this!
- <#elseif elementTypeReference.isComplexTypeReference()>
- // TODO: Finish this!
- <#else>
- sizeInBits += values.getList().size() *
${elementTypeReference.asSimpleTypeReference().orElseThrow().sizeInBits};
- </#if>
- <#break>
- <#case "const">
- <#assign constField=field.asConstField().orElseThrow()>
- // Const Field (${constField.name})
- <#-- const fields are only simple type -->
- sizeInBits +=
${constField.type.asSimpleTypeReference().orElseThrow().sizeInBits};
- <#break>
- <#case "enum">
- <#assign enumField=field.asEnumField().orElseThrow()>
- // Enum field (${enumField.name})
- sizeInBits +=
${helper.getEnumFieldSimpleTypeReference(enumField.type,
enumField.fieldName).sizeInBits};
- <#break>
- <#case "manual">
- <#assign manualField=field.asManualField().orElseThrow()>
- // Manual Field (${manualField.name})
- sizeInBits += ${helper.toSerializationExpression(manualField,
helper.intTypeReference, manualField.lengthExpression,
type.parserArguments.orElse(null))};
- <#break>
- <#case "reserved">
- <#assign reservedField=field.asReservedField().orElseThrow()>
- // Reserved Field
- sizeInBits +=
${reservedField.type.asSimpleTypeReference().orElseThrow().sizeInBits};
- <#break>
- <#case "simple">
- <#assign simpleField=field.asSimpleField().orElseThrow()>
- // Simple Field (${simpleField.name})
- sizeInBits +=
${simpleField.type.asSimpleTypeReference().orElseThrow().sizeInBits};
- <#break>
- </#switch>
- </#list>
- }<#sep> else </#sep></#list>
- return sizeInBits;
- }
+<#-- public static int getLengthInBits(PlcValue _value<#if
type.parserArguments.isPresent()>, <#list type.parserArguments.orElseThrow() as
parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type,
false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {-->
+<#-- int sizeInBits = 0;-->
+<#-- <#assign defaultCaseOutput=false>-->
+<#-- <#assign
dataIoTypeDefinition=type.asDataIoTypeDefinition().orElseThrow()>-->
+<#-- <#list dataIoTypeDefinition.switchField.orElseThrow().cases as
case>-->
+<#-- <@compress single_line=true>-->
+<#-- <#if case.discriminatorValueTerms?has_content>-->
+<#-- if(-->
+<#-- <#list case.discriminatorValueTerms as
discriminatorValueTerm>-->
+<#-- <#assign
discriminatorExpression=dataIoTypeDefinition.switchField.orElseThrow().discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>-->
+<#-- <#assign
discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.name]>-->
+<#-- EvaluationHelper.equals(-->
+<#--
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorExpression, parserArguments)},-->
+<#-- <#if discriminatorType.isEnumTypeReference()>-->
+<#--
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#-- <#else>-->
+<#--
${helper.toParseExpression(dataIoTypeDefinition.switchField.orElseThrow(),
discriminatorType, discriminatorValueTerm, parserArguments)}-->
+<#-- </#if>-->
+<#-- )-->
+<#-- <#sep> && </#sep>-->
+<#-- </#list>-->
+<#-- )-->
+<#-- <#else>-->
+<#-- <#assign defaultCaseOutput=true>-->
+<#-- </#if>-->
+<#-- </@compress> { // ${case.name}-->
+<#-- <#list case.fields as field>-->
+<#-- <#switch field.typeName>-->
+<#-- <#case "array">-->
+<#-- <#assign arrayField=field.asArrayField().orElseThrow()>-->
+<#-- <#assign
elementTypeReference=arrayField.type.elementTypeReference>-->
+<#-- PlcList values = (PlcList) _value;-->
+<#-- <#if case.name == "Struct">-->
+<#-- // TODO: Finish this!-->
+<#-- <#elseif elementTypeReference.isComplexTypeReference()>-->
+<#-- // TODO: Finish this!-->
+<#-- <#else>-->
+<#-- sizeInBits += values.getList().size() *
${elementTypeReference.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#-- </#if>-->
+<#-- <#break>-->
+<#-- <#case "const">-->
+<#-- <#assign constField=field.asConstField().orElseThrow()>-->
+<#-- // Const Field (${constField.name})-->
+<#-- <#– const fields are only simple type
–>-->
+<#-- sizeInBits +=
${constField.type.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#-- <#break>-->
+<#-- <#case "enum">-->
+<#-- <#assign enumField=field.asEnumField().orElseThrow()>-->
+<#-- // Enum field (${enumField.name})-->
+<#-- sizeInBits +=
${helper.getEnumFieldSimpleTypeReference(enumField.type,
enumField.fieldName).sizeInBits};-->
+<#-- <#break>-->
+<#-- <#case "manual">-->
+<#-- <#assign
manualField=field.asManualField().orElseThrow()>-->
+<#-- // Manual Field (${manualField.name})-->
+<#-- sizeInBits +=
${helper.toSerializationExpression(manualField, helper.intTypeReference,
manualField.lengthExpression, type.parserArguments.orElse(null))};-->
+<#-- <#break>-->
+<#-- <#case "reserved">-->
+<#-- <#assign
reservedField=field.asReservedField().orElseThrow()>-->
+<#-- // Reserved Field-->
+<#-- sizeInBits +=
${reservedField.type.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#-- <#break>-->
+<#-- <#case "simple">-->
+<#-- <#assign
simpleField=field.asSimpleField().orElseThrow()>-->
+<#-- // Simple Field (${simpleField.name})-->
+<#-- sizeInBits +=
${simpleField.type.asSimpleTypeReference().orElseThrow().sizeInBits};-->
+<#-- <#break>-->
+<#-- </#switch>-->
+<#-- </#list>-->
+<#-- }<#sep> else </#sep></#list>-->
+<#-- return sizeInBits;-->
+<#-- }-->
-}
+<#--}-->
</#outputformat>
diff --git
a/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
b/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
index 2f58c5914c..ac60e18d2b 100644
---
a/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
+++
b/code-generation/language-rust/src/main/resources/templates/rust/enum-template.rs.ftlh
@@ -26,7 +26,8 @@
<#-- @ftlvariable name="helper"
type="org.apache.plc4x.language.rust.RustLanguageTemplateHelper" -->
<#-- @ftlvariable name="tracer"
type="org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer" -->
<#-- @ftlvariable name="type"
type="org.apache.plc4x.plugins.codegenerator.types.definitions.EnumTypeDefinition"
-->
-${helper.packageName(protocolName, languageName, outputFlavor)?replace(".",
"/")}/${type.name}.rs
+src/${type.name}.rs
+<#--${helper.packageName(protocolName, languageName,
outputFlavor)?replace(".", "/")}/${type.name}.rs-->
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -46,9 +47,11 @@ ${helper.packageName(protocolName, languageName,
outputFlavor)?replace(".", "/")
* under the License.
*/
// package ${helper.packageName(protocolName, languageName, outputFlavor)};
-use crate::plc4x_enum;
+<#--use crate::plc4x_enum;-->
use std::io::{Error, ErrorKind, Read, Write};
-use crate::{Message, NoOption, ReadBuffer, WriteBuffer};
+use plc4rust::{Message, NoOption};
+use plc4rust::read_buffer::ReadBuffer;
+use plc4rust::write_buffer::WriteBuffer;
<#list helper.generateImports(type) as import>
<#if type.name != import>
@@ -78,7 +81,7 @@ impl
TryFrom<${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(
fn try_from(value:
${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)})
-> Result<Self, Self::Error> {
match value {
<#list type.enumValues as enumValue>
- ${enumValue.value} => ${enumValue.name},
+ ${enumValue.value} => Ok(${type.name}::${enumValue.name}),
</#list>
_ => {
panic!("Unable to deserialize enum!")
@@ -88,7 +91,7 @@ impl
TryFrom<${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(
}
impl
Into<${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(),
true)}> for ${type.name} {
- fn into(self) -> ${type.name} {
+ fn into(self) ->
${helper.getLanguageTypeNameForTypeReference(type.type.orElseThrow(), true)} {
match self {
<#list type.enumValues as enumValue>
${enumValue.name} => ${enumValue.value}<#sep>,</#sep>
diff --git a/plc4rust/src/read_buffer.rs b/plc4rust/src/read_buffer.rs
index 25e1cefbd6..8f4161eb04 100644
--- a/plc4rust/src/read_buffer.rs
+++ b/plc4rust/src/read_buffer.rs
@@ -43,11 +43,11 @@ impl<T: Read> ReadBuffer<T> {
impl<T: Read> ReadBuffer<T> {
- pub(crate) fn read_bit(&mut self) -> Result<bool, std::io::Error> {
+ pub fn read_bit(&mut self) -> Result<bool, std::io::Error> {
Ok(self.read_u_n(1)? > 0)
}
- pub(crate) fn read_u8(&mut self) -> Result<u8, std::io::Error> {
+ pub fn read_u8(&mut self) -> Result<u8, std::io::Error> {
let mut byte = [0_u8; 1];
self.reader.read(&mut byte)?;
// println!("read_u8: {}", byte[0]);
@@ -55,7 +55,7 @@ impl<T: Read> ReadBuffer<T> {
Ok(byte[0])
}
- pub(crate) fn read_u16(&mut self) -> Result<u16, std::io::Error> {
+ pub fn read_u16(&mut self) -> Result<u16, std::io::Error> {
let mut bytes = [0_u8; 2];
self.reader.read(&mut bytes)?;
@@ -71,7 +71,11 @@ impl<T: Read> ReadBuffer<T> {
})
}
- pub(crate) fn read_u_n(&mut self, number_of_bits: u8) -> Result<u64,
std::io::Error> {
+ pub fn read_u32(&mut self) -> Result<u32, std::io::Error> {
+ todo!()
+ }
+
+ pub fn read_u_n(&mut self, number_of_bits: u8) -> Result<u64,
std::io::Error> {
match self.bit_reader.read(number_of_bits, &mut self.reader) {
Ok(value) => {
Ok(value as u64)