You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2019/06/03 14:54:03 UTC
[plc4x] branch feature/code-gen updated: - Fine-Tuning of the spec
(correcting expressions,
adding missing payload types to match the parameter types) - Added
Array-Access to spec expressions - Made a "curPos" field available to the
Jexl execution,
if required - Fixed some errors in the MessageFormatListener not omitting
the expression ticks - Made the plugin add the generated sources to the
project sources (So they are compiled) - Implemented a first mostly working
version of the ReadBuffer - Added a Test class to experiment wit [...]
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/code-gen by this push:
new fab6cb9 - Fine-Tuning of the spec (correcting expressions, adding missing payload types to match the parameter types) - Added Array-Access to spec expressions - Made a "curPos" field available to the Jexl execution, if required - Fixed some errors in the MessageFormatListener not omitting the expression ticks - Made the plugin add the generated sources to the project sources (So they are compiled) - Implemented a first mostly working version of the ReadBuffer - Added a Test clas [...]
fab6cb9 is described below
commit fab6cb944d47a81af08682d186c6de54046b5be7
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Jun 3 16:53:54 2019 +0200
- Fine-Tuning of the spec (correcting expressions, adding missing payload types to match the parameter types)
- Added Array-Access to spec expressions
- Made a "curPos" field available to the Jexl execution, if required
- Fixed some errors in the MessageFormatListener not omitting the expression ticks
- Made the plugin add the generated sources to the project sources (So they are compiled)
- Implemented a first mostly working version of the ReadBuffer
- Added a Test class to experiment with using the parser
---
.../main/resources/templates/java/io-template.ftlh | 8 +-
.../codegenerator/parser/imaginary/Imaginary.g4 | 1 +
.../plc4x/plugins/codegenerator/GenerateMojo.java | 3 +
.../parser/MessageFormatListener.java | 4 +-
.../src/main/resources/protocols/s7/protocol.spec | 10 +-
.../code-generation/test-java-s7-driver/pom.xml | 12 ++
.../org/apache/plc4x/java/utils/ReadBuffer.java | 155 +++++++++++++++++----
.../org/apache/plc4x/java/utils/WriteBuffer.java | 24 ++++
.../test-java-s7-driver/src/test/java/Test.java | 33 +++++
9 files changed, 213 insertions(+), 37 deletions(-)
diff --git a/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh b/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh
index 08f0364..fb45225 100644
--- a/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh
+++ b/sandbox/code-generation/language-template-java/src/main/resources/templates/java/io-template.ftlh
@@ -55,6 +55,7 @@ public class ${typeName}IO {
private static final Logger LOGGER = LoggerFactory.getLogger(${typeName}IO.class);
public static <#if helper.isDiscriminatedType(type)>${typeName}Builder<#else>${typeName}</#if> parse(ReadBuffer io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForSpecType(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) throws ParseException {
+ int startPos = io.getPos();
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
<#if type.parserArguments?has_content>
@@ -67,7 +68,10 @@ public class ${typeName}IO {
// Array field
JexlExpression ex${field.name} = jexl.createExpression("${field.lengthExpression}");
- int size = (int) ex${field.name}.evaluate(jc);
+ <#if field.lengthExpression?contains("curPos")>
+ jc.set("curPos", io.getPos() - startPos);
+ </#if>
+ int size = Integer.valueOf(ex${field.name}.evaluate(jc).toString());
<#if helper.isCountArray(field)>
${helper.getLanguageTypeNameForSpecType(field.type)}[] ${field.name} = new ${helper.getLanguageTypeNameForSpecType(field.type)}[size];
for(int i = 0; i < size; i++) {
@@ -147,7 +151,7 @@ public class ${typeName}IO {
builder = ${case.name}IO.parse(io<#if type.parserArguments?has_content>, <#list type.parserArguments as parserArgument>${parserArgument.name}<#sep>, </#sep></#list></#if>);
}
</#list>
- else {
+ if (builder == null) {
throw new ParseException("Unsupported case for discriminated type");
}
<#break>
diff --git a/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4 b/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
index 9f84b82..4671814 100644
--- a/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
+++ b/sandbox/code-generation/plc4x-maven-plugin/src/main/antlr4/org/apache/plc4x/codegenerator/parser/imaginary/Imaginary.g4
@@ -107,6 +107,7 @@ innerExpression
| IDENTIFIER // Variable reference
| innerExpression '.' IDENTIFIER // Field Reference
| innerExpression BinaryOperator innerExpression // Addition
+ | innerExpression LBRACKET INTEGER_LITERAL RBRACKET
| '(' innerExpression ')'
| '"' innerExpression '"'
;
diff --git a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/GenerateMojo.java b/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/GenerateMojo.java
index f7a6432..516b789 100644
--- a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/GenerateMojo.java
+++ b/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/GenerateMojo.java
@@ -136,6 +136,9 @@ public class GenerateMojo extends AbstractMojo {
} catch (GenerationException e) {
getLog().error("Error generating sources", e);
}
+
+ // Add the generated sources to the project internally.
+ project.addCompileSourceRoot(outputDir.getPath());
}
}
diff --git a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java b/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
index 9ef5847..be438b5 100644
--- a/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
+++ b/sandbox/code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatListener.java
@@ -95,7 +95,7 @@ public class MessageFormatListener extends ImaginaryBaseListener {
} else {
lengthType = ArrayField.LengthType.LENGTH;
}
- String lengthExpression = ctx.lengthExpression.getText();
+ String lengthExpression = ctx.lengthExpression.expr.getText();
String[] params = getFieldParams((ImaginaryParser.FieldDefinitionContext) ctx.parent.parent);
Field field = new DefaultArrayField(type, name, lengthType, lengthExpression, params);
parserContexts.peek().add(field);
@@ -140,7 +140,7 @@ public class MessageFormatListener extends ImaginaryBaseListener {
public void enterImplicitField(ImaginaryParser.ImplicitFieldContext ctx) {
SimpleTypeReference type = getSimpleTypeReference(ctx.type);
String name = ctx.name.id.getText();
- String serializationExpression = ctx.serializationExpression.getText();
+ String serializationExpression = ctx.serializationExpression.expr.getText();
Field field = new DefaultImplicitField(type, name, serializationExpression);
parserContexts.peek().add(field);
}
diff --git a/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec b/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec
index 8e91b41..a84cdcb 100644
--- a/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec
+++ b/sandbox/code-generation/protocol-s7/src/main/resources/protocols/s7/protocol.spec
@@ -45,7 +45,7 @@
[field uint 8 'rejectCause']
]
]
- [arrayField COTPParameter 'parameters' length '(headerLength + 1) - cur']
+ [arrayField COTPParameter 'parameters' length '(headerLength + 1) - curPos']
[field S7Message 'payload']
]
@@ -101,7 +101,7 @@
[discriminatedType 'S7Parameter' [uint 8 'messageType']
[discriminator uint 8 'parameterType']
[typeSwitch 'parameterType','messageType'
- ['0xF0' SetupCommunication
+ ['0xF0' S7ParameterSetupCommunication
[reserved uint 8 '0x00']
[field uint 16 'maxAmqCaller']
[field uint 16 'maxAmqCallee']
@@ -144,7 +144,7 @@
['0x10' S7AddressAny
[field uint 8 'transportSize']
[field uint 16 'numberOfElements']
- [field uint 8 'dbNumber']
+ [field uint 16 'dbNumber']
[field uint 8 'area']
[reserved uint 5 '0x00']
[field uint 16 'byteAddress']
@@ -173,7 +173,9 @@
// Payloads
[discriminatedType 'S7Payload' [uint 8 'messageType', S7Parameter 'parameter']
- [typeSwitch 'parameter.parameterType', 'messageType'
+ [typeSwitch 'parameter.discriminatorValues[0]', 'messageType'
+ ['0xF0' S7PayloadSetupCommunication]
+ ['0x04','0x01' S7PayloadReadVarRequest]
['0x04','0x03' S7PayloadReadVarResponse
[arrayField S7VarPayloadDataItem 'items' count 'parameter.numItems']
]
diff --git a/sandbox/code-generation/test-java-s7-driver/pom.xml b/sandbox/code-generation/test-java-s7-driver/pom.xml
index 5665884..5933593 100644
--- a/sandbox/code-generation/test-java-s7-driver/pom.xml
+++ b/sandbox/code-generation/test-java-s7-driver/pom.xml
@@ -61,6 +61,18 @@
<artifactId>commons-jexl3</artifactId>
<version>3.1</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>1.18</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.12</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.apache.plc4x.plugins</groupId>
diff --git a/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java b/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java
index 0524629..ff059dc 100644
--- a/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java
+++ b/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java
@@ -19,69 +19,166 @@
package org.apache.plc4x.java.utils;
+import org.apache.commons.compress.utils.BitInputStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.nio.ByteOrder;
public class ReadBuffer {
+ private BitInputStream bis;
+
+
+ public ReadBuffer(byte[] input) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(input);
+ bis = new BitInputStream(bais, ByteOrder.BIG_ENDIAN);
+ }
+
public int getPos() {
- return 0;
+ return (int) bis.getBytesRead();
}
- public boolean readBit() {
- return false;
+ public boolean readBit() throws ParseException {
+ try {
+ return bis.readBits(1) == 1;
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public byte readUnsignedByte(int bitLength) {
- return 0;
+ public byte readUnsignedByte(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("unsigned byte must contain at least 1 bit");
+ }
+ if(bitLength > 4) {
+ throw new ParseException("unsigned byte can only contain max 4 bits");
+ }
+ try {
+ return (byte) bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public short readUnsignedShort(int bitLength) {
- return 0;
+ public short readUnsignedShort(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("unsigned short must contain at least 1 bit");
+ }
+ if(bitLength > 8) {
+ throw new ParseException("unsigned short can only contain max 8 bits");
+ }
+ try {
+ return (short) bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public int readUnsignedInt(int bitLength) {
- return 0;
+ public int readUnsignedInt(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("unsigned int must contain at least 1 bit");
+ }
+ if(bitLength > 16) {
+ throw new ParseException("unsigned int can only contain max 16 bits");
+ }
+ try {
+ return (int) bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public long readUnsignedLong(int bitLength) {
- return 0;
+ public long readUnsignedLong(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("unsigned long must contain at least 1 bit");
+ }
+ if(bitLength > 32) {
+ throw new ParseException("unsigned long can only contain max 32 bits");
+ }
+ try {
+ return bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public BigInteger readUnsignedBigInteger(int bitLength) {
- return BigInteger.ZERO;
+ public BigInteger readUnsignedBigInteger(int bitLength) throws ParseException {
+ throw new UnsupportedOperationException("not implemented yet");
}
- public byte readByte(int bitLength) {
- return 0;
+ public byte readByte(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("byte must contain at least 1 bit");
+ }
+ if(bitLength > 8) {
+ throw new ParseException("byte can only contain max 8 bits");
+ }
+ try {
+ return (byte) bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public short readShort(int bitLength) {
- return 0;
+ public short readShort(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("short must contain at least 1 bit");
+ }
+ if(bitLength > 16) {
+ throw new ParseException("short can only contain max 16 bits");
+ }
+ try {
+ return (short) bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public int readInt(int bitLength) {
- return 0;
+ public int readInt(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("int must contain at least 1 bit");
+ }
+ if(bitLength > 32) {
+ throw new ParseException("int can only contain max 32 bits");
+ }
+ try {
+ return (int) bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public long readLong(int bitLength) {
- return 0;
+ public long readLong(int bitLength) throws ParseException {
+ if(bitLength <= 0) {
+ throw new ParseException("long must contain at least 1 bit");
+ }
+ if(bitLength > 64) {
+ throw new ParseException("long can only contain max 64 bits");
+ }
+ try {
+ return bis.readBits(bitLength);
+ } catch (IOException e) {
+ throw new ParseException("Error reading", e);
+ }
}
- public BigInteger readBigInteger(int bitLength) {
- return BigInteger.ZERO;
+ public BigInteger readBigInteger(int bitLength) throws ParseException {
+ throw new UnsupportedOperationException("not implemented yet");
}
- public float readFloat(int bitLength) {
- return 0.0f;
+ public float readFloat(int bitLength) throws ParseException {
+ throw new UnsupportedOperationException("not implemented yet");
}
- public double readDouble(int bitLength) {
- return 0.0;
+ public double readDouble(int bitLength) throws ParseException {
+ throw new UnsupportedOperationException("not implemented yet");
}
- public BigDecimal readBigDecimal(int bitLength) {
- return BigDecimal.ZERO;
+ public BigDecimal readBigDecimal(int bitLength) throws ParseException {
+ throw new UnsupportedOperationException("not implemented yet");
}
}
diff --git a/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java b/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
index 44aadf7..211239d 100644
--- a/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
+++ b/sandbox/code-generation/test-java-s7-driver/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
@@ -19,11 +19,35 @@
package org.apache.plc4x.java.utils;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
public class WriteBuffer {
+ private int bytePos;
+ private byte bitPos;
+ private ByteArrayOutputStream baos;
+ private DataOutputStream dos;
+
+ public WriteBuffer() {
+ bytePos = 0;
+ bitPos = 0;
+ baos = new ByteArrayOutputStream();
+ dos = new DataOutputStream(baos);
+ }
+
+ public byte[] getMessage() throws ParseException {
+ try {
+ dos.flush();
+ } catch (IOException e) {
+ throw new ParseException("Unable to flush buffer");
+ }
+ return baos.toByteArray();
+ }
+
public void writeBit(boolean value) {
}
diff --git a/sandbox/code-generation/test-java-s7-driver/src/test/java/Test.java b/sandbox/code-generation/test-java-s7-driver/src/test/java/Test.java
new file mode 100644
index 0000000..28598d5
--- /dev/null
+++ b/sandbox/code-generation/test-java-s7-driver/src/test/java/Test.java
@@ -0,0 +1,33 @@
+/*
+ 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.
+ */
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.plc4x.java.s7.TPKTPacket;
+import org.apache.plc4x.java.s7.io.TPKTPacketIO;
+import org.apache.plc4x.java.utils.ReadBuffer;
+
+public class Test {
+
+ public static void main(String[] args) throws Exception {
+ byte[] data = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
+ ReadBuffer buf = new ReadBuffer(data);
+ TPKTPacket packet = TPKTPacketIO.parse(buf);
+ }
+
+}