TBEL Utils and tests
This commit is contained in:
parent
046d313581
commit
acfd8afa0c
@ -24,6 +24,8 @@ import java.io.IOException;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -65,12 +67,24 @@ public class TbUtils {
|
|||||||
String.class)));
|
String.class)));
|
||||||
parserConfig.addImport("parseHexToInt", new MethodStub(TbUtils.class.getMethod("parseHexToInt",
|
parserConfig.addImport("parseHexToInt", new MethodStub(TbUtils.class.getMethod("parseHexToInt",
|
||||||
String.class, boolean.class)));
|
String.class, boolean.class)));
|
||||||
|
parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt",
|
||||||
|
List.class, int.class, int.class)));
|
||||||
|
parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt",
|
||||||
|
List.class, int.class, int.class, boolean.class)));
|
||||||
|
parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt",
|
||||||
|
byte[].class, int.class, int.class)));
|
||||||
|
parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt",
|
||||||
|
byte[].class, int.class, int.class, boolean.class)));
|
||||||
parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed",
|
parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed",
|
||||||
double.class, int.class)));
|
double.class, int.class)));
|
||||||
parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes",
|
parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes",
|
||||||
ExecutionContext.class, String.class)));
|
ExecutionContext.class, String.class)));
|
||||||
parserConfig.addImport("base64ToHex", new MethodStub(TbUtils.class.getMethod("base64ToHex",
|
parserConfig.addImport("base64ToHex", new MethodStub(TbUtils.class.getMethod("base64ToHex",
|
||||||
String.class)));
|
String.class)));
|
||||||
|
parserConfig.addImport("base64ToBytes", new MethodStub(TbUtils.class.getMethod("base64ToBytes",
|
||||||
|
String.class)));
|
||||||
|
parserConfig.addImport("bytesToBase64", new MethodStub(TbUtils.class.getMethod("bytesToBase64",
|
||||||
|
byte[].class)));
|
||||||
parserConfig.addImport("bytesToHex", new MethodStub(TbUtils.class.getMethod("bytesToHex",
|
parserConfig.addImport("bytesToHex", new MethodStub(TbUtils.class.getMethod("bytesToHex",
|
||||||
byte[].class)));
|
byte[].class)));
|
||||||
parserConfig.addImport("bytesToHex", new MethodStub(TbUtils.class.getMethod("bytesToHex",
|
parserConfig.addImport("bytesToHex", new MethodStub(TbUtils.class.getMethod("bytesToHex",
|
||||||
@ -119,8 +133,8 @@ public class TbUtils {
|
|||||||
|
|
||||||
private static List<Byte> bytesToList(ExecutionContext ctx, byte[] bytes) {
|
private static List<Byte> bytesToList(ExecutionContext ctx, byte[] bytes) {
|
||||||
List<Byte> list = new ExecutionArrayList<>(ctx);
|
List<Byte> list = new ExecutionArrayList<>(ctx);
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (byte aByte : bytes) {
|
||||||
list.add(bytes[i]);
|
list.add(aByte);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -194,14 +208,14 @@ public class TbUtils {
|
|||||||
if (length > 8) {
|
if (length > 8) {
|
||||||
throw new IllegalArgumentException("Hex string is too large. Maximum 8 symbols allowed.");
|
throw new IllegalArgumentException("Hex string is too large. Maximum 8 symbols allowed.");
|
||||||
}
|
}
|
||||||
if (bigEndian) {
|
if (length % 2 > 0) {
|
||||||
return Integer.parseInt(hex, 16);
|
throw new IllegalArgumentException("Hex string must be even-length.");
|
||||||
} else {
|
|
||||||
if (length < 8) {
|
|
||||||
hex = hex + "0".repeat(8 - length);
|
|
||||||
}
|
|
||||||
return Integer.reverseBytes(Integer.parseInt(hex, 16));
|
|
||||||
}
|
}
|
||||||
|
byte[] data = new byte[length / 2];
|
||||||
|
for (int i = 0; i < length; i += 2) {
|
||||||
|
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
|
||||||
|
}
|
||||||
|
return parseBytesToInt(data, 0, data.length, bigEndian);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExecutionArrayList<Integer> hexToBytes(ExecutionContext ctx, String hex) {
|
public static ExecutionArrayList<Integer> hexToBytes(ExecutionContext ctx, String hex) {
|
||||||
@ -212,7 +226,7 @@ public class TbUtils {
|
|||||||
ExecutionArrayList<Integer> data = new ExecutionArrayList<>(ctx);
|
ExecutionArrayList<Integer> data = new ExecutionArrayList<>(ctx);
|
||||||
for (int i = 0; i < len; i += 2) {
|
for (int i = 0; i < len; i += 2) {
|
||||||
data.add((Character.digit(hex.charAt(i), 16) << 4)
|
data.add((Character.digit(hex.charAt(i), 16) << 4)
|
||||||
+ Character.digit(hex.charAt(i+1), 16));
|
+ Character.digit(hex.charAt(i + 1), 16));
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -221,6 +235,50 @@ public class TbUtils {
|
|||||||
return bytesToHex(Base64.getDecoder().decode(base64));
|
return bytesToHex(Base64.getDecoder().decode(base64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String bytesToBase64(byte[] bytes) {
|
||||||
|
return Base64.getEncoder().encodeToString(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] base64ToBytes(String input) {
|
||||||
|
return Base64.getDecoder().decode(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int parseBytesToInt(List<Byte> data, int offset, int length) {
|
||||||
|
return parseBytesToInt(data, offset, length, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int parseBytesToInt(List<Byte> data, int offset, int length, boolean bigEndian) {
|
||||||
|
final byte[] bytes = new byte[data.size()];
|
||||||
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
bytes[i] = data.get(i);
|
||||||
|
}
|
||||||
|
return parseBytesToInt(bytes, offset, length, bigEndian);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int parseBytesToInt(byte[] data, int offset, int length) {
|
||||||
|
return parseBytesToInt(data, offset, length, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int parseBytesToInt(byte[] data, int offset, int length, boolean bigEndian) {
|
||||||
|
if (offset > data.length) {
|
||||||
|
throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!");
|
||||||
|
}
|
||||||
|
if (length > 4) {
|
||||||
|
throw new IllegalArgumentException("Length: " + length + " is too large. Maximum 4 bytes is allowed!");
|
||||||
|
}
|
||||||
|
if (offset + length > data.length) {
|
||||||
|
throw new IllegalArgumentException("Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!");
|
||||||
|
}
|
||||||
|
var bb = ByteBuffer.allocate(4);
|
||||||
|
if (!bigEndian) {
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
bb.position(bigEndian ? 4 - length : 0);
|
||||||
|
bb.put(data, offset, length);
|
||||||
|
bb.position(0);
|
||||||
|
return bb.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
public static String bytesToHex(ExecutionArrayList<?> bytesList) {
|
public static String bytesToHex(ExecutionArrayList<?> bytesList) {
|
||||||
byte[] bytes = new byte[bytesList.size()];
|
byte[] bytes = new byte[bytesList.size()];
|
||||||
for (int i = 0; i < bytesList.size(); i++) {
|
for (int i = 0; i < bytesList.size(); i++) {
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2022 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed 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.thingsboard.script.api.tbel;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TbUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseHexToInt() {
|
||||||
|
Assert.assertEquals(0xAB, TbUtils.parseHexToInt("AB"));
|
||||||
|
Assert.assertEquals(0xABBA, TbUtils.parseHexToInt("ABBA", true));
|
||||||
|
Assert.assertEquals(0xBAAB, TbUtils.parseHexToInt("ABBA", false));
|
||||||
|
Assert.assertEquals(0xAABBCC, TbUtils.parseHexToInt("AABBCC", true));
|
||||||
|
Assert.assertEquals(0xAABBCC, TbUtils.parseHexToInt("CCBBAA", false));
|
||||||
|
Assert.assertEquals(0xAABBCCDD, TbUtils.parseHexToInt("AABBCCDD", true));
|
||||||
|
Assert.assertEquals(0xAABBCCDD, TbUtils.parseHexToInt("DDCCBBAA", false));
|
||||||
|
Assert.assertEquals(0xDDCCBBAA, TbUtils.parseHexToInt("DDCCBBAA", true));
|
||||||
|
Assert.assertEquals(0xDDCCBBAA, TbUtils.parseHexToInt("AABBCCDD", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseBytesToInt_checkPrimitives() {
|
||||||
|
int expected = 257;
|
||||||
|
byte[] data = ByteBuffer.allocate(4).putInt(expected).array();
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4));
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 2, 2, true));
|
||||||
|
Assert.assertEquals(1, TbUtils.parseBytesToInt(data, 3, 1, true));
|
||||||
|
|
||||||
|
expected = Integer.MAX_VALUE;
|
||||||
|
data = ByteBuffer.allocate(4).putInt(expected).array();
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4, true));
|
||||||
|
|
||||||
|
expected = 0xAABBCCDD;
|
||||||
|
data = new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD};
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4, true));
|
||||||
|
data = new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xBB, (byte) 0xAA};
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4, false));
|
||||||
|
|
||||||
|
expected = 0xAABBCC;
|
||||||
|
data = new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC};
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 3, true));
|
||||||
|
data = new byte[]{(byte) 0xCC, (byte) 0xBB, (byte) 0xAA};
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 3, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseBytesToInt_checkLists() {
|
||||||
|
int expected = 257;
|
||||||
|
List<Byte> data = toList(ByteBuffer.allocate(4).putInt(expected).array());
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4));
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 2, 2, true));
|
||||||
|
Assert.assertEquals(1, TbUtils.parseBytesToInt(data, 3, 1, true));
|
||||||
|
|
||||||
|
expected = Integer.MAX_VALUE;
|
||||||
|
data = toList(ByteBuffer.allocate(4).putInt(expected).array());
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4, true));
|
||||||
|
|
||||||
|
expected = 0xAABBCCDD;
|
||||||
|
data = toList(new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD});
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4, true));
|
||||||
|
data = toList(new byte[]{(byte) 0xDD, (byte) 0xCC, (byte) 0xBB, (byte) 0xAA});
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 4, false));
|
||||||
|
|
||||||
|
expected = 0xAABBCC;
|
||||||
|
data = toList(new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC});
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 3, true));
|
||||||
|
data = toList(new byte[]{(byte) 0xCC, (byte) 0xBB, (byte) 0xAA});
|
||||||
|
Assert.assertEquals(expected, TbUtils.parseBytesToInt(data, 0, 3, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Byte> toList(byte[] data) {
|
||||||
|
List<Byte> result = new ArrayList<>(data.length);
|
||||||
|
for (Byte b : data) {
|
||||||
|
result.add(b);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user