You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2018/02/22 18:07:45 UTC
[incubator-plc4x] 01/02: extracted encoder decoder methods to
utility classes
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
commit 03b3c219ca4b59709f6e07b530761b652c77e3b1
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Feb 22 16:08:39 2018 +0100
extracted encoder decoder methods to utility classes
---
.../plc4x/java/s7/netty/Plc4XS7Protocol.java | 146 +--------------------
.../plc4x/java/s7/netty/util/BigEndianDecoder.java | 74 +++++++++++
.../plc4x/java/s7/netty/util/BigEndianEncoder.java | 128 ++++++++++++++++++
3 files changed, 205 insertions(+), 143 deletions(-)
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
index 24f269b..2acc90a 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
@@ -49,6 +49,9 @@ import org.apache.plc4x.java.s7.netty.model.types.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
+import static org.apache.plc4x.java.s7.netty.util.BigEndianDecoder.decodeData;
+import static org.apache.plc4x.java.s7.netty.util.BigEndianEncoder.encodeData;
+
public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequestContainer> {
private static final AtomicInteger tpduGenerator = new AtomicInteger(1);
@@ -323,106 +326,6 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
return null;
}
- private byte[] encodeData(Object[] values) {
- final int length = values.length;
- if (length == 0) {
- return new byte[]{};
- }
- byte[] result = null;
- Class valueType = values[0].getClass();
- if (valueType == Boolean.class) {
- result = encodeBoolean(values, length);
- } else if (valueType == Byte.class) {
- result = encodeByte(values, length);
- } else if (valueType == Short.class) {
- result = encodeShort(values, length);
- } else if (valueType == Integer.class) {
- result = encodeInteger(values, length);
- } else if (valueType == Calendar.class) {
- // TODO: Decide what to do here ...
- result = null;
- } else if (valueType == Float.class) {
- result = encodeFloat(values, length);
- } else if (valueType == String.class) {
- result = encodeString(values, length);
- }
- return result;
- }
-
- private byte[] encodeString(Object[] values, int length) {
- byte[] result;
- int size = 0;
- for (Object value : values) {
- size = size + ((String) value).length();
- }
- result = new byte[size + length];
- int j = 0;
- for (Object value : values) {
- String str = (String) value;
- for (int i = 0; i < str.length(); i++) {
- result[j++] = (byte) str.charAt(i);
- }
- result[j++] = (byte) 0x0;
- }
- return result;
- }
-
- private byte[] encodeFloat(Object[] values, int length) {
- byte[] result;
- result = new byte[length * 4];
- for (int i = 0; i < length; i++) {
- float floatValue = (float) values[i];
- int intValue = Float.floatToIntBits(floatValue);
- result[i * 4] = (byte) ((intValue & 0xff000000) >> 24);
- result[(i * 4) + 1] = (byte) ((intValue & 0x00ff0000) >> 16);
- result[(i * 4) + 2] = (byte) ((intValue & 0x0000ff00) >> 8);
- result[(i * 4) + 3] = (byte) (intValue & 0xff);
- }
- return result;
- }
-
- private byte[] encodeInteger(Object[] values, int length) {
- byte[] result;
- result = new byte[length * 4];
- for (int i = 0; i < length; i++) {
- int intValue = (int) values[i];
- result[i * 4] = (byte) ((intValue & 0xff000000) >> 24);
- result[(i * 4) + 1] = (byte) ((intValue & 0x00ff0000) >> 16);
- result[(i * 4) + 2] = (byte) ((intValue & 0x0000ff00) >> 8);
- result[(i * 4) + 3] = (byte) (intValue & 0xff);
- }
- return result;
- }
-
- private byte[] encodeShort(Object[] values, int length) {
- byte[] result;
- result = new byte[length * 2];
- for (int i = 0; i < length; i++) {
- short intValue = (short) values[i];
- result[i * 2] = (byte) ((intValue & 0xff00) >> 8);
- result[(i * 2) + 1] = (byte) (intValue & 0xff);
- }
- return result;
- }
-
- private byte[] encodeByte(Object[] values, int length) {
- byte[] result;
- result = new byte[length];
- for (int i = 0; i < length; i++) {
- result[i] = (byte) values[i];
- }
- return result;
- }
-
- private byte[] encodeBoolean(Object[] values, int length) {
- byte[] result;// TODO: Check if this is true and the result is not Math.ceil(values.lenght / 8)
- result = new byte[length];
- for (int i = 0; i < length; i++) {
- result[i] = (byte) (((Boolean) values[i]) ? 0x01 : 0x00);
- }
- return result;
- }
-
////////////////////////////////////////////////////////////////////////////////
// Decoding helpers.
////////////////////////////////////////////////////////////////////////////////
@@ -443,47 +346,4 @@ public class Plc4XS7Protocol extends MessageToMessageCodec<S7Message, PlcRequest
}
}
- @SuppressWarnings("unchecked")
- private <T> List<T> decodeData(Class<T> datatype, byte[] s7Data) throws PlcProtocolException {
-
- List<Object> result = new LinkedList<>();
- int i = 0;
- final int length = s7Data.length;
- while (i < length) {
- if (datatype == Boolean.class) {
- result.add((s7Data[i] & 0x01) == 0x01);
- i += 1;
- } else if (datatype == Byte.class) {
- result.add(s7Data[i]);
- i += 1;
- } else if (datatype == Short.class) {
- result.add((short) (((s7Data[i] & 0xff) << 8) | (s7Data[i + 1] & 0xff)));
- i += 2;
- } else if (datatype == Integer.class) {
- result.add(((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) |
- ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff));
- i += 4;
- } else if (datatype == Float.class) {
- // Description of the Real number format:
- // https://www.sps-lehrgang.de/zahlenformate-step7/#c144
- // https://de.wikipedia.org/wiki/IEEE_754
- int intValue = ((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) |
- ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff);
- result.add(Float.intBitsToFloat(intValue));
- i += 4;
- } else if (datatype == String.class) {
- StringBuilder builder = new StringBuilder();
- while (s7Data[i] != (byte) 0x0 && i < length) {
- builder.append((char) s7Data[i]);
- i++;
- }
- i++; // skip terminating character
- result.add(builder.toString());
- } else {
- throw new PlcProtocolException("Unsupported datatype " + datatype.getSimpleName());
- }
- }
- return (List<T>) result;
- }
-
}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/BigEndianDecoder.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/BigEndianDecoder.java
new file mode 100644
index 0000000..6e22bcd
--- /dev/null
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/BigEndianDecoder.java
@@ -0,0 +1,74 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.plc4x.java.s7.netty.util;
+
+import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class BigEndianDecoder {
+
+ private BigEndianDecoder() {
+ // Utility class
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> List<T> decodeData(Class<T> datatype, byte[] s7Data) throws PlcProtocolException {
+
+ List<Object> result = new LinkedList<>();
+ int i = 0;
+ final int length = s7Data.length;
+ while (i < length) {
+ if (datatype == Boolean.class) {
+ result.add((s7Data[i] & 0x01) == 0x01);
+ i += 1;
+ } else if (datatype == Byte.class) {
+ result.add(s7Data[i]);
+ i += 1;
+ } else if (datatype == Short.class) {
+ result.add((short) (((s7Data[i] & 0xff) << 8) | (s7Data[i + 1] & 0xff)));
+ i += 2;
+ } else if (datatype == Integer.class) {
+ result.add(((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) |
+ ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff));
+ i += 4;
+ } else if (datatype == Float.class) {
+ // Description of the Real number format:
+ // https://www.sps-lehrgang.de/zahlenformate-step7/#c144
+ // https://de.wikipedia.org/wiki/IEEE_754
+ int intValue = ((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) |
+ ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff);
+ result.add(Float.intBitsToFloat(intValue));
+ i += 4;
+ } else if (datatype == String.class) {
+ StringBuilder builder = new StringBuilder();
+ while (s7Data[i] != (byte) 0x0 && i < length) {
+ builder.append((char) s7Data[i]);
+ i++;
+ }
+ i++; // skip terminating character
+ result.add(builder.toString());
+ } else {
+ throw new PlcProtocolException("Unsupported datatype " + datatype.getSimpleName());
+ }
+ }
+ return (List<T>) result;
+ }
+}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/BigEndianEncoder.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/BigEndianEncoder.java
new file mode 100644
index 0000000..f9d1159
--- /dev/null
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/BigEndianEncoder.java
@@ -0,0 +1,128 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.plc4x.java.s7.netty.util;
+
+import java.util.Calendar;
+
+public class BigEndianEncoder {
+
+ private BigEndianEncoder() {
+ // Utility class
+ }
+
+ public static byte[] encodeData(Object[] values) {
+ final int length = values.length;
+ if (length == 0) {
+ return new byte[]{};
+ }
+ byte[] result = null;
+ Class valueType = values[0].getClass();
+ if (valueType == Boolean.class) {
+ result = encodeBoolean(values, length);
+ } else if (valueType == Byte.class) {
+ result = encodeByte(values, length);
+ } else if (valueType == Short.class) {
+ result = encodeShort(values, length);
+ } else if (valueType == Integer.class) {
+ result = encodeInteger(values, length);
+ } else if (valueType == Calendar.class) {
+ // TODO: Decide what to do here ...
+ result = null;
+ } else if (valueType == Float.class) {
+ result = encodeFloat(values, length);
+ } else if (valueType == String.class) {
+ result = encodeString(values, length);
+ }
+ return result;
+ }
+
+ public static byte[] encodeString(Object[] values, int length) {
+ byte[] result;
+ int size = 0;
+ for (Object value : values) {
+ size = size + ((String) value).length();
+ }
+ result = new byte[size + length];
+ int j = 0;
+ for (Object value : values) {
+ String str = (String) value;
+ for (int i = 0; i < str.length(); i++) {
+ result[j++] = (byte) str.charAt(i);
+ }
+ result[j++] = (byte) 0x0;
+ }
+ return result;
+ }
+
+ public static byte[] encodeFloat(Object[] values, int length) {
+ byte[] result;
+ result = new byte[length * 4];
+ for (int i = 0; i < length; i++) {
+ float floatValue = (float) values[i];
+ int intValue = Float.floatToIntBits(floatValue);
+ result[i * 4] = (byte) ((intValue & 0xff000000) >> 24);
+ result[(i * 4) + 1] = (byte) ((intValue & 0x00ff0000) >> 16);
+ result[(i * 4) + 2] = (byte) ((intValue & 0x0000ff00) >> 8);
+ result[(i * 4) + 3] = (byte) (intValue & 0xff);
+ }
+ return result;
+ }
+
+ public static byte[] encodeInteger(Object[] values, int length) {
+ byte[] result;
+ result = new byte[length * 4];
+ for (int i = 0; i < length; i++) {
+ int intValue = (int) values[i];
+ result[i * 4] = (byte) ((intValue & 0xff000000) >> 24);
+ result[(i * 4) + 1] = (byte) ((intValue & 0x00ff0000) >> 16);
+ result[(i * 4) + 2] = (byte) ((intValue & 0x0000ff00) >> 8);
+ result[(i * 4) + 3] = (byte) (intValue & 0xff);
+ }
+ return result;
+ }
+
+ public static byte[] encodeShort(Object[] values, int length) {
+ byte[] result;
+ result = new byte[length * 2];
+ for (int i = 0; i < length; i++) {
+ short intValue = (short) values[i];
+ result[i * 2] = (byte) ((intValue & 0xff00) >> 8);
+ result[(i * 2) + 1] = (byte) (intValue & 0xff);
+ }
+ return result;
+ }
+
+ public static byte[] encodeByte(Object[] values, int length) {
+ byte[] result;
+ result = new byte[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = (byte) values[i];
+ }
+ return result;
+ }
+
+ public static byte[] encodeBoolean(Object[] values, int length) {
+ byte[] result;// TODO: Check if this is true and the result is not Math.ceil(values.lenght / 8)
+ result = new byte[length];
+ for (int i = 0; i < length; i++) {
+ result[i] = (byte) (((Boolean) values[i]) ? 0x01 : 0x00);
+ }
+ return result;
+ }
+}
--
To stop receiving notification emails like this one, please contact
sruehl@apache.org.