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 2020/01/17 12:04:26 UTC

[plc4x] branch develop updated: - Updated the code generator to provide a local 'checksumRawData' field for checksum fields containing a byte[] with all the bytes of the current type read so far - Fixed a bug in the ReadBuffer getPos implementation - Moved the types for reading and writing into the plc4x package namespace

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

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 2240a97  - Updated the code generator to provide a local 'checksumRawData' field for checksum fields containing a byte[] with all the bytes of the current type read so far - Fixed a bug in the ReadBuffer getPos implementation - Moved the types for reading and writing into the plc4x package namespace
2240a97 is described below

commit 2240a9711d4ae6a07ffb0a4f74c9ca27114e2cb3
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Jan 17 13:04:18 2020 +0100

    - Updated the code generator to provide a local 'checksumRawData' field for checksum fields containing a byte[] with all the bytes of the current type read so far
    - Fixed a bug in the ReadBuffer getPos implementation
    - Moved the types for reading and writing into the plc4x package namespace
---
 .../language/java/JavaLanguageTemplateHelper.java  |  4 +++
 .../main/resources/templates/java/io-template.ftlh | 24 ++++++++++----
 .../plc4x/java/spi/generation/ReadBuffer.java      |  9 +++++-
 .../plc4x/java/spi/generation/WriteBuffer.java     | 20 +++++++++---
 .../java/spi/generation}/io/MyDefaultBitInput.java |  7 ++--
 .../java/spi/generation/io/MyDefaultBitOutput.java | 37 ++++++++++++++++++++++
 .../developers/code-gen/protocol/mspec.adoc        |  2 ++
 7 files changed, 89 insertions(+), 14 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 cc95fa5..47ac6f2 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
@@ -682,6 +682,10 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
             return sb.toString();
         }
         boolean isSerializerArg = false;
+        // The synthetic checksumRawData is a local field and should not be accessed as bean property.
+        if(vl.getName().equals("checksumRawData")) {
+            isSerializerArg = true;
+        }
         if(parserArguments != null) {
             for (Argument parserArgument : parserArguments) {
                 if (parserArgument.getName().equals(vl.getName())) {
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 385d247..3c0457a 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
@@ -131,10 +131,15 @@ public class ${typeName}IO {
     <#case "checksum">
 
         // Checksum Field (${field.name})
-        ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
-        ${helper.getLanguageTypeNameForField(field)} _${field.name}Ref = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(field.checksumExpression, type.parserArguments)});
-        if(${field.name} != _${field.name}Ref) {
-            throw new ParseException(String.format("Checksum verification failed. Expected %04X but got %04X",_${field.name}Ref & 0xFFFF, ${field.name} & 0xFFFF));
+        ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForType(field.type)};
+        {
+            // Create an array of all the bytes read in this message element so far.
+            byte[] checksumRawData = io.getBytes(startPos, io.getPos());
+            ${helper.getLanguageTypeNameForField(field)} _${field.name}Ref = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
+            ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(field.checksumExpression, type.parserArguments)});
+            if(${field.name} != _${field.name}Ref) {
+                throw new ParseException(String.format("Checksum verification failed. Expected %04X but got %04X",_${field.name}Ref & 0xFFFF, ${field.name} & 0xFFFF));
+            }
         }
         <#break>
     <#case "const">
@@ -292,6 +297,8 @@ public class ${typeName}IO {
 
 <#if outputFlavor != "passive">
     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 {
+        int startPos = io.getPos();
+
 <#list type.fields as field>
 <#switch field.typeName>
     <#case "array">
@@ -314,8 +321,13 @@ public class ${typeName}IO {
     <#case "checksum">
 
         // Checksum Field (${field.name}) (Calculated)
-        ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(field.checksumExpression, type.parserArguments)});
-        ${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")?no_esc};
+        ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForType(field.type)};
+        {
+            // Create an array of all the bytes written in this message element so far.
+            byte[] checksumRawData = io.getBytes(startPos, io.getPos());
+            ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toSerializationExpression(field.checksumExpression, type.parserArguments)});
+            ${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")?no_esc};
+        }
         <#break>
     <#case "const">
 
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
index 32c1c68..99ddeda 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
@@ -20,7 +20,7 @@
 package org.apache.plc4x.java.spi.generation;
 
 import com.github.jinahya.bit.io.ArrayByteInput;
-import com.github.jinahya.bit.io.MyDefaultBitInput;
+import org.apache.plc4x.java.spi.generation.io.MyDefaultBitInput;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -47,6 +47,13 @@ public class ReadBuffer {
         return (int) bi.getPos();
     }
 
