You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2019/12/27 19:16:10 UTC

[plc4x] 05/09: - Make additional count array data available (Helping making the padding in s7 more correct)

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch next-gen-core
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 2c7c80a53d179eef94cf4d572f59a0acb9505a2e
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Dec 26 23:57:12 2019 +0100

    - Make additional count array data available (Helping making the padding in s7 more correct)
---
 .../language/java/JavaLanguageTemplateHelper.java  | 39 ++++++++++++++++++++--
 .../resources/templates/java/data-io-template.ftlh |  2 +-
 .../main/resources/templates/java/io-template.ftlh | 13 +++++---
 .../resources/templates/java/pojo-template.ftlh    |  3 +-
 .../s7/src/main/resources/protocols/s7/s7.mspec    |  8 ++---
 5 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 41ff0df..cc95fa5 100644
--- a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -27,9 +27,7 @@ import org.apache.plc4x.plugins.codegenerator.types.fields.*;
 import org.apache.plc4x.plugins.codegenerator.types.references.*;
 import org.apache.plc4x.plugins.codegenerator.types.terms.*;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -770,4 +768,39 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
         return (SimpleTypeReference) enumTypeDefinition.getType();
     }
 
+    public List<Argument> getSerializerArguments(Argument[] arguments) {
+        List<Argument> serializerArguments = new LinkedList<>();
+        if(arguments != null) {
+            for (Argument argument : arguments) {
+                if ("lastItem".equals(argument.getName())) {
+                    serializerArguments.add(argument);
+                }
+            }
+        }
+        return serializerArguments;
+    }
+
+    public boolean hasLastItemTerm(Term[] terms) {
+        if(terms != null) {
+            for (Term term : terms) {
+                if (term.contains("lastItem")) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public List<Term> getSerializerTerms(Term[] terms) {
+        List<Term> serializerTerms = new LinkedList<>();
+        if(terms != null) {
+            for (Term term : terms) {
+                if (term.contains("lastItem")) {
+                    serializerTerms.add(term);
+                }
+            }
+        }
+        return serializerTerms;
+    }
+
 }
diff --git a/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
index 5e7966b..7f3d864 100644
--- a/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
@@ -192,7 +192,7 @@ public class ${typeName}IO {
             <#if case.name == "Struct">
             Map<String, PlcValue> _map = new HashMap<>();
                 <#list case.fields as field>
-            _map.put("${field.name}", PlcValue.of(${field.name}));
+            _map.put("${field.name}", PlcValues.of(${field.name}));
                 </#list>
             </#if>
             <#if !skipReturn>
diff --git a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
index fb06dfe..385d247 100644
--- a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
@@ -81,6 +81,7 @@ public class ${typeName}IO {
             int itemCount = (int) ${helper.toParseExpression(field.loopExpression, type.parserArguments)?no_esc};
             ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[itemCount];
             for(int curItem = 0; curItem < itemCount; curItem++) {
+                <#if !helper.isSimpleType(field.type)>boolean lastItem = curItem == (itemCount - 1);</#if>
                 ${field.name}[curItem] = <#if helper.isSimpleType(field.type)>${helper.getReadBufferReadMethodCall(field.type)?no_esc}<#else>${field.type.name}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toParseExpression(parserArgument, type.parserArguments)?no_esc})<#sep>, </#sep></#list></#if>)</#if>;
             }
         }
@@ -236,7 +237,7 @@ public class ${typeName}IO {
     <#case "padding">
 
         // Padding Field (${field.name})
-        boolean _${field.name}NeedsPadding = (boolean) ((io.hasMore(${helper.getNumBits(field.type)})) && (${helper.toParseExpression(field.paddingCondition, type.parserArguments)}));
+        boolean _${field.name}NeedsPadding = (boolean) ((io.hasMore(${helper.getNumBits(field.type)})) && (${helper.toParseExpression(field.paddingCondition, type.parserArguments)?no_esc}));
         if(_${field.name}NeedsPadding) {
             // Just read the padding data and ignore it
             ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
@@ -290,19 +291,23 @@ public class ${typeName}IO {
     }
 
 <#if outputFlavor != "passive">
-    public static void serialize(WriteBuffer io, ${typeName} _value) throws ParseException {
+    public static void serialize(WriteBuffer io, ${typeName} _value<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeName(parserArgument.type, false)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
 <#list type.fields as field>
 <#switch field.typeName>
     <#case "array">
 
         // Array Field (${field.name})
         if(_value.get${field.name?cap_first}() != null) {
+            int itemCount = (int) _value.get${field.name?cap_first}().length;
+            int curItem = 0;
             for(${helper.getLanguageTypeNameForField(field)} element : _value.get${field.name?cap_first}()) {
                 <#if helper.isSimpleType(field.type)>
                 ${helper.getWriteBufferReadMethodCall(field.type, "element")?no_esc};
                 <#else>
-                ${field.type.name}IO.serialize(io, element);
+                boolean lastItem = curItem == (itemCount - 1);
+                ${field.type.name}IO.serialize(io, element<#if helper.getSerializerTerms(field.params)?has_content>, <#list helper.getSerializerTerms(field.params) as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
                 </#if>
+                curItem++;
             }
         }
         <#break>
@@ -365,7 +370,7 @@ public class ${typeName}IO {
     <#case "padding">
 
         // Padding Field (${field.name})
-        boolean _${field.name}NeedsPadding = (boolean) (${helper.toSerializationExpression(field.paddingCondition, type.parserArguments)});
+        boolean _${field.name}NeedsPadding = (boolean) (${helper.toSerializationExpression(field.paddingCondition, type.parserArguments)?no_esc});
         if(_${field.name}NeedsPadding) {
             ${helper.getLanguageTypeNameForField(field)} _${field.name}PaddingValue = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(field.paddingValue, type.parserArguments)});
             ${helper.getWriteBufferReadMethodCall(field.type, "(_" + field.name + "PaddingValue)")?no_esc};
diff --git a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
index c548867..41e3ee3 100644
--- a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
@@ -182,7 +182,8 @@ public<#if type.abstract> abstract</#if> class ${typeName}<#if type.parentType??
     <#case "padding">
 
         // Padding Field (${field.name})
-        if((boolean) (${helper.toParseExpression(field.paddingCondition, type.parserArguments)})) {
+        <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last -->
+        if((boolean) (${helper.toParseExpression(field.paddingCondition, type.parserArguments)?replace("lastItem", "false")?no_esc})) {
             lengthInBits += ${field.type.sizeInBits};
         }
         <#break>
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 9f44ff3..618001d 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -214,10 +214,10 @@
         ['0x04','0x01' S7PayloadReadVarRequest
         ]
         ['0x04','0x03' S7PayloadReadVarResponse
-            [array S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems']
+            [array S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems' ['lastItem']]
         ]
         ['0x05','0x01' S7PayloadWriteVarRequest
-            [array S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)']
+            [array S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)' ['lastItem']]
         ]
         ['0x05','0x03' S7PayloadWriteVarResponse
             [array S7VarPayloadStatusItem 'items' count 'CAST(parameter, S7ParameterWriteVarResponse).numItems']
@@ -229,12 +229,12 @@
 ]
 
 // This is actually not quite correct as depending pon the transportSize the length is either defined in bits or bytes.
-[type 'S7VarPayloadDataItem'
+[type 'S7VarPayloadDataItem' [bit 'lastItem']
     [enum    DataTransportErrorCode 'returnCode']
     [enum    DataTransportSize      'transportSize']
     [simple  uint 16                'dataLength']
     [array   int  8                 'data' count 'transportSize.sizeInBits ? CEIL(dataLength / 8.0) : dataLength']
-    [padding uint 8                 'pad' '0x00' '(COUNT(data) % 2) == 1']
+    [padding uint 8                 'pad' '0x00' '!lastItem && ((COUNT(data) % 2) == 1)']
 ]
 
 [type 'S7VarPayloadStatusItem'