From d6ff18e0ff89d36e80195da43ca40bf3a8f42b2c Mon Sep 17 00:00:00 2001
From: Administrator <pjb>
Date: 星期日, 15 六月 2025 09:38:14 +0800
Subject: [PATCH] wms分配库位异常

---
 src/main/java/com/zy/common/utils/Struct.java |  898 ++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 452 insertions(+), 446 deletions(-)

diff --git a/src/main/java/com/zy/common/utils/Struct.java b/src/main/java/com/zy/common/utils/Struct.java
index 9f960a0..b505108 100644
--- a/src/main/java/com/zy/common/utils/Struct.java
+++ b/src/main/java/com/zy/common/utils/Struct.java
@@ -21,481 +21,487 @@
  * @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;
-	}
+    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;
 
-	/**
-	 * 鍒ゆ柇澶у皬绔�
-	 * @return true: 灏忕 / false: 澶х
-	 */
-	public boolean isReverse() {
-		return this.getClass().getAnnotation(little.class)!=null;
-	}
+    @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[] 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;
-	}
-	
-	@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