Files
min-dev-java/src/main/java/packet/MINPacket.java
T
2021-03-16 10:24:38 +08:00

170 lines
5.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package packet;
import component.IdentifierField;
import component.MutableField;
import component.ReadOnlyField;
import component.SignatureField;
import encoding.*;
/*
* @Author: Wang Fengs
* @Description: 表示一个MIN网络层包的通用结构
* @Version: 1.0.0
* @Date: 22:07 2021/3/13
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class MINPacket implements IEncodingAble {
public IdentifierField identifierField; // 标识区
private SignatureField signatureField; // 签名区
public ReadOnlyField readOnlyField; // 只读区
public MutableField mutableField; // 可变区
public VlInt packetType; // 包类型
/**
* 判断 MIN 包是否是一个有效的包
* @return
*/
public boolean isPacketValid(){
return TLV.isValidPacketType(packetType);
}
/**
* 将 Packet 线速编码为 TLV
* @param encoder
* @return
*/
@Override
public int wireEncode(Encoder encoder) {
if(!this.isPacketValid()){
return 0;
}
int totalLength=0;
// 编码 TLV-VALUE
// 可变区
int tmplen=this.mutableField.wireEncode(encoder);
if(tmplen<=0){
return 0;
}
totalLength+=tmplen;
// 只读区
tmplen=this.readOnlyField.wireEncode(encoder);
if(tmplen<=0){
return 0;
}
totalLength+=tmplen;
// 签名区
tmplen=this.signatureField.wireEncode(encoder);
if(tmplen<=0){
return 0;
}
totalLength+=tmplen;
// 标识区
tmplen=this.identifierField.wireEncode(encoder);
if(tmplen<=0){
return 0;
}
totalLength+=tmplen;
// 编码包 TLV-LENGTH
tmplen=encoder.prependVarNumber(new VlInt(totalLength));
if(tmplen<=0){
return 0;
}
totalLength+=tmplen;
// 编码包 TLV-TYPE
tmplen=encoder.prependVarNumber(this.packetType);
if(tmplen<=0){
return 0;
}
totalLength+=tmplen;
return totalLength;
}
/**
* 线速解码,将 MIN包 TLV 中的四个区域分别解析出来
* // @Description:
* // 1. 解析出四个区的TLV;
* // 2. 检查必要的TLV是否存在,不存在则抛出异常,以下为必须条件:
* // a. 必须包含标识区,且标识区至少包含一个标识
* @param block
* @return
*/
@Override
public boolean wireDecode(Block block) {
// 首先判断包是否有效
if(!block.isValid()){
return false;
}
// 首先解析子 Block
if(!block.parseSubElements()){
return false;
}
// 标记,用来记录是否满足必要条件
boolean existIdentifier=false;
// 解析四个标识区
int elementSize=block.getSubElements().length();
for (int i=0;i<elementSize;i++) {
Block cacheBlock=block.getSubElements().getBlock(i);
int judgeType= 0;
try {
judgeType = cacheBlock.getType().getVlIntValue2Int();
} catch (VlIntException e) {
throw new Error("MINPacket.wireDecode: "+e.getMessage());
}
switch (judgeType){
case TLV.TlvIdentifierField: // 目的标识区
// 解析标识区,保证其中至少存在一个标识
if(!cacheBlock.parseSubElements()){
return false;
}
if(!cacheBlock.hasSubElement()){
return false;
}
// 解析标识区
if(!this.identifierField.wireDecode(cacheBlock)){
return false;
}
// 标示解析到了至少一个以上的合法标识
existIdentifier=true;
case TLV.TlvSignatureField: // 签名区
// 解析签名区,保证如果存在签名,则签名均符合格式
if(!this.signatureField.wireDecode(cacheBlock)){
return false;
}
case TLV.TlvReadOnlyField: // 只读区
// 解析只读区
if(!this.readOnlyField.wireDecode(cacheBlock)){
return false;
}
case TLV.TlvMutableField: // 可变区
// 解析可变区
if(!this.mutableField.wireDecode(cacheBlock)){
return false;
}
default:
return false;
}
}
// 判断是否有必须的组件缺失
if(!existIdentifier){
return false;
}
return true;
}
}