| | |
| | | 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;//起始符 |