+    public byte[] getBytes(int startPos, int endPos) {
+        int numBytes = endPos - startPos;
+        byte[] data = new byte[numBytes];
+        System.arraycopy(bi.getDelegate().getSource(), startPos, data, 0, numBytes);
+        return data;
+    }
+
     public boolean hasMore(int numBits) {
         return (numBits / 8) < (totalBytes - getPos());
     }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
index 2c3158f..7516277 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
@@ -19,9 +19,8 @@
 
 package org.apache.plc4x.java.spi.generation;
 
-import com.github.jinahya.bit.io.BitOutput;
 import com.github.jinahya.bit.io.BufferByteOutput;
-import com.github.jinahya.bit.io.DefaultBitOutput;
+import org.apache.plc4x.java.spi.generation.io.MyDefaultBitOutput;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -31,8 +30,8 @@ import java.nio.ByteBuffer;
 public class WriteBuffer {
 
     private final ByteBuffer bb;
-    private final BufferByteOutput bbo;
-    private final BitOutput bo;
+    private final BufferByteOutput<ByteBuffer> bbo;
+    private final MyDefaultBitOutput bo;
     private final boolean littleEndian;
 
     public WriteBuffer(int size) {
@@ -42,7 +41,7 @@ public class WriteBuffer {
     public WriteBuffer(int size, boolean littleEndian) {
         bb = ByteBuffer.allocate(size);
         bbo = new BufferByteOutput<>(bb);
-        bo = new DefaultBitOutput<>(bbo);
+        bo = new MyDefaultBitOutput(bbo);
         this.littleEndian = littleEndian;
     }
 
@@ -50,6 +49,17 @@ public class WriteBuffer {
         return bb.array();
     }
 
+    public int getPos() {
+        return (int) bo.getPos();
+    }
+
+    public byte[] getBytes(int startPos, int endPos) {
+        int numBytes = endPos - startPos;
+        byte[] data = new byte[numBytes];
+        System.arraycopy(bb.array(), startPos, data, 0, numBytes);
+        return data;
+    }
+
     public void writeBit(boolean value) throws ParseException {
         try {
             bo.writeBoolean(value);
diff --git a/plc4j/spi/src/main/java/com/github/jinahya/bit/io/MyDefaultBitInput.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/io/MyDefaultBitInput.java
similarity index 84%
rename from plc4j/spi/src/main/java/com/github/jinahya/bit/io/MyDefaultBitInput.java
rename to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/io/MyDefaultBitInput.java
index eb538d9..7f63f85 100644
--- a/plc4j/spi/src/main/java/com/github/jinahya/bit/io/MyDefaultBitInput.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/io/MyDefaultBitInput.java
@@ -17,7 +17,10 @@
  under the License.
  */
 
-package com.github.jinahya.bit.io;
+package org.apache.plc4x.java.spi.generation.io;
+
+import com.github.jinahya.bit.io.ArrayByteInput;
+import com.github.jinahya.bit.io.DefaultBitInput;
 
 /**
  * Modified version that exposes the position.
@@ -29,7 +32,7 @@ public class MyDefaultBitInput extends DefaultBitInput<ArrayByteInput> {
     }
 
     public long getPos() {
-        return count;
+        return delegate.getIndex();
     }
 
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/io/MyDefaultBitOutput.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/io/MyDefaultBitOutput.java
new file mode 100644
index 0000000..086a8e6
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/io/MyDefaultBitOutput.java
@@ -0,0 +1,37 @@
+/*
+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 org.apache.plc4x.java.spi.generation.io;
+
+import com.github.jinahya.bit.io.BufferByteOutput;
+import com.github.jinahya.bit.io.DefaultBitOutput;
+
+import java.nio.ByteBuffer;
+
+public class MyDefaultBitOutput extends DefaultBitOutput<BufferByteOutput> {
+
+    public MyDefaultBitOutput(BufferByteOutput delegate) {
+        super(delegate);
+    }
+
+    @SuppressWarnings("unchecked")
+    public long getPos() {
+        return ((BufferByteOutput<ByteBuffer>) getDelegate()).getTarget().position();
+    }
+
+}
diff --git a/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc b/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc
index 357beda..a0603f2 100644
--- a/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc
+++ b/src/site/asciidoc/developers/code-gen/protocol/mspec.adoc
@@ -151,6 +151,8 @@ If they don't match an exception is thrown.
 
 When serializing, the `checksum-expression` is evaluated and the result is then output.
 
+Note: As quite often a checksum is calculated based on the byte data of a message read up to the checksum, an artificial variable is available in expressions called `checksumRawData` of type `byte[]` which contains an array of all the byte data read in the current message element and it's sub types in case of a discriminated type.
+
 This field doesn't keep any data in memory.
 
 See also: