From 13e8005d15a12d34835a954022ce0e5a169aff78 Mon Sep 17 00:00:00 2001
From: pang.jiabao <pang_jiabao@163.com>
Date: 星期六, 10 五月 2025 09:21:21 +0800
Subject: [PATCH] wcs监控界面显示内容调整
---
src/main/java/com/zy/common/utils/Struct.java | 896 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 456 insertions(+), 440 deletions(-)
diff --git a/src/main/java/com/zy/common/utils/Struct.java b/src/main/java/com/zy/common/utils/Struct.java
index 29baf5c..b505108 100644
--- a/src/main/java/com/zy/common/utils/Struct.java
+++ b/src/main/java/com/zy/common/utils/Struct.java
@@ -16,476 +16,492 @@
import java.nio.charset.StandardCharsets;
import java.util.*;
+/**
+ * Tcp鍗忚鎶ユ枃鍩虹被
+ * @author vincent
+ */
public class Struct implements java.io.Serializable {
-
- private transient Map<String,byte[]> decodeByteMapping = new HashMap<>();
- private transient Map<String,byte[]> encodeByteMapping = new HashMap<>();
- private transient byte[] dataBytes = null;
- private transient byte[] decodeBytes = null;
- private transient byte[] encodeBytes = null;
- private transient byte[] unusedBytes = null;
- public Class getClassType(String name){
- return null;
- }
-
- public boolean isReverse() {
- return this.getClass().getAnnotation(little.class)!=null;
- }
-
- public byte[] toBytes() throws Exception {
- return encode(this);
- }
-
- public Map<String,String> toDecodeHexMapping() throws Exception{
- if(this.decodeByteMapping==null)this.decodeByteMapping=new HashMap<>();
- Map<String, String> mapping = getHex(this.decodeByteMapping);
- if(this.decodeBytes!=null){
- mapping.put("byte[]", Struct.toHex(this.decodeBytes));
- }
- return mapping;
- }
- public Map<String,String> toEncodeHexMapping() throws Exception{
- if(this.encodeBytes==null)this.encode(this);
- if(this.encodeByteMapping==null)this.encodeByteMapping=new HashMap<>();
- Map<String, String> mapping = getHex(this.encodeByteMapping);
- mapping.put("byte[]", Struct.toHex(this.encodeBytes));
- return mapping;
- }
- public Map<String,String> getHex(Map<String,byte[]> bytemapping) throws Exception {
- Map<String,String> map = new LinkedHashMap<>();
- Field[] fields = this.getClass().getFields();
- for (Field field : fields) {
- byte[] bytes = bytemapping.get(field.getName());
- if(bytes!=null){
- map.put(field.getName(), Struct.toHex(bytes));
- }
- }
- return map;
- }
-
- // 杞琷ava瀵硅薄鍒版暟缁�
- public byte[] encode(Struct entity) throws Exception {
- ByteArrayOutputStream baOs = new ByteArrayOutputStream();
- write(new DataOutputStream(baOs), entity);
- entity.encodeBytes = baOs.toByteArray();
- return entity.encodeBytes;
- }
+ private transient Map<String, byte[]> decodeByteMapping = new HashMap<>();
+ private transient Map<String, byte[]> encodeByteMapping = new HashMap<>();
+ // 瑙g爜鍓嶇殑鍘熺敓瀛楄妭鏁扮粍
+ private transient byte[] dataBytes = null;
+ private transient byte[] decodeBytes = null;
+ private transient byte[] encodeBytes = null;
+ private transient byte[] unusedBytes = null;
- /**
- * 鍐欐暟鎹埌杈撳嚭娴�
- *
- * @param dos
- * @param entity
- * @throws Exception
- */
- public void write(DataOutputStream dos, Struct entity) throws Exception {
- if(entity==null)return;
- if(entity.encodeByteMapping==null)entity.encodeByteMapping=new HashMap<>();
- Field[] fields = entity.getClass().getFields();
- EvaluationContext context = new StandardEvaluationContext();
- for (Field field : Objects.requireNonNull(ReflectUtils.removeStaticField(fields))) {
- field.setAccessible(true);
-
- String name = field.getName();
- Class<?> type = field.getType();
- String typeName = type.getSimpleName();
- if(typeName.equals("Struct")){
- if(entity.getClassType(name)!=null){
- type = entity.getClassType(name);
- typeName = type.getSimpleName();
- }else if(field.get(entity)!=null){
- type = field.get(entity).getClass();
- typeName = type.getSimpleName();
- }
- }
-
- size size = field.getAnnotation(size.class);
- bit bit = field.getAnnotation(bit.class);
- expr expr = field.getAnnotation(expr.class);
- flag flag = field.getAnnotation(flag.class);
- if(size==null && bit==null && expr==null){
- continue;
- }
-
- int bited = 0;//宸插啓浣嶆暟
- int length = 0;//瀹氫箟鐨勯暱搴�
- if(size!=null){
- length = size.value();
- bited+=size.value()*8;
- }else if(bit!=null){
- //鎸変綅鍐欐柟寮忔湭瀹炵幇澶勭悊
- throw new RuntimeException("鎸変綅鍐欐柟寮忔湭瀹炵幇澶勭悊");
- }else if(expr!=null){
- ExpressionParser parser = new SpelExpressionParser();
- Expression exp = parser.parseExpression(expr.value());
- Integer len = null;
- try{
- len = CommonUtils.parseInt(exp.getValue(context, entity));
- }catch (Exception e){
- len = 0;
- }
- if(len!=null){
- if(len==-1)continue;
- length = len;
- bited+=len*8;
- }
- }
- context.setVariable(name, field.get(entity));
-
- byte[] bytes = new byte[length];
-
- if (typeName.equals("int") || typeName.equals("Integer")){
- dos.write(bytes=convert(length,field.getInt(entity)));
- }else if (typeName.equals("long") || typeName.equals("Long")){
- dos.write(bytes=convert(length,field.getLong(entity)));
- }else if (typeName.equals("short") || typeName.equals("Short")){
- dos.write(bytes=convert(length,field.getShort(entity)));
- }else if (typeName.equals("byte") || typeName.equals("Byte")){
- dos.write(bytes=convert(length,field.getByte(entity)));
- }else if (typeName.equals("String")) {
- String str = (String) field.get(entity);
- if (str == null)
- str = "";
- str = str.replaceAll("銆�", " ");
-
- byte[] bts = null;
- if(flag!=null && flag.value().equals("ASCII")){
- bts = Struct.StrToAsc(str);
- }else if(flag!=null && flag.value().equals("BCD")){
- bts = Struct.str2Bcd(str);
- }else{
- bts = str.getBytes();
- }
-
- if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
- bytes = new byte[bts.length];
- }
- System.arraycopy(bts, 0, bytes, 0, bts.length);
- dos.write(bytes);
- } else if (typeName.equals("byte[]")) {
- byte[] bts = (byte[]) field.get(entity);
- if(bts!=null){
- if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
- bytes = new byte[bts.length];
- }
- System.arraycopy(bts, 0, bytes, 0, bts.length);
- dos.write(bytes);
- }
- }else if (type.isArray()) {
- ByteArrayOutputStream baOs1 = new ByteArrayOutputStream();
- DataOutputStream dos1 = new DataOutputStream(baOs1);
- for (Object object : (Object[]) field.get(entity)){
- write(dos1, (Struct) object);
- }
- byte[] bts = baOs1.toByteArray();
- if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
- bytes = new byte[bts.length];
- }
- System.arraycopy(bts, 0, bytes, 0, bts.length);
- dos.write(bytes);
- } else {
- byte[] bts = encode((Struct) field.get(entity));
- if(length==0){//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
- bytes = new byte[bts.length];
- }
- System.arraycopy(bts, 0, bytes, 0, bts.length);
- dos.write(bytes);
- }
- entity.encodeByteMapping.put(name, bytes);
- }
- }
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public static <T extends Struct> T decode(Class<? extends Struct> cls, byte[] bytes) throws Exception {
+ Struct instance = cls.newInstance();
+ return instance.decode(bytes);
+ }
-
- public byte[] convert(int size, long value) throws Exception{
- ByteArrayOutputStream baOs = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baOs);
- switch(size){
- case 1://byte
- dos.write((byte) value);
- break;
- case 2://short
- dos.writeShort(this.isReverse() ? Short.reverseBytes((short)value) : (short)value);
- break;
- case 4://int
- dos.writeInt(this.isReverse() ? Integer.reverseBytes((int)value) : (int)value);
- break;
- case 8://long
- dos.writeLong(this.isReverse() ? Long.reverseBytes((long)value) : (long)value);
- break;
- }
- return baOs.toByteArray();
- }
-
- public long convertEx(long value,int size) throws Exception{
- switch(size){
- case 1://byte
- return value;
- case 2://short
- return (this.isReverse() ? Short.reverseBytes((short)value) : (short)value);
- case 4://int
- return (this.isReverse() ? Integer.reverseBytes((int)value) : (int)value);
- case 8://long
- return (this.isReverse() ? Long.reverseBytes((long)value) : (long)value);
- }
- return 0;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <T extends Struct> T decode(Class<? extends Struct> cls,byte[] bytes) throws Exception{
- Struct instance = cls.newInstance();
- return instance.decode(bytes);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <T extends Struct> T decode(byte[] bytes) throws Exception{
- this.dataBytes = bytes;
- Struct instance = this;
- Class<? extends Struct> cls = this.getClass();
- Field[] fields = cls.getFields();
- if(this.decodeByteMapping==null)instance.decodeByteMapping=new HashMap();
- EvaluationContext context = new StandardEvaluationContext();
- context.setVariable("_", bytes.length);
- int bited = 0;//宸茶浣嶆暟
- for(Field field: Objects.requireNonNull(ReflectUtils.removeStaticField(fields))){
- size size = field.getAnnotation(size.class);
- bit bit = field.getAnnotation(bit.class);
- expr expr = field.getAnnotation(expr.class);
- flag flag = field.getAnnotation(flag.class);
- if(size==null && bit==null && expr==null){
- continue;
- //throw new RuntimeException(cls.getSimpleName()+"瀛楁"+field.getName()+"鏈爣璁癅size|@bit|@expr");
- }
- String name = field.getName();
- Class<?> type = field.getType();
- String typeName = type.getSimpleName();
- if(typeName.equals("Struct")){
- if(instance.getClassType(name)!=null){
- type = instance.getClassType(name);
- typeName = type.getSimpleName();
- }
- }
- context.setVariable("__", bytes.length-bited/8);
- byte[] bts = null;
- if(size!=null){
- bts = new byte[size.value()];
- System.arraycopy(bytes, bited/8, bts, 0, size.value());
- bited+=size.value()*8;
- }else if(bit!=null){
- int val = 0;
- String strBin = "";
- for(int i=bited;i<bited+bit.value();i++){//閫愪綅鎵弿
- if((bytes[i/8] & (1 << (i%8))) != 0){//濡傛灉浣嶄负1
- strBin+="1";
- }else{
- strBin+="0";
- }
- val = Integer.parseInt(strBin, 2);
- }
- byte[] result = new byte[4];
- result[3] = (byte)(val);
- result[2] = (byte)(val >> 8);
- result[1] = (byte)(val >> 16);
- result[0] = (byte)(val >> 24);
- bts = new byte[(int)Math.ceil((double)bit.value()/8.0)];
- System.arraycopy(result, result.length-bts.length, bts, 0, bts.length);
- bited+=bit.value();
- }else if(expr!=null){
- ExpressionParser parser = new SpelExpressionParser();
- Expression exp = parser.parseExpression(expr.value());
- Integer len = CommonUtils.parseInt(exp.getValue(context,instance));
- if(len!=null){
- if(len==-1)continue;
- bts = new byte[len];
- System.arraycopy(bytes, bited/8, bts, 0, len);
- bited+=len*8;
- }
- }
- if(bts.length==0)continue;
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bts));
- if (typeName.equals("int") || typeName.equals("Integer")){
- field.setInt(instance,(int) convertEx(dis.readInt(),4));
- }else if (typeName.equals("long") || typeName.equals("Long")){
- field.setLong(instance, convertEx(dis.readLong(),8));
- }else if (typeName.equals("short") || typeName.equals("Short")){
- field.setShort(instance, (short) convertEx(dis.readShort(),2));
- }else if (typeName.equals("byte") || typeName.equals("Byte")){
- field.setByte(instance, (byte) convertEx(dis.readByte(),1));
- }else if (typeName.equals("byte[]")){
- field.set(instance, bts);
- }else if (typeName.equals("String")) {
- String strStr = new String(bts, StandardCharsets.UTF_8);
- if(flag!=null && flag.value().equals("BCD")){
- strStr = bcd2Str(bts);
- }else if(flag!=null && flag.value().equals("ASCII")){
- strStr = Struct.AscToStr(bts);
- }
- strStr = strStr.replaceAll("[\u0000]", "");
- field.set(instance, strStr);
- }else if (type.isArray()) {
- byte[] arrayBytes = bts;
- List list = new ArrayList();
- while(arrayBytes.length>0 && list.size()<256){
- Struct item = decode((Class<? extends Struct>) type.getComponentType(),arrayBytes);
- list.add(item);
- arrayBytes = item.unusedBytes;
- }
- Object array = Array.newInstance(type.getComponentType(), list.size());
- for(int i=0;i<list.size();i++){
- Array.set(array, i, list.get(i));
- }
- field.set(instance, array);
- }else if(type==Struct.class || Struct.class.isAssignableFrom(type)){
- byte[] arrayBytes = bts;
- Struct item = decode((Class<? extends Struct>) type,arrayBytes);
- field.set(instance, item);
- }else{
- throw new RuntimeException(cls.getSimpleName()+"瀛楁"+field.getName()+"绫诲瀷鏈煡");
- }
- instance.decodeByteMapping.put(name, bts);
- context.setVariable(name, field.get(instance));
- }
- byte[] useBytes = new byte[bited/8];
- System.arraycopy(bytes, 0 , useBytes, 0, bited/8);
- instance.decodeBytes = useBytes;
- byte[] unusedBytes = new byte[bytes.length-(bited/8)];
- if(unusedBytes.length>0){
- System.arraycopy(bytes, useBytes.length , unusedBytes, 0, unusedBytes.length);
- }
- instance.unusedBytes = unusedBytes;
- return (T) instance;
- }
- public static String toHex(byte[] bytes) {
+ // 瀛楄妭鏁扮粍 ===>> 杞负鍗佸叚杩涘埗瀛楃涓�
+ public static String toHex(byte[] bytes) {
StringBuilder buf = new StringBuilder(bytes.length * 2);
- for(byte b : bytes) { // 浣跨敤String鐨刦ormat鏂规硶杩涜杞崲
- buf.append(String.format("%02x", new Integer(b & 0xff)));
+ for (byte b : bytes) { // 浣跨敤String鐨刦ormat鏂规硶杩涜杞崲
+ buf.append(String.format("%02x", b & 0xff));
}
return buf.toString().toUpperCase();
}
+
public static byte[] toBytes(String str) {
- if(str == null || str.trim().equals("")) return new byte[0];
+ if (str == null || str.trim().equals("")) return new byte[0];
byte[] bytes = new byte[str.length() / 2];
- for(int i = 0; i < str.length() / 2; i++) {
+ for (int i = 0; i < str.length() / 2; i++) {
String subStr = str.substring(i * 2, i * 2 + 2);
bytes[i] = (byte) Integer.parseInt(subStr, 16);
}
return bytes;
}
-
-
-
- /**
- * @鍔熻兘: BCD鐮佽浆涓�10杩涘埗涓�(闃挎媺浼暟鎹�)
- * @鍙傛暟: BCD鐮�
- * @缁撴灉: 10杩涘埗涓�
- */
- public static String bcd2Str(byte[] bytes) {
- StringBuffer temp = new StringBuffer(bytes.length * 2);
- for (int i = 0; i < bytes.length; i++) {
- temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
- temp.append((byte) (bytes[i] & 0x0f));
- }
- return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
- .toString().substring(1) : temp.toString();
- }
- /**
- * @鍔熻兘: 10杩涘埗涓茶浆涓築CD鐮�
- * @鍙傛暟: 10杩涘埗涓�
- * @缁撴灉: BCD鐮�
- */
- public static byte[] str2Bcd(String asc) {
- int len = asc.length();
- int mod = len % 2;
- if (mod != 0) {
- asc = "0" + asc;
- len = asc.length();
- }
- byte abt[] = new byte[len];
- if (len >= 2) {
- len = len / 2;
- }
- byte bbt[] = new byte[len];
- abt = asc.getBytes();
- int j, k;
- for (int p = 0; p < asc.length() / 2; p++) {
- if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
- j = abt[2 * p] - '0';
- } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
- j = abt[2 * p] - 'a' + 0x0a;
- } else {
- j = abt[2 * p] - 'A' + 0x0a;
- }
- if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
- k = abt[2 * p + 1] - '0';
- } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
- k = abt[2 * p + 1] - 'a' + 0x0a;
- } else {
- k = abt[2 * p + 1] - 'A' + 0x0a;
- }
- int a = (j << 4) + k;
- byte b = (byte) a;
- bbt[p] = b;
- }
- return bbt;
- }
-
-
- public static class TestMessage {
- public @size(1) byte begin = 0x7e;//璧峰绗�
- public @size(2) short type = 0;//娑堟伅ID
- public @bit(2) byte retain;//娑堟伅浣撳睘鎬�>淇濈暀
- public @bit(1) byte subpkg;//娑堟伅浣撳睘鎬�>鏄惁鍒嗗寘,0琛ㄧず涓嶅垎鍖�
- public @bit(3) byte encrypt;//娑堟伅浣撳睘鎬�>鍔犲瘑鏂瑰紡,0琛ㄧず涓嶅姞瀵�
- public @bit(10) short length;//娑堟伅浣撻暱搴�
- public @size(6) @flag("BCD") String number;//鎵嬫満鍙风爜
- public @size(2) short serial;//娑堟伅娴佹按鍙�
- public @expr("#subpkg==1?2:0") short pkgs;//鍒嗗寘鏁�
- public @expr("#subpkg==1?2:0") short index;//鍖呭簭鍙�
- public @expr("#length") byte[] data;//鏁版嵁閮ㄥ垎
- public @size(1) byte verify;//鏍¢獙鐮�
- public @size(1) byte end = 0x7e;//缁撴潫绗�
- }
-
- public static byte getXor(byte[] datas,int start, int end){
- byte temp=datas[start];
- for (int i = start+1; i <end; i++) {
- temp ^=datas[i];
- }
- return temp;
+ /**
+ * @鍔熻兘: BCD鐮佽浆涓�10杩涘埗涓�(闃挎媺浼暟鎹�)
+ * @鍙傛暟: BCD鐮�
+ * @缁撴灉: 10杩涘埗涓�
+ */
+ public static String bcd2Str(byte[] bytes) {
+ StringBuffer temp = new StringBuffer(bytes.length * 2);
+ for (int i = 0; i < bytes.length; i++) {
+ temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
+ temp.append((byte) (bytes[i] & 0x0f));
+ }
+ return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
+ .toString().substring(1) : temp.toString();
}
-
+ /**
+ * @鍔熻兘: 10杩涘埗涓茶浆涓築CD鐮�
+ * @鍙傛暟: 10杩涘埗涓�
+ * @缁撴灉: BCD鐮�
+ */
+ public static byte[] str2Bcd(String asc) {
+ int len = asc.length();
+ int mod = len % 2;
+ if (mod != 0) {
+ asc = "0" + asc;
+ len = asc.length();
+ }
+ byte abt[] = new byte[len];
+ if (len >= 2) {
+ len = len / 2;
+ }
+ byte bbt[] = new byte[len];
+ abt = asc.getBytes();
+ int j, k;
+ for (int p = 0; p < asc.length() / 2; p++) {
+ if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
+ j = abt[2 * p] - '0';
+ } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
+ j = abt[2 * p] - 'a' + 0x0a;
+ } else {
+ j = abt[2 * p] - 'A' + 0x0a;
+ }
+ if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
+ k = abt[2 * p + 1] - '0';
+ } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
+ k = abt[2 * p + 1] - 'a' + 0x0a;
+ } else {
+ k = abt[2 * p + 1] - 'A' + 0x0a;
+ }
+ int a = (j << 4) + k;
+ byte b = (byte) a;
+ bbt[p] = b;
+ }
+ return bbt;
+ }
+
+ public static byte getXor(byte[] datas, int start, int end) {
+ byte temp = datas[start];
+ for (int i = start + 1; i < end; i++) {
+ temp ^= datas[i];
+ }
+ return temp;
+ }
+
/**
* 姹傛牎楠屽拰鐨勭畻娉�
* @param b 闇�瑕佹眰鏍¢獙鍜岀殑瀛楄妭鏁扮粍
* @return 鏍¢獙鍜�
*/
- public static byte sumCheck(byte[] b,int start, int end){
+ public static byte sumCheck(byte[] b, int start, int end) {
int sum = 0;
- for(int i = start; i < end; i++){
+ for (int i = start; i < end; i++) {
sum = sum + b[i];
}
return (byte) (sum & 0xff);
}
-
- //瀛楃涓茶浆鎹负ascii
- public static byte[] StrToAsc(String content){
- try {
- return content.getBytes(StandardCharsets.US_ASCII);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
+
+ //瀛楃涓茶浆鎹负ascii
+ public static byte[] StrToAsc(String content) {
+ try {
+ return content.getBytes(StandardCharsets.US_ASCII);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
}
-
+
//ascii杞崲涓簊tring
- public static String AscToStr(byte[] bytes){
- StringBuffer sbu = new StringBuffer();
- for (byte aByte : bytes) {
- sbu.append(Character.toString((char) aByte));
- }
- return sbu.toString();
+ public static String AscToStr(byte[] bytes) {
+ StringBuffer sbu = new StringBuffer();
+ for (byte aByte : bytes) {
+ sbu.append(Character.toString((char) aByte));
+ }
+ return sbu.toString();
+ }
+
+ public Class getClassType(String name) {
+ return null;
+ }
+
+ /**
+ * 鍒ゆ柇澶у皬绔�
+ * @return true: 灏忕 / false: 澶х
+ */
+ public boolean isReverse() {
+ return this.getClass().getAnnotation(little.class) != null;
+ }
+
+ /**
+ * 鑾峰彇瀛楄妭鏁扮粍
+ */
+ public byte[] toBytes() throws Exception {
+ return encode(this);
+ }
+
+ public Map<String, String> toDecodeHexMapping() throws Exception {
+ if (this.decodeByteMapping == null) this.decodeByteMapping = new HashMap<>();
+ Map<String, String> mapping = getHex(this.decodeByteMapping);
+ if (this.decodeBytes != null) {
+ mapping.put("byte[]", Struct.toHex(this.decodeBytes));
+ }
+ return mapping;
+ }
+
+ public Map<String, String> toEncodeHexMapping() throws Exception {
+ if (this.encodeBytes == null) this.encode(this);
+ if (this.encodeByteMapping == null) this.encodeByteMapping = new HashMap<>();
+ Map<String, String> mapping = getHex(this.encodeByteMapping);
+ mapping.put("byte[]", Struct.toHex(this.encodeBytes));
+ return mapping;
+ }
+
+ public Map<String, String> getHex(Map<String, byte[]> bytemapping) throws Exception {
+ Map<String, String> map = new LinkedHashMap<>();
+ Field[] fields = this.getClass().getFields();
+ for (Field field : fields) {
+ byte[] bytes = bytemapping.get(field.getName());
+ if (bytes != null) {
+ map.put(field.getName(), Struct.toHex(bytes));
+ }
+ }
+ return map;
+ }
+
+ // 杞琷ava瀵硅薄鍒版暟缁�
+ public byte[] encode(Struct entity) throws Exception {
+ ByteArrayOutputStream baOs = new ByteArrayOutputStream();
+ write(new DataOutputStream(baOs), entity);
+ entity.encodeBytes = baOs.toByteArray();
+ return entity.encodeBytes;
+ }
+
+ /**
+ * 鍐欐暟鎹埌杈撳嚭娴�
+ *
+ * @param dos
+ * @param entity
+ */
+ public void write(DataOutputStream dos, Struct entity) throws Exception {
+ if (entity == null) return;
+ if (entity.encodeByteMapping == null) entity.encodeByteMapping = new HashMap<>();
+ Field[] fields = entity.getClass().getFields();
+ EvaluationContext context = new StandardEvaluationContext();
+ for (Field field : Objects.requireNonNull(ReflectUtils.removeStaticField(fields))) {
+ field.setAccessible(true);
+
+ String name = field.getName();
+ Class<?> type = field.getType();
+ String typeName = type.getSimpleName();
+ if (typeName.equals("Struct")) {
+ if (entity.getClassType(name) != null) {
+ type = entity.getClassType(name);
+ typeName = type.getSimpleName();
+ } else if (field.get(entity) != null) {
+ type = field.get(entity).getClass();
+ typeName = type.getSimpleName();
+ }
+ }
+
+ size size = field.getAnnotation(size.class);
+ bit bit = field.getAnnotation(bit.class);
+ expr expr = field.getAnnotation(expr.class);
+ flag flag = field.getAnnotation(flag.class);
+ if (size == null && bit == null && expr == null) {
+ continue;
+ }
+
+ int bited = 0;//宸插啓浣嶆暟
+ int length = 0;//瀹氫箟鐨勯暱搴�
+ if (size != null) {
+ length = size.value();
+ bited += size.value() * 8;
+ } else if (bit != null) {
+ //鎸変綅鍐欐柟寮忔湭瀹炵幇澶勭悊
+ throw new RuntimeException("鎸変綅鍐欐柟寮忔湭瀹炵幇澶勭悊");
+ } else if (expr != null) {
+ ExpressionParser parser = new SpelExpressionParser();
+ Expression exp = parser.parseExpression(expr.value());
+ Integer len = null;
+ try {
+ len = CommonUtils.parseInt(exp.getValue(context, entity));
+ } catch (Exception e) {
+ len = 0;
+ }
+ if (len != null) {
+ if (len == -1) continue;
+ length = len;
+ bited += len * 8;
+ }
+ }
+ context.setVariable(name, field.get(entity));
+
+ byte[] bytes = new byte[length];
+
+ if (typeName.equals("int") || typeName.equals("Integer")) {
+ dos.write(bytes = convert(length, field.getInt(entity)));
+ } else if (typeName.equals("long") || typeName.equals("Long")) {
+ dos.write(bytes = convert(length, field.getLong(entity)));
+ } else if (typeName.equals("short") || typeName.equals("Short")) {
+ dos.write(bytes = convert(length, field.getShort(entity)));
+ } else if (typeName.equals("byte") || typeName.equals("Byte")) {
+ dos.write(bytes = convert(length, field.getByte(entity)));
+ } else if (typeName.equals("String")) {
+ String str = (String) field.get(entity);
+ if (str == null)
+ str = "";
+ str = str.replaceAll("銆�", " ");
+
+ byte[] bts = null;
+ if (flag != null && flag.value().equals("ASCII")) {
+ bts = Struct.StrToAsc(str);
+ } else if (flag != null && flag.value().equals("BCD")) {
+ bts = Struct.str2Bcd(str);
+ } else {
+ bts = str.getBytes();
+ }
+
+ if (length == 0) {//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+ bytes = new byte[bts.length];
+ }
+ System.arraycopy(bts, 0, bytes, 0, bts.length);
+ dos.write(bytes);
+ } else if (typeName.equals("byte[]")) {
+ byte[] bts = (byte[]) field.get(entity);
+ if (bts != null) {
+ if (length == 0) {//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+ bytes = new byte[bts.length];
+ }
+ System.arraycopy(bts, 0, bytes, 0, bts.length);
+ dos.write(bytes);
+ }
+ } else if (type.isArray()) {
+ ByteArrayOutputStream baOs1 = new ByteArrayOutputStream();
+ DataOutputStream dos1 = new DataOutputStream(baOs1);
+ for (Object object : (Object[]) field.get(entity)) {
+ write(dos1, (Struct) object);
+ }
+ byte[] bts = baOs1.toByteArray();
+ if (length == 0) {//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+ bytes = new byte[bts.length];
+ }
+ System.arraycopy(bts, 0, bytes, 0, bts.length);
+ dos.write(bytes);
+ } else {
+ byte[] bts = encode((Struct) field.get(entity));
+ if (length == 0) {//濡傛灉闀垮害鏈缃紝浠ュ綋鍓嶅疄闄呯殑瀛楄妭涓哄噯
+ bytes = new byte[bts.length];
+ }
+ System.arraycopy(bts, 0, bytes, 0, bts.length);
+ dos.write(bytes);
+ }
+ entity.encodeByteMapping.put(name, bytes);
+ }
+ }
+
+ public byte[] convert(int size, long value) throws Exception {
+ ByteArrayOutputStream baOs = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(baOs);
+ switch (size) {
+ case 1://byte
+ dos.write((byte) value);
+ break;
+ case 2://short
+ dos.writeShort(this.isReverse() ? Short.reverseBytes((short) value) : (short) value);
+ break;
+ case 4://int
+ dos.writeInt(this.isReverse() ? Integer.reverseBytes((int) value) : (int) value);
+ break;
+ case 8://long
+ dos.writeLong(this.isReverse() ? Long.reverseBytes((long) value) : (long) value);
+ break;
+ }
+ return baOs.toByteArray();
+ }
+
+ public long convertEx(long value, int size) throws Exception {
+ switch (size) {
+ case 1://byte
+ return value;
+ case 2://short
+ return (this.isReverse() ? Short.reverseBytes((short) value) : (short) value);
+ case 4://int
+ return (this.isReverse() ? Integer.reverseBytes((int) value) : (int) value);
+ case 8://long
+ return (this.isReverse() ? Long.reverseBytes((long) value) : (long) value);
+ }
+ return 0;
+ }
+
+ /**
+ * 瑙g爜锛� 瀛楄妭鏁扮粍 ====>> java瀵硅薄
+ */
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public <T extends Struct> T decode(byte[] bytes) throws Exception {
+ this.dataBytes = bytes;
+ Struct instance = this;
+ Class<? extends Struct> cls = this.getClass();
+ Field[] fields = cls.getFields();
+ if (this.decodeByteMapping == null) instance.decodeByteMapping = new HashMap();
+ // spring el琛ㄨ揪寮�
+ EvaluationContext context = new StandardEvaluationContext();
+ context.setVariable("_", bytes.length);
+ int bited = 0;//宸茶浣嶆暟
+ for (Field field : Objects.requireNonNull(ReflectUtils.removeStaticField(fields))) {
+ size size = field.getAnnotation(size.class);
+ bit bit = field.getAnnotation(bit.class);
+ expr expr = field.getAnnotation(expr.class);
+ flag flag = field.getAnnotation(flag.class);
+ // 娌℃湁size銆乥it銆乪xpr娉ㄨВ鐨勫彉閲忎笉杩涜瑙f瀽
+ if (size == null && bit == null && expr == null) {
+ continue;
+ }
+ String name = field.getName();
+ Class<?> type = field.getType();
+ String typeName = type.getSimpleName();
+ if (typeName.equals("Struct")) {
+ if (instance.getClassType(name) != null) {
+ type = instance.getClassType(name);
+ typeName = type.getSimpleName();
+ }
+ }
+ context.setVariable("__", bytes.length - bited / 8);
+ byte[] bts = null;
+ if (size != null) {
+ bts = new byte[size.value()];
+ System.arraycopy(bytes, bited / 8, bts, 0, size.value());
+ bited += size.value() * 8;
+ } else if (bit != null) {
+ int val = 0;
+ String strBin = "";
+ for (int i = bited; i < bited + bit.value(); i++) {//閫愪綅鎵弿
+ if ((bytes[i / 8] & (1 << (i % 8))) != 0) {//濡傛灉浣嶄负1
+ strBin += "1";
+ } else {
+ strBin += "0";
+ }
+ val = Integer.parseInt(strBin, 2);
+ }
+ byte[] result = new byte[4];
+ result[3] = (byte) (val);
+ result[2] = (byte) (val >> 8);
+ result[1] = (byte) (val >> 16);
+ result[0] = (byte) (val >> 24);
+ bts = new byte[(int) Math.ceil((double) bit.value() / 8.0)];
+ System.arraycopy(result, result.length - bts.length, bts, 0, bts.length);
+ bited += bit.value();
+ } else if (expr != null) {
+ ExpressionParser parser = new SpelExpressionParser();
+ Expression exp = parser.parseExpression(expr.value());
+ Integer len = CommonUtils.parseInt(exp.getValue(context, instance));
+ if (len != null) {
+ if (len == -1) continue;
+ bts = new byte[len];
+ System.arraycopy(bytes, bited / 8, bts, 0, len);
+ bited += len * 8;
+ }
+ }
+ if (bts.length == 0) continue;
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bts));
+ if (typeName.equals("int") || typeName.equals("Integer")) {
+ field.setInt(instance, (int) convertEx(dis.readInt(), 4));
+ } else if (typeName.equals("long") || typeName.equals("Long")) {
+ field.setLong(instance, convertEx(dis.readLong(), 8));
+ } else if (typeName.equals("short") || typeName.equals("Short")) {
+ field.setShort(instance, (short) convertEx(dis.readShort(), 2));
+ } else if (typeName.equals("byte") || typeName.equals("Byte")) {
+ field.setByte(instance, (byte) convertEx(dis.readByte(), 1));
+ } else if (typeName.equals("byte[]")) {
+ field.set(instance, bts);
+ } else if (typeName.equals("String")) {
+ String strStr = new String(bts, StandardCharsets.UTF_8);
+ if (flag != null && flag.value().equals("BCD")) {
+ strStr = bcd2Str(bts);
+ } else if (flag != null && flag.value().equals("ASCII")) {
+ strStr = Struct.AscToStr(bts);
+ }
+ strStr = strStr.replaceAll("[\u0000]", "");
+ field.set(instance, strStr);
+ } else if (type.isArray()) {
+ byte[] arrayBytes = bts;
+ List list = new ArrayList();
+ while (arrayBytes.length > 0 && list.size() < 256) {
+ Struct item = decode((Class<? extends Struct>) type.getComponentType(), arrayBytes);
+ list.add(item);
+ arrayBytes = item.unusedBytes;
+ }
+ Object array = Array.newInstance(type.getComponentType(), list.size());
+ for (int i = 0; i < list.size(); i++) {
+ Array.set(array, i, list.get(i));
+ }
+ field.set(instance, array);
+ } else if (type == Struct.class || Struct.class.isAssignableFrom(type)) {
+ byte[] arrayBytes = bts;
+ Struct item = decode((Class<? extends Struct>) type, arrayBytes);
+ field.set(instance, item);
+ } else {
+ throw new RuntimeException(cls.getSimpleName() + "瀛楁" + field.getName() + "绫诲瀷鏈煡");
+ }
+ instance.decodeByteMapping.put(name, bts);
+ context.setVariable(name, field.get(instance));
+ }
+ byte[] useBytes = new byte[bited / 8];
+ System.arraycopy(bytes, 0, useBytes, 0, bited / 8);
+ instance.decodeBytes = useBytes;
+ byte[] unusedBytes = new byte[bytes.length - (bited / 8)];
+ if (unusedBytes.length > 0) {
+ System.arraycopy(bytes, useBytes.length, unusedBytes, 0, unusedBytes.length);
+ }
+ instance.unusedBytes = unusedBytes;
+ return (T) instance;
+ }
+
+ public static class TestMessage {
+ public @size(1) byte begin = 0x7e;//璧峰绗�
+ public @size(2) short type = 0;//娑堟伅ID
+ public @bit(2) byte retain;//娑堟伅浣撳睘鎬�>淇濈暀
+ public @bit(1) byte subpkg;//娑堟伅浣撳睘鎬�>鏄惁鍒嗗寘,0琛ㄧず涓嶅垎鍖�
+ public @bit(3) byte encrypt;//娑堟伅浣撳睘鎬�>鍔犲瘑鏂瑰紡,0琛ㄧず涓嶅姞瀵�
+ public @bit(10) short length;//娑堟伅浣撻暱搴�
+ public @size(6)
+ @flag("BCD") String number;//鎵嬫満鍙风爜
+ public @size(2) short serial;//娑堟伅娴佹按鍙�
+ public @expr("#subpkg==1?2:0") short pkgs;//鍒嗗寘鏁�
+ public @expr("#subpkg==1?2:0") short index;//鍖呭簭鍙�
+ public @expr("#length") byte[] data;//鏁版嵁閮ㄥ垎
+ public @size(1) byte verify;//鏍¢獙鐮�
+ public @size(1) byte end = 0x7e;//缁撴潫绗�
}
}
\ No newline at end of file
--
Gitblit v1.9.1