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:43 UTC
[plc4x] 01/02: - Continued working on the serializer/parser
testsuite for go
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
+}