You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by ld...@apache.org on 2020/09/01 09:42:42 UTC

[plc4x] 01/11: PLC4X-244 Support for variable length padding fields.

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

ldywicki pushed a commit to branch feature/socketcan
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 31da84d434bb9dfe07fe6ec3db19e1ef8435b5ed
Author: Ɓukasz Dywicki <lu...@code-house.org>
AuthorDate: Fri Aug 28 12:02:51 2020 +0200

    PLC4X-244 Support for variable length padding fields.
    
    Padding expression must now evaluate to an integer specifying how many times 'padding' field needs to be read or written to the buffer.
---
 .../src/main/resources/templates/c/pojo-template-c.ftlh       | 11 ++++++-----
 .../src/main/resources/templates/java/io-template.ftlh        |  8 ++++----
 .../src/main/resources/templates/java/pojo-template.ftlh      |  3 ++-
 protocols/s7/src/main/resources/protocols/s7/s7.mspec         |  2 +-
 src/site/asciidoc/developers/code-gen/protocol/mspec.adoc     |  6 ++++--
 5 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
index 13719d1..8901d25 100644
--- a/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
@@ -327,8 +327,8 @@ plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer*
 
 <#if indentContent>  </#if>  // Padding Field (padding)
 <#if indentContent>  </#if>  {
-<#if indentContent>  </#if>    bool _needsPadding = (bool) ((plc4c_spi_read_has_more(buf, ${helper.getNumBits(paddingField.type)})) && (${helper.toParseExpression(baseType, paddingField, paddingField.paddingCondition, baseType.parserArguments)}));
-<#if indentContent>  </#if>    if(_needsPadding) {
+<#if indentContent>  </#if>    int _needsPadding = (int) ((plc4c_spi_read_has_more(buf, ${helper.getNumBits(paddingField.type)})) && (${helper.toParseExpression(baseType, paddingField, paddingField.paddingCondition, baseType.parserArguments)}));
+<#if indentContent>  </#if>    while (_needsPadding-- > 0) {
 <#if indentContent>  </#if>      // Just read the padding data and ignore it
 <#if indentContent>  </#if>      ${helper.getLanguageTypeNameForField(field)} _paddingValue = ${helper.getNullValueForTypeReference(paddingField.type)};
 <#if indentContent>  </#if>      _res = ${helper.getReadBufferReadMethodCall(paddingField.type, "&_paddingValue")};
@@ -516,8 +516,8 @@ plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_bu
 <#if indentContent>    </#if>  // Padding Field (padding)
 <#if indentContent>    </#if>  {
     <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last -->
-<#if indentContent>    </#if>    bool _needsPadding = (bool) (${helper.toSerializationExpression(baseType, paddingField, paddingField.paddingCondition, baseType.parserArguments)});
-<#if indentContent>    </#if>    if(_needsPadding) {
+<#if indentContent>    </#if>    int _needsPadding = (int) (${helper.toSerializationExpression(baseType, paddingField, paddingField.paddingCondition, baseType.parserArguments)});
+<#if indentContent>    </#if>    while (_needsPadding-- > 0) {
 <#if indentContent>    </#if>      // Just output the default padding data
 <#if indentContent>    </#if>      _res = ${helper.getWriteBufferWriteMethodCall(paddingField.type, helper.toParseExpression(baseType, paddingField, paddingField.paddingValue, baseType.parserArguments))};
 <#if indentContent>    </#if>      if(_res != OK) {
@@ -663,7 +663,8 @@ uint16_t ${helper.getCTypeName(type.name)}_length_in_bits(${helper.getCTypeName(
 
 <#if indentContent>    </#if>  // Padding Field (padding)
             <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last -->
-<#if indentContent>    </#if>  if((bool) (${helper.toSerializationExpression(type, paddingField, paddingField.paddingCondition, type.parserArguments)?replace("lastItem", "false")})) {
+<#if indentContent>    </#if> int _needsPadding = (int) (${helper.toSerializationExpression(type, paddingField, paddingField.paddingCondition, type.parserArguments)?replace("lastItem", "false")})
+<#if indentContent>    </#if> while(_needsPadding-- > 0) {
 <#if indentContent>    </#if>    lengthInBits += ${simpleTypeReference.sizeInBits};
 <#if indentContent>    </#if>  }
                 <#break>
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 4c5ba3b..d90916d 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
@@ -338,8 +338,8 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
 
         // Padding Field (padding)
         {
-            boolean _needsPadding = (boolean) ((io.hasMore(${helper.getNumBits(simpleTypeReference)})) && (${helper.toParseExpression(paddingField, paddingField.paddingCondition, type.parserArguments)}));
-            if(_needsPadding) {
+            int _needsPadding = (int) (${helper.toParseExpression(paddingField, paddingField.paddingCondition, type.parserArguments)});
+            while ((io.hasMore(${helper.getNumBits(simpleTypeReference)})) && _needsPadding-- > 0) {
                 // Just read the padding data and ignore it
                 ${helper.getReadBufferReadMethodCall(simpleTypeReference)};
             }
@@ -505,8 +505,8 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
 
         // Padding Field (padding)
         {
-            boolean _needsPadding = (boolean) (${helper.toSerializationExpression(paddingField, paddingField.paddingCondition, type.parserArguments)});
-            if(_needsPadding) {
+            int _needsPadding = (int) (${helper.toSerializationExpression(paddingField, paddingField.paddingCondition, type.parserArguments)});
+            while (_needsPadding-- > 0) {
                 ${helper.getLanguageTypeNameForField(field)} _paddingValue = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(paddingField, paddingField.paddingValue, type.parserArguments)});
                 ${helper.getWriteBufferWriteMethodCall(simpleTypeReference, "(_paddingValue)")};
             }
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 bf469eb..58a96ef 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
@@ -251,7 +251,8 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${
 
         // Padding Field (padding)
         <#-- We're replacing the "lastItem" with 'false' here as the item itself can't know if it is the last -->
-        if((boolean) (${helper.toParseExpression(paddingField, paddingField.paddingCondition, type.parserArguments)?replace("lastItem", "false")})) {
+        int _needsPadding = (int) (${helper.toParseExpression(paddingField, paddingField.paddingCondition, type.parserArguments)?replace("lastItem", "false")});
+        while (_needsPadding-- > 0) {
             lengthInBits += ${simpleTypeReference.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 7d4f9c1..34808bb 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -234,7 +234,7 @@
     [enum     DataTransportSize      'transportSize']
     [implicit uint 16                'dataLength' 'COUNT(data) * ((transportSize == DataTransportSize.BIT) ? 1 : (transportSize.sizeInBits ? 8 : 1))']
     [array    int  8                 'data'       count 'transportSize.sizeInBits ? CEIL(dataLength / 8.0) : dataLength']
-    [padding  uint 8                 'pad'        '0x00' '!lastItem && ((COUNT(data) % 2) == 1)']
+    [padding  uint 8                 'pad'        '0x00' 'lastItem ? 0 : COUNT(data) % 2']
 ]
 
 [type 'S7VarPayloadStatusItem'
diff --git a/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc b/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc
index a0603f2..90b774b 100644
--- a/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc
+++ b/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc
@@ -230,11 +230,13 @@ See also:
 
 ==== padding Field
 
-A padding field outputs additional padding data, if an expression evaluates to `true`.
+A padding field allows aligning of data blocks.
+It outputs additional padding data, given amount of times specified by padding expression.
+Padding is added only when result of expression is bigger than zero.
 
     [padding {simple-type} {size} '{pading-value}' '{padding-expression}']
 
-When parsing a `padding` field is just consumed without being made available as property or local valiable if the `padding-expression` evaluates to true.
+When parsing a `padding` field is just consumed without being made available as property or local variable if the `padding-expression` evaluates to value greater than zero.
 If it doesn't, it is just skipped.
 
 This field doesn't keep any data in memory.