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