From 7ce9a7dcc6d7cf9506573dd49d76621f55772f34 Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Sat, 6 Mar 2021 21:20:57 +0800 Subject: [PATCH] finished Block --- src/main/java/encoding/Block.java | 217 +++++++++++++++++++++++++-- src/main/java/encoding/Encoder.java | 2 +- src/main/java/encoding/VlInt.java | 3 + src/main/java/util/ErrorHandler.java | 13 ++ 4 files changed, 225 insertions(+), 10 deletions(-) create mode 100644 src/main/java/util/ErrorHandler.java diff --git a/src/main/java/encoding/Block.java b/src/main/java/encoding/Block.java index e3fb196..8fa9f36 100644 --- a/src/main/java/encoding/Block.java +++ b/src/main/java/encoding/Block.java @@ -15,12 +15,68 @@ import java.util.List; // TLV 组件容器 class ElementContainer{ - private List ElementContainer; + private List elementContainer; public ElementContainer(){ - ElementContainer= new LinkedList<>(); + elementContainer = new LinkedList<>(); } + + /** + * 获取所有Block + * @return + */ + public List getElements(){ + return elementContainer; + } + + /** + * 获取block个数 + * @return + */ public int length(){ - return ElementContainer.size(); + return elementContainer.size(); + } + + /** + * 清除 elements 中所有的子TLV + */ + public void clear(){ + elementContainer.clear(); + } + + /** + * 往 elements 中添加一个子tlv + * @param block + */ + public void addElement(Block block){ + elementContainer.add(block); + } + + /** + * 移除所有指定type的子tlv + * @param tlvType + */ + public void removeElements(VlInt tlvType){ + List elementContainer=new LinkedList<>(); + for(Block block: this.elementContainer){ + if(!block.getTlvType().isEqual(tlvType)){ + elementContainer.add(block); + } + } + this.elementContainer =elementContainer; + } + + /** + * 从 elements 中找到第一个指定type的子TLV + * @param tlvType + * @return + */ + public Block getElement(VlInt tlvType){ + for(Block block: this.elementContainer){ + if(block.getTlvType().isEqual(tlvType)){ + return block; + } + } + return null; } } @@ -88,9 +144,32 @@ public class Block { //todo: 抛出异常 } - // todo;设置 Raw + // 设置 Raw + Encoder encoder=new Encoder(); + boolean resetBool=encoder.encoderReset(new SizeT(tlvType.size()+tlvLength.size()+buffer.length),new SizeT(0)); + if(!resetBool){ + //todo: 抛出异常 + } + if(encoder.prependByteArray(buffer,new SizeT(buffer.length))==0){ + //todo: 抛出异常 + } + if(encoder.prependVarNumber(tlvLength)==0){ + //todo: 抛出异常 + } + if(encoder.prependVarNumber(tlvType)==0){ + //todo: 抛出异常 + } + byte[] encodedBuffer=encoder.getBuffer(); + if(encodedBuffer==null){ + //todo: 抛出异常 + } + this.raw=encodedBuffer; - // todo 设置Value + // 设置value + this.value=buffer; + } + + public Block(Block block){ } @@ -177,16 +256,136 @@ public class Block { * 2. 如果TLV的value不为空,且不存在嵌套的子TLV,则会抛出错误 * @return */ -// public boolean parseSubElements(){ -// -// } + public boolean parseSubElements(){ + if((this.value.length==0)||this.elements.length()!=0){ + return true; + } + + // 循环解析所有的一级子TLV + for (int start = 0; start < this.value.length; start++) { + // 读取 TLV-TYPE + VlInt tlvType=TLV.readType(this.value,new VlInt(start)); + if(tlvType==null){ + this.clearElements(); + return false; + } + start+=tlvType.size(); + + // 读取 TLV-LENGTH + VlInt tlvLength=TLV.readVarNumber(this.value,new VlInt(start)); + if(tlvType==null){ + this.clearElements(); + return false; + } + start+=tlvLength.size(); + + // 检查 buffer 中是否有足够的字节 + if(tlvLength.add(start)>this.value.length){ + this.clearElements(); + return false; + } + + // 创建一个子 TLV Block 并添加到elements当中 + byte[] subBlockValue=new byte[tlvLength.getVlIntValue2Int()]; + System.arraycopy(this.value,start,subBlockValue,0,tlvLength.getVlIntValue2Int()); + Block block=createBlockByTypeLengthBuffer(tlvType,tlvLength,subBlockValue,true); + if(block==null){ + return false; + } + this.addElement(block); + start+=tlvLength.getVlIntValue2Int(); + } + return true; + } + + + /** + * 从 elements 中找到第一个指定type的子TLV + * @param tlvType + * @return + */ + public Block getElement(VlInt tlvType){ + return this.elements.getElement(tlvType); + } + + /** + * 移除所有指定type的子tlv + * @param tlvType + */ + public void removeElements(VlInt tlvType){ + this.elements.removeElements(tlvType); + } + + /** + * 往 elements 中添加一个子tlv + * @param block + */ + public void addElement(Block block){ + this.elements.addElement(block); + } + + /** + * 清除 elements 中所有的子TLV + */ + public void clearElements(){ + this.elements.clear(); + } /** * 判断是否有效 * @return */ public boolean isValid(){ - return true; + return this.tlvType.isEqual(TLV.TlvInvalid); + } + + /** + * 将当前的 TLV Block 编码成字节数组,存放在 raw 当中 + * @param encoder + * @return + */ + public int encode(Encoder encoder){ + // 如果已经有raw,则说明编码过,或者是解码而来的,不用在此Encode + if(this.hasRaw()){ + return encoder.prependByteArray(this.raw,new SizeT(this.raw.length)); + } + + int len=0; + + // 编码 TLV-VALUE + if(this.hasValue()){ + // 如果设置了 value ,则直接使用 + int tmplen=encoder.appendByteArray(this.value,new SizeT(this.value.length)); + if(tmplen==0){ + return 0; + } + len+=tmplen; + }else{ + // 如果 value 为空,则看 elements 中有没有子TLV Block,有则编码后插入 + for(Block subBlock:this.elements.getElements()){ + int tmplen=subBlock.encode(encoder); + if(tmplen==0){ + return 0; + } + len+=tmplen; + } + } + + // 编码 TLV-LENGTH + int tmplen=encoder.prependVarNumber(new VlInt(len)); + if(tmplen==0){ + return 0; + } + len+=tmplen; + + // 编码 TLV-TYPE + tmplen=encoder.prependVarNumber(this.tlvType); + if(tmplen==0){ + return 0; + } + len+=tmplen; + + return len; } } diff --git a/src/main/java/encoding/Encoder.java b/src/main/java/encoding/Encoder.java index cda4c63..4c1463b 100644 --- a/src/main/java/encoding/Encoder.java +++ b/src/main/java/encoding/Encoder.java @@ -35,7 +35,7 @@ public class Encoder { * @param reserveFromBack 默认情况下,左右指针都指向数组的最右侧,表示totalReserve指定的所有空间都是预留给 Prepend* 操作的 * reserveFromBack 可以指定需要预留多少空间给 Append*操作 */ - public boolean estimatorReset(SizeT totalReserve,SizeT reserveFromBack){ + public boolean encoderReset(SizeT totalReserve,SizeT reserveFromBack){ if(reserveFromBack.compareTo(totalReserve)>0){ return false; } diff --git a/src/main/java/encoding/VlInt.java b/src/main/java/encoding/VlInt.java index 72ee337..d57e00f 100644 --- a/src/main/java/encoding/VlInt.java +++ b/src/main/java/encoding/VlInt.java @@ -205,6 +205,9 @@ public class VlInt { public int add(VlInt vlInt){ return this.VlIntValue.add(vlInt.VlIntValue).intValue(); } + public int add(int i_int){ + return this.VlIntValue.intValue()+i_int; + } /** * 将BigInteger转为byte[按照变长无符号整数方式转] diff --git a/src/main/java/util/ErrorHandler.java b/src/main/java/util/ErrorHandler.java new file mode 100644 index 0000000..7a5a8c1 --- /dev/null +++ b/src/main/java/util/ErrorHandler.java @@ -0,0 +1,13 @@ +package util; + +/* + * @Author: Wang Feng + * @Description: 错误处理工具类 + * @Version: 1.0.0 + * @Date: 16:22 2021/3/6 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class ErrorHandler { + + +}