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/10/26 15:46:42 UTC

[plc4x] branch feature/plc4go updated (a1720ad -> fd80b89)

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

cdutz pushed a change to branch feature/plc4go
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from a1720ad  - Addressed some issues in the reading of values via S7 protocol
     new 75bc370  - Continued working on the serializer/parser testsuite for go
     new fd80b89  - Added the parse-char stuff to plc4c

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../BaseFreemarkerLanguageTemplateHelper.java      |   7 +-
 .../apache/plc4x/language/go/GoLanguageOutput.java |   5 +-
 .../templates/go/parser-factory-template.ftlh      |  95 +++++++++++
 .../apache/plc4x/java/s7/utils/StaticHelper.java   |  10 ++
 sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h |   2 +
 sandbox/plc4c/drivers/s7/src/driver_s7.c           |   5 +
 sandbox/plc4c/generated-sources/s7/src/data_item.c |  10 ++
 sandbox/plc4go/cmd/main/drivers/modbus_test.go     |   2 +-
 .../tests/modbus_parser_serializer_test.go}        |  20 +--
 sandbox/plc4go/go.mod                              |   2 +
 sandbox/plc4go/go.sum                              |   8 +-
 .../bacnetip/readwrite/model/ParserHelper.go       |  78 +++++++++
 .../knxnetip/readwrite/model/ParserHelper.go       |  90 ++++++++++
 .../plc4go/modbus/readwrite/model/ParserHelper.go  |  62 +++++++
 .../internal/plc4go/s7/readwrite/model/DataItem.go |  16 ++
 .../plc4go/s7/readwrite/model/ParserHelper.go      |  87 ++++++++++
 .../plc4go/s7/readwrite/model/S7StaticHelper.go    |   4 +
 .../plc4go/testutils/ParserSerializerTestRunner.go | 185 ++++++++++++++++++++-
 sandbox/plc4go/internal/plc4go/utils/CastUtils.go  |  26 +++
 .../plc4go/utils/{Utils.go => ParserHelper.go}     |  12 +-
 .../plc4go/utils/Serializable.go}                  |   5 +-
 21 files changed, 693 insertions(+), 38 deletions(-)
 create mode 100644 build-utils/language-go/src/main/resources/templates/go/parser-factory-template.ftlh
 copy sandbox/plc4go/{internal/plc4go/testutils/ParserSerializerTestRunner.go => cmd/main/drivers/tests/modbus_parser_serializer_test.go} (75%)
 create mode 100644 sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go
 create mode 100644 sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go
 create mode 100644 sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go
 create mode 100644 sandbox/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go
 copy sandbox/plc4go/internal/plc4go/utils/{Utils.go => ParserHelper.go} (81%)
 copy sandbox/plc4go/{cmd/main/main.go => internal/plc4go/utils/Serializable.go} (91%)


[plc4x] 01/02: - Continued working on the serializer/parser testsuite for go

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 75bc37050414cda0fc5654c8315d052df88e269f
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Oct 26 16:46:15 2020 +0100

    - Continued working on the serializer/parser testsuite for go
---
 .../BaseFreemarkerLanguageTemplateHelper.java      |   7 +-
 .../apache/plc4x/language/go/GoLanguageOutput.java |   5 +-
 .../templates/go/parser-factory-template.ftlh      |  95 +++++++++++
 .../apache/plc4x/java/s7/utils/StaticHelper.java   |  10 ++
 sandbox/plc4go/cmd/main/drivers/modbus_test.go     |   2 +-
 .../tests/modbus_parser_serializer_test.go}        |  20 +--
 sandbox/plc4go/go.mod                              |   2 +
 sandbox/plc4go/go.sum                              |   8 +-
 .../bacnetip/readwrite/model/ParserHelper.go       |  78 +++++++++
 .../knxnetip/readwrite/model/ParserHelper.go       |  90 ++++++++++
 .../plc4go/modbus/readwrite/model/ParserHelper.go  |  62 +++++++
 .../internal/plc4go/s7/readwrite/model/DataItem.go |  16 ++
 .../plc4go/s7/readwrite/model/ParserHelper.go      |  87 ++++++++++
 .../plc4go/s7/readwrite/model/S7StaticHelper.go    |   4 +
 .../plc4go/testutils/ParserSerializerTestRunner.go | 185 ++++++++++++++++++++-
 sandbox/plc4go/internal/plc4go/utils/CastUtils.go  |  26 +++
 .../plc4go/utils/ParserHelper.go}                  |  12 +-
 .../plc4go/utils/Serializable.go}                  |  12 +-
 18 files changed, 677 insertions(+), 44 deletions(-)

diff --git a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
index 74b91ff..0ce48c9 100644
--- a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
+++ b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
@@ -98,10 +98,15 @@ public abstract class BaseFreemarkerLanguageTemplateHelper implements Freemarker
         return flavorName;
     }
 
-    protected Map<String, TypeDefinition> getTypeDefinitions() {
+    public Map<String, TypeDefinition> getTypeDefinitions() {
         return types;
     }
 
+    public List<TypeDefinition> getComplexTypeRootDefinitions() {
+        return types.values().stream().filter(typeDefinition -> (typeDefinition instanceof ComplexTypeDefinition) &&
+            !(typeDefinition instanceof DiscriminatedComplexTypeDefinition)).collect(Collectors.toList());
+    }
+
     protected static Map<String, SimpleTypeReference> getBuiltInFieldTypes() {
         return builtInFields;
     }
diff --git a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
index b16b36e..a0f91a6 100644
--- a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
+++ b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
@@ -41,9 +41,8 @@ public class GoLanguageOutput extends FreemarkerLanguageOutput {
 
     @Override
     protected List<Template> getSpecTemplates(Configuration freemarkerConfiguration) throws IOException {
-        /*return Collections.singletonList(
-            freemarkerConfiguration.getTemplate("templates/go/enum-package-info-template.ftlh"));*/
-        return Collections.emptyList();
+        return Collections.singletonList(
+            freemarkerConfiguration.getTemplate("templates/go/parser-factory-template.ftlh"));
     }
 
     @Override
diff --git a/build-utils/language-go/src/main/resources/templates/go/parser-factory-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/parser-factory-template.ftlh
new file mode 100644
index 0000000..cc848bf
--- /dev/null
+++ b/build-utils/language-go/src/main/resources/templates/go/parser-factory-template.ftlh
@@ -0,0 +1,95 @@
+<#--
+  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.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.go.GoLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/ParserHelper.go
+//
+// 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 model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+type ${protocolName?cap_first}ParserHelper struct {
+}
+
+func (m ${protocolName?cap_first}ParserHelper) Parse(typeName string, arguments []string, io *utils.ReadBuffer) (spi.Message, error) {
+    switch typeName {
+<#list helper.getComplexTypeRootDefinitions() as typeDefinition>
+    case "${typeDefinition.name}":
+    <#if typeDefinition.parserArguments?has_content>
+        <#list typeDefinition.parserArguments as parserArgument>
+            <#if helper.isSimpleTypeReference(parserArgument.type)>
+        ${parserArgument.name}, err := utils.StrTo${helper.getLanguageTypeNameForTypeReference(parserArgument.type)?cap_first}(arguments[${parserArgument?index}])
+        if err != nil {
+            return nil, err
+        }
+            <#else>
+        var ${parserArgument.name} I${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}
+            </#if>
+        </#list>
+    </#if>
+        return ${typeDefinition.name}Parse(io<#if typeDefinition.parserArguments?has_content>, <#list typeDefinition.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#list></#if>)
+</#list>
+    }
+    return nil, errors.New("Unsupported type " + typeName)
+}
+</#outputformat>
\ No newline at end of file
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
index e76539c..71234e7 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
@@ -137,4 +137,14 @@ public class StaticHelper {
         throw new NotImplementedException("Serializing STRING not implemented");
     }
 
+    public static String parseS7Char(ReadBuffer io, Object encoding) {
+        // Read the full size of the string.
+        return io.readString(8, (String) encoding);
+    }
+
+    public static void serializeS7Char(WriteBuffer io, PlcValue value, Object encoding) {
+        // TODO: Need to implement the serialization or we can't write strings
+        throw new NotImplementedException("Serializing STRING not implemented");
+    }
+
 }
diff --git a/sandbox/plc4go/cmd/main/drivers/modbus_test.go b/sandbox/plc4go/cmd/main/drivers/modbus_test.go
index 26b0c9a..139e472 100644
--- a/sandbox/plc4go/cmd/main/drivers/modbus_test.go
+++ b/sandbox/plc4go/cmd/main/drivers/modbus_test.go
@@ -36,7 +36,7 @@ import (
 
 func TestModbus(t *testing.T) {
 
-	testutils.NewParserSerializerTestsuite("")
+	testutils.RunParserSerializerTestsuite("")
 
 	test(t, "000000000006ff0408d20002", false)
 	test(t, "7cfe000000c9ff04c600000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000004000000000000000000000000000001db000001d600004a380000000000000000000000000000000000000000000000000000000000006461696d006e0000000000000000000000000000303100300000000000000000000000000000000000000000000000000000000000000000000000000000", true)
diff --git a/sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go b/sandbox/plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go
similarity index 75%
copy from sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go
copy to sandbox/plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go
index 408a230..7594366 100644
--- a/sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go
+++ b/sandbox/plc4go/cmd/main/drivers/tests/modbus_parser_serializer_test.go
@@ -16,21 +16,13 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-package testutils
+package tests
 
 import (
-	"fmt"
-	"log"
-	"os"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/testutils"
+    "testing"
 )
 
-type ParserSerializerTestsuite struct {
-}
-
-func NewParserSerializerTestsuite(testPath string) {
-	dir, err := os.Getwd()
-	if err != nil {
-		log.Fatal(err)
-	}
-	fmt.Println(dir)
-}
+func TestModbusParserSerializer(t *testing.T) {
+    testutils.RunParserSerializerTestsuite(t, "assets/testing/protocols/modbus/ParserSerializerTestsuite.xml")
+}
\ No newline at end of file
diff --git a/sandbox/plc4go/go.mod b/sandbox/plc4go/go.mod
index 12ff77e..99673e6 100644
--- a/sandbox/plc4go/go.mod
+++ b/sandbox/plc4go/go.mod
@@ -23,5 +23,7 @@ go 1.15
 require github.com/sirupsen/logrus v1.7.0
 
 require (
+	github.com/ajankovic/xdiff v0.0.1
 	github.com/icza/bitio v1.0.0
+	github.com/subchen/go-xmldom v1.1.2
 )
diff --git a/sandbox/plc4go/go.sum b/sandbox/plc4go/go.sum
index 0f6ce3d..e7a4d67 100644
--- a/sandbox/plc4go/go.sum
+++ b/sandbox/plc4go/go.sum
@@ -1,7 +1,9 @@
+github.com/ajankovic/xdiff v0.0.1 h1:V1cj8t5xwYzm6ZGPqPOlAc9AIajXuTEn41D/1MJBWMM=
+github.com/ajankovic/xdiff v0.0.1/go.mod h1:SUmEZ67uB97I0zkiuQ+lb+LOms9ipn8X+p+2RdJV710=
+github.com/antchfx/xpath v0.0.0-20170515025933-1f3266e77307 h1:C735MoY/X+UOx6SECmHk5pVOj51h839Ph13pEoY8UmU=
+github.com/antchfx/xpath v0.0.0-20170515025933-1f3266e77307/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259 h1:ZHJ7+IGpuOXtVf6Zk/a3WuHQgkC+vXwaqfUBDFwahtI=
-github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259/go.mod h1:9Qcha0gTWLw//0VNka1Cbnjvg3pNKGFdAm7E9sBabxE=
 github.com/icza/bitio v1.0.0 h1:squ/m1SHyFeCA6+6Gyol1AxV9nmPPlJFT8c2vKdj3U8=
 github.com/icza/bitio v1.0.0/go.mod h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A=
 github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k=
@@ -12,5 +14,7 @@ github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/subchen/go-xmldom v1.1.2 h1:7evI2YqfYYOnuj+PBwyaOZZYjl3iWq35P6KfBUw9jeU=
+github.com/subchen/go-xmldom v1.1.2/go.mod h1:6Pg/HuX5/T4Jlj0IPJF1sRxKVoI/rrKP6LIMge9d5/8=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go
new file mode 100644
index 0000000..930ba37
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/ParserHelper.go
@@ -0,0 +1,78 @@
+//
+// 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 model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+type BacnetipParserHelper struct {
+}
+
+func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io *utils.ReadBuffer) (spi.Message, error) {
+    switch typeName {
+    case "APDU":
+        apduLength, err := utils.StrToUint16(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return APDUParse(io, apduLength)
+    case "BACnetTag":
+        return BACnetTagParse(io)
+    case "BACnetTagWithContent":
+        return BACnetTagWithContentParse(io)
+    case "BACnetError":
+        return BACnetErrorParse(io)
+    case "NLM":
+        apduLength, err := utils.StrToUint16(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return NLMParse(io, apduLength)
+    case "BACnetConfirmedServiceRequest":
+        len, err := utils.StrToUint16(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return BACnetConfirmedServiceRequestParse(io, len)
+    case "BACnetAddress":
+        return BACnetAddressParse(io)
+    case "BACnetConfirmedServiceACK":
+        return BACnetConfirmedServiceACKParse(io)
+    case "BACnetUnconfirmedServiceRequest":
+        len, err := utils.StrToUint16(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return BACnetUnconfirmedServiceRequestParse(io, len)
+    case "BACnetServiceAck":
+        return BACnetServiceAckParse(io)
+    case "BVLC":
+        return BVLCParse(io)
+    case "NPDU":
+        npduLength, err := utils.StrToUint16(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return NPDUParse(io, npduLength)
+    }
+    return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go
new file mode 100644
index 0000000..0743306
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/ParserHelper.go
@@ -0,0 +1,90 @@
+//
+// 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 model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+type KnxnetipParserHelper struct {
+}
+
+func (m KnxnetipParserHelper) Parse(typeName string, arguments []string, io *utils.ReadBuffer) (spi.Message, error) {
+    switch typeName {
+    case "CEMIAdditionalInformation":
+        return CEMIAdditionalInformationParse(io)
+    case "HPAIControlEndpoint":
+        return HPAIControlEndpointParse(io)
+    case "TunnelingResponseDataBlock":
+        return TunnelingResponseDataBlockParse(io)
+    case "ConnectionResponseDataBlock":
+        return ConnectionResponseDataBlockParse(io)
+    case "TunnelingRequestDataBlock":
+        return TunnelingRequestDataBlockParse(io)
+    case "KNXGroupAddress":
+        numLevels, err := utils.StrToUint8(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return KNXGroupAddressParse(io, numLevels)
+    case "DIBDeviceInfo":
+        return DIBDeviceInfoParse(io)
+    case "DeviceConfigurationRequestDataBlock":
+        return DeviceConfigurationRequestDataBlockParse(io)
+    case "DeviceConfigurationAckDataBlock":
+        return DeviceConfigurationAckDataBlockParse(io)
+    case "DIBSuppSvcFamilies":
+        return DIBSuppSvcFamiliesParse(io)
+    case "ConnectionRequestInformation":
+        return ConnectionRequestInformationParse(io)
+    case "HPAIDiscoveryEndpoint":
+        return HPAIDiscoveryEndpointParse(io)
+    case "ProjectInstallationIdentifier":
+        return ProjectInstallationIdentifierParse(io)
+    case "KNXAddress":
+        return KNXAddressParse(io)
+    case "CEMIDataFrame":
+        return CEMIDataFrameParse(io)
+    case "ServiceId":
+        return ServiceIdParse(io)
+    case "KNXNetIPMessage":
+        return KNXNetIPMessageParse(io)
+    case "HPAIDataEndpoint":
+        return HPAIDataEndpointParse(io)
+    case "RelativeTimestamp":
+        return RelativeTimestampParse(io)
+    case "CEMI":
+        size, err := utils.StrToUint8(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return CEMIParse(io, size)
+    case "MACAddress":
+        return MACAddressParse(io)
+    case "CEMIFrame":
+        return CEMIFrameParse(io)
+    case "DeviceStatus":
+        return DeviceStatusParse(io)
+    case "IPAddress":
+        return IPAddressParse(io)
+    }
+    return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go
new file mode 100644
index 0000000..6f94f1f
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ParserHelper.go
@@ -0,0 +1,62 @@
+//
+// 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 model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+type ModbusParserHelper struct {
+}
+
+func (m ModbusParserHelper) Parse(typeName string, arguments []string, io *utils.ReadBuffer) (spi.Message, error) {
+    switch typeName {
+    case "ModbusPDUWriteFileRecordRequestItem":
+        return ModbusPDUWriteFileRecordRequestItemParse(io)
+    case "ModbusPDUReadFileRecordResponseItem":
+        return ModbusPDUReadFileRecordResponseItemParse(io)
+    case "ModbusConstants":
+        return ModbusConstantsParse(io)
+    case "ModbusTcpADU":
+        response, err := utils.StrToBool(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return ModbusTcpADUParse(io, response)
+    case "ModbusPDUWriteFileRecordResponseItem":
+        return ModbusPDUWriteFileRecordResponseItemParse(io)
+    case "ModbusPDU":
+        response, err := utils.StrToBool(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return ModbusPDUParse(io, response)
+    case "ModbusPDUReadFileRecordRequestItem":
+        return ModbusPDUReadFileRecordRequestItemParse(io)
+    case "ModbusSerialADU":
+        response, err := utils.StrToBool(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return ModbusSerialADUParse(io, response)
+    }
+    return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
index c70dd05..8f80b6e 100644
--- a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
@@ -166,6 +166,22 @@ func DataItemParse(io *utils.ReadBuffer, dataProtocolId uint8, stringLength int3
                 return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
             }
             return values.NewPlcLREAL(value), nil
+        case dataProtocolId == 41: // CHAR
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7Char(io, "UTF-8")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcCHAR(value), nil
+        case dataProtocolId == 42: // CHAR
+
+            // Manual Field (value)
+            value, _valueErr := StaticHelperParseS7Char(io, "UTF-16")
+            if _valueErr != nil {
+                return nil, errors.New("Error parsing 'value' field " + _valueErr.Error())
+            }
+            return values.NewPlcCHAR(value), nil
         case dataProtocolId == 43: // STRING
 
             // Manual Field (value)
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go
new file mode 100644
index 0000000..5e51dd9
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/ParserHelper.go
@@ -0,0 +1,87 @@
+//
+// 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 model
+
+import (
+    "errors"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+)
+
+type S7ParserHelper struct {
+}
+
+func (m S7ParserHelper) Parse(typeName string, arguments []string, io *utils.ReadBuffer) (spi.Message, error) {
+    switch typeName {
+    case "SzlId":
+        return SzlIdParse(io)
+    case "S7Message":
+        return S7MessageParse(io)
+    case "S7VarPayloadStatusItem":
+        return S7VarPayloadStatusItemParse(io)
+    case "S7Parameter":
+        messageType, err := utils.StrToUint8(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return S7ParameterParse(io, messageType)
+    case "SzlDataTreeItem":
+        return SzlDataTreeItemParse(io)
+    case "COTPPacket":
+        cotpLen, err := utils.StrToUint16(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return COTPPacketParse(io, cotpLen)
+    case "S7PayloadUserDataItem":
+        cpuFunctionType, err := utils.StrToUint8(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return S7PayloadUserDataItemParse(io, cpuFunctionType)
+    case "COTPParameter":
+        rest, err := utils.StrToUint8(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return COTPParameterParse(io, rest)
+    case "TPKTPacket":
+        return TPKTPacketParse(io)
+    case "S7Payload":
+        messageType, err := utils.StrToUint8(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        var parameter IS7Parameter
+        return S7PayloadParse(io, messageType, parameter)
+    case "S7VarRequestParameterItem":
+        return S7VarRequestParameterItemParse(io)
+    case "S7VarPayloadDataItem":
+        lastItem, err := utils.StrToBool(arguments[0])
+        if err != nil {
+            return nil, err
+        }
+        return S7VarPayloadDataItemParse(io, lastItem)
+    case "S7Address":
+        return S7AddressParse(io)
+    case "S7ParameterUserDataItem":
+        return S7ParameterUserDataItemParse(io)
+    }
+    return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
index 08bb781..64965ce 100644
--- a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7StaticHelper.go
@@ -135,3 +135,7 @@ func StaticHelperParseS7String(io *utils.ReadBuffer, stringLength int32, encodin
     }*/
     return "", nil
 }
+
+func StaticHelperParseS7Char(io *utils.ReadBuffer, encoding string) (uint8, error) {
+    return 0, nil
+}
\ No newline at end of file
diff --git a/sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go b/sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go
index 408a230..20de594 100644
--- a/sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go
+++ b/sandbox/plc4go/internal/plc4go/testutils/ParserSerializerTestRunner.go
@@ -19,18 +19,185 @@
 package testutils
 
 import (
-	"fmt"
-	"log"
+    "encoding/hex"
+    "encoding/xml"
+    "errors"
+    "fmt"
+    "github.com/ajankovic/xdiff"
+    "github.com/ajankovic/xdiff/parser"
+    "github.com/subchen/go-xmldom"
 	"os"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/modbus/readwrite/model"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+    "strconv"
+    "strings"
+    "testing"
 )
 
-type ParserSerializerTestsuite struct {
+func RunParserSerializerTestsuite(t *testing.T, testPath string) {
+    // Get the current working directory
+    path, err := os.Getwd()
+    if err != nil {
+        t.Error(err)
+    }
+
+    // Check if the test-file is available
+    info, err := os.Stat(path + "/../../../../" + testPath)
+    if os.IsNotExist(err) {
+        t.Error("Test-File doesn't exist")
+    }
+    if info.IsDir() {
+        t.Error("Test-File refers to a directory")
+    }
+
+    // Open a reader for this file
+    dat, err := os.Open(path + "/../../../../" + testPath)
+    if err != nil {
+        t.Error("Error opening file")
+    }
+
+    // Read the xml
+    node := xmldom.Must(xmldom.Parse(dat)).Root
+
+    if node.Name != "testsuite" {
+        t.Error("Invalid document structure")
+    }
+    var testsuiteName string
+    for _, childPtr := range node.Children {
+        curFailed := false
+        child := *childPtr
+        if child.Name == "name" {
+            testsuiteName = child.Text
+        } else if child.Name != "testcase" {
+            t.Error("Invalid document structure")
+            curFailed = true
+        } else {
+            t.Logf("running testsuite: %s test: %s", testsuiteName, (*(child.FindOneByName("name"))).Text)
+            rawInputText := (*(child.FindOneByName("raw"))).Text
+            rootType := (*(child.FindOneByName("root-type"))).Text
+            parserArgumentsXml := child.FindOneByName("parser-arguments")
+            var parserArguments []string
+            if parserArgumentsXml != nil {
+                for _, parserArgumentXml := range parserArgumentsXml.Children {
+                    parserArguments = append(parserArguments, parserArgumentXml.Text)
+                }
+            }
+            referenceXml := child.FindOneByName("xml")
+            normalizeXml(referenceXml)
+            referenceSerialized := referenceXml.FirstChild().XML()
+
+            // Get the raw input by decoding the hex-encoded binary input
+            rawInput, err := hex.DecodeString(rawInputText)
+            if err != nil {
+                t.Errorf("Error decoding test input")
+                t.Fail()
+                curFailed = true
+            }
+            readBuffer := utils.ReadBufferNew(rawInput)
+
+            // Parse the input according to the settings of the testcase
+            helper := new(model.ModbusParserHelper)
+            msg, err := helper.Parse(rootType, parserArguments, readBuffer)
+            if err != nil {
+                t.Error("Error parsing input data: " + err.Error())
+                t.Fail()
+                curFailed = true
+            }
+
+            // Serialize the parsed object to XML
+            actualSerialized, err := xml.Marshal(msg)
+            if err != nil {
+                t.Error("Error serializing the actual message: " + err.Error())
+                t.Fail()
+                curFailed = true
+            }
+
+            // Compare the actual and the expected xml
+            err = compareResults(actualSerialized, []byte(referenceSerialized))
+            if err != nil {
+                t.Error("Error comparing the results: " + err.Error())
+                t.Fail()
+                curFailed = true
+            }
+
+            // If all was ok, serialize the object again
+            s, ok := msg.(utils.Serializable)
+            if !ok {
+                t.Error("Couldn't cast message to Serializable")
+                t.Fail()
+                curFailed = true
+            }
+            writeBuffer := utils.WriteBufferNew()
+            err = s.Serialize(*writeBuffer)
+            if !ok {
+                t.Error("Couldn't serialize message back to byte array")
+                t.Fail()
+                curFailed = true
+            }
+
+            // Check if the output matches in size and content
+            rawOutput := writeBuffer.GetBytes()
+            if len(rawInput) != len(rawOutput) {
+                t.Error("Couldn't serialize message back to byte array")
+                t.Fail()
+                curFailed = true
+            }
+            for i, val := range rawInput {
+                if rawOutput[i] != val {
+                    t.Error("Raw output doesn't match input at position: " + strconv.Itoa(i))
+                    t.Fail()
+                    curFailed = true
+                }
+            }
+
+            if curFailed {
+                // All worked
+                t.Logf("FAILED")
+            } else {
+                // All worked
+                t.Logf("SUCCESS")
+            }
+        }
+    }
+    fmt.Printf("name = %v\n", node.Name)
 }
 
-func NewParserSerializerTestsuite(testPath string) {
-	dir, err := os.Getwd()
-	if err != nil {
-		log.Fatal(err)
-	}
-	fmt.Println(dir)
+// Mainly remove linebreaks from text content.
+func normalizeXml(input *xmldom.Node) {
+    if len(input.Children) > 0 {
+        for _, child := range input.Children {
+            normalizeXml(child)
+        }
+    }
+    if len(input.Text) > 0 {
+        if strings.Contains(input.Text, "\n") {
+            input.Text = strings.Replace(input.Text, "\n", "", -1)
+        }
+    }
 }
+
+func compareResults(actualString []byte, referenceString []byte) error {
+    // Now parse the xml strings of the actual and the reference in xdiff's dom
+    p := parser.New()
+    actual, err := p.ParseBytes(actualString)
+    if err != nil {
+        return errors.New("Error parsing actual input: " + err.Error())
+    }
+    reference, err := p.ParseBytes(referenceString)
+    if err != nil {
+        return errors.New("Error parsing reference input: " + err.Error())
+    }
+    // Use XDiff to actually do the comparison
+    diff, err := xdiff.Compare(actual, reference)
+    if err != nil {
+        return errors.New("Error comparing xml trees: " + err.Error())
+    }
+    if diff != nil {
+        enc := xdiff.NewTextEncoder(os.Stdout)
+        if err := enc.Encode(diff); err != nil {
+            return errors.New("Error outputting results: " + err.Error())
+        }
+        return errors.New("there were differences")
+    }
+    return nil
+}
\ No newline at end of file
diff --git a/sandbox/plc4go/internal/plc4go/utils/CastUtils.go b/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
index 01b7006..46c15a0 100644
--- a/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
+++ b/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
@@ -18,6 +18,8 @@
 //
 package utils
 
+import "strconv"
+
 func Int8ToUint8(input []int8) []uint8 {
     output := make([]uint8, len(input))
     for i, _val := range input {
@@ -33,3 +35,27 @@ func Int8ToByte(input []int8) []byte {
     }
     return output
 }
+
+func StrToBool(str string) (bool, error) {
+    boolVal, err := strconv.ParseBool(str)
+    if err != nil {
+        return false, err
+    }
+    return boolVal, nil
+}
+
+func StrToUint8(str string) (uint8, error) {
+    intVal, err := strconv.ParseInt(str, 10, 8)
+    if err != nil {
+        return 0, err
+    }
+    return uint8(intVal), nil
+}
+
+func StrToUint16(str string) (uint16, error) {
+    intVal, err := strconv.ParseInt(str, 10, 16)
+    if err != nil {
+        return 0, err
+    }
+    return uint16(intVal), nil
+}
diff --git a/sandbox/plc4go/go.mod b/sandbox/plc4go/internal/plc4go/utils/ParserHelper.go
similarity index 80%
copy from sandbox/plc4go/go.mod
copy to sandbox/plc4go/internal/plc4go/utils/ParserHelper.go
index 12ff77e..b4b80d2 100644
--- a/sandbox/plc4go/go.mod
+++ b/sandbox/plc4go/internal/plc4go/utils/ParserHelper.go
@@ -16,12 +16,12 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-module plc4x.apache.org/plc4go-modbus-driver/v0
+package utils
 
-go 1.15
+import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
 
-require github.com/sirupsen/logrus v1.7.0
+type ParserHelper interface {
 
-require (
-	github.com/icza/bitio v1.0.0
-)
+    Parse(typeName string, arguments []string, io ReadBuffer) (spi.Message, error)
+
+}
diff --git a/sandbox/plc4go/go.mod b/sandbox/plc4go/internal/plc4go/utils/Serializable.go
similarity index 85%
copy from sandbox/plc4go/go.mod
copy to sandbox/plc4go/internal/plc4go/utils/Serializable.go
index 12ff77e..b73ffe1 100644
--- a/sandbox/plc4go/go.mod
+++ b/sandbox/plc4go/internal/plc4go/utils/Serializable.go
@@ -16,12 +16,8 @@
 // specific language governing permissions and limitations
 // under the License.
 //
-module plc4x.apache.org/plc4go-modbus-driver/v0
+package utils
 
-go 1.15
-
-require github.com/sirupsen/logrus v1.7.0
-
-require (
-	github.com/icza/bitio v1.0.0
-)
+type Serializable interface {
+    Serialize(io WriteBuffer) error
+}


[plc4x] 02/02: - Added the parse-char stuff to plc4c

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit fd80b897b6e9888c664853d05486f5a2a9e8fefe
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Oct 26 16:46:35 2020 +0100

    - Added the parse-char stuff to plc4c
---
 sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h |  2 ++
 sandbox/plc4c/drivers/s7/src/driver_s7.c           |  5 +++++
 sandbox/plc4c/generated-sources/s7/src/data_item.c | 10 ++++++++++
 3 files changed, 17 insertions(+)

diff --git a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
index 715a867..9e12392 100644
--- a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
+++ b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
@@ -73,6 +73,8 @@ plc4c_driver *plc4c_driver_s7_create();
 
 char* plc4c_s7_read_write_parse_s7_string(plc4c_spi_read_buffer* io, int32_t stringLength, char* encoding);
 
+char* plc4c_s7_read_write_parse_s7_char(plc4c_spi_read_buffer* io, char* encoding);
+
 time_t plc4c_s7_read_write_parse_tia_time(plc4c_spi_read_buffer* io);
 
 time_t plc4c_s7_read_write_parse_s5_time(plc4c_spi_read_buffer* io);
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7.c b/sandbox/plc4c/drivers/s7/src/driver_s7.c
index 9f897db..2cfd568 100644
--- a/sandbox/plc4c/drivers/s7/src/driver_s7.c
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7.c
@@ -75,6 +75,11 @@ char* plc4c_s7_read_write_parse_s7_string(plc4c_spi_read_buffer* io, int32_t str
   return "";
 }
 
+char* plc4c_s7_read_write_parse_s7_char(plc4c_spi_read_buffer* io, char* encoding) {
+  // TODO: Implement ...
+  return "";
+}
+
 time_t plc4c_s7_read_write_parse_tia_time(plc4c_spi_read_buffer* io) {
   // TODO: Implement ...
   return 0;
diff --git a/sandbox/plc4c/generated-sources/s7/src/data_item.c b/sandbox/plc4c/generated-sources/s7/src/data_item.c
index 9cfb060..db44784 100644
--- a/sandbox/plc4c/generated-sources/s7/src/data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/data_item.c
@@ -191,6 +191,16 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                 *data_item = plc4c_data_create_double_data(value);
 
         } else 
+        if(dataProtocolId == 41) { /* CHAR */
+
+                    // Manual Field (value)
+                    char* value = (char*) (plc4c_s7_read_write_parse_s7_char(io, "UTF-8"));
+        } else 
+        if(dataProtocolId == 42) { /* CHAR */
+
+                    // Manual Field (value)
+                    char* value = (char*) (plc4c_s7_read_write_parse_s7_char(io, "UTF-16"));
+        } else 
         if(dataProtocolId == 43) { /* STRING */
 
                     // Manual Field (value)