|  |  |  | 
|---|
|  |  |  | 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; | 
|---|
|  |  |  | 
|---|
|  |  |  | 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); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param dos | 
|---|
|  |  |  | * @param entity | 
|---|
|  |  |  | * @throws Exception | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void write(DataOutputStream dos, Struct entity) throws Exception { | 
|---|
|  |  |  | if(entity==null)return; | 
|---|
|  |  |  | 
|---|
|  |  |  | return instance.decode(bytes); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 解码: 字节数组 ====>> java对象 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @SuppressWarnings({ "unchecked", "rawtypes" }) | 
|---|
|  |  |  | public <T extends Struct> T decode(byte[] bytes) throws Exception{ | 
|---|
|  |  |  | this.dataBytes = bytes; | 
|---|
|  |  |  | 
|---|
|  |  |  | 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;//已读位数 | 
|---|
|  |  |  | 
|---|
|  |  |  | bit bit = field.getAnnotation(bit.class); | 
|---|
|  |  |  | expr expr = field.getAnnotation(expr.class); | 
|---|
|  |  |  | flag flag = field.getAnnotation(flag.class); | 
|---|
|  |  |  | // 没有size、bit、expr注解的变量不进行解析 | 
|---|
|  |  |  | 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(); | 
|---|
|  |  |  | 
|---|
|  |  |  | instance.unusedBytes = unusedBytes; | 
|---|
|  |  |  | return (T) instance; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 字节数组 ===>> 转为十六进制字符串 | 
|---|
|  |  |  | public static String toHex(byte[] bytes) { | 
|---|
|  |  |  | StringBuilder buf = new StringBuilder(bytes.length * 2); | 
|---|
|  |  |  | for(byte b : bytes) { // 使用String的format方法进行转换 | 
|---|
|  |  |  | buf.append(String.format("%02x", new Integer(b & 0xff))); | 
|---|
|  |  |  | buf.append(String.format("%02x", b & 0xff)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return buf.toString().toUpperCase(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return bbt; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static class TestMessage { | 
|---|
|  |  |  | public @size(1) byte begin = 0x7e;//起始符 | 
|---|