diff --git a/src/main/java/encoding/Block.java b/src/main/java/encoding/Block.java index cb92f54..0b796bd 100644 --- a/src/main/java/encoding/Block.java +++ b/src/main/java/encoding/Block.java @@ -1,6 +1,6 @@ -package main.java.encoding; +package encoding; -import main.java.util.ByteHelper; +import util.ByteHelper; import java.util.LinkedList; import java.util.List; diff --git a/src/main/java/encoding/Encoder.java b/src/main/java/encoding/Encoder.java new file mode 100644 index 0000000..2562083 --- /dev/null +++ b/src/main/java/encoding/Encoder.java @@ -0,0 +1,167 @@ +package encoding; + +/* + * @Author: Wang Feng + * @Description: 一个工具类,用来便捷的实现TLV编码 + * @Version: 1.0.0 + * @Date: 20:21 2021/3/5 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class Encoder { + private byte[] buffer; + private int left; // 左指针 => 指向 Prepend* 操作下一个可以插入的位置 + private int right; // 右指针 => 指向 Append* 操作下一个可以插入的位置 + private boolean isInitial; // 是否初始化 + private boolean isEstimator;// 是否仅测量编码后的长度,而不实际进行编码 + private SizeT totalReserve; // 编码缓存数组的大小 + + /** + * 编码测量初始化 + * @Description: + * 1. 一旦调用这个函数进行初始化,则调用所有的编码函数只会测量编码后的长度,不会执行实际的编码 + */ + public void estimatorReset(){ + this.left=0; + this.right=1; + this.isInitial=true; + this.isEstimator=true; + this.totalReserve=new SizeT(Long.MAX_VALUE); //todo: 这里可能越界。 + } + + /** + * 编码初始化 + * @Description: + * @param totalReserve 总的存储编码结果的数组长度 + * @param reserveFromBack 默认情况下,左右指针都指向数组的最右侧,表示totalReserve指定的所有空间都是预留给 Prepend* 操作的 + * reserveFromBack 可以指定需要预留多少空间给 Append*操作 + */ + public boolean estimatorReset(SizeT totalReserve,SizeT reserveFromBack){ + if(reserveFromBack.compareTo(totalReserve)>0){ + return false; + } + this.isInitial=true; + this.isEstimator=false; + this.totalReserve=totalReserve; + this.buffer=new byte[totalReserve.getVlIntValue2Int()]; //todo: 特殊情况下,可能越界。 + this.left=totalReserve.subtract(reserveFromBack)-1;//todo: 特殊情况下,可能越界。 + this.right=totalReserve.subtract(reserveFromBack);//todo: 特殊情况下,可能越界。 + return true; + } + + /** + * 判断是否为空 + * @return + */ + public boolean empty(){ + return (this.left+1)>=this.right; + } + + /** + * 编码后的大小 + * @return + */ + public SizeT size(){ + return new SizeT(this.right-this.left-1); + } + + + /** + * 在每个操作之前进行有效性检查 + * @Description: + * 1. 首先检查 Encoder 实例有没有初始化,没有初始化则返回错误; + * 2. 然后检查预计新增 size 个字节,会不会超出最大包限制,超出则返回错误; + * 3. 否则返回 nil + * @param size + * @return + */ + public boolean check(SizeT size){ + if(!this.isInitial){ + return false; + } + if(this.totalReserve.compareTo(this.size().add(size))<0){ + return false; + } + return true; + } + + /** + * Prepend a byte + * @param value + * @return 返回成功插入的字节数 + */ + public int prependByte(byte value){ + if(this.isEstimator){ + this.left--; + return 1; + } + if(check(new SizeT(1))){ + this.buffer[this.left]=value; + this.left--; + return 1; + }else{ + return 0; + } + } + + /** + * @param value + * @return 返回插入成功的字节数 + */ + public int appendByte(byte value){ + if(this.isEstimator){ + this.right++; + return 1; + } + if(check(new SizeT(1))){ + this.buffer[this.right]=value; + this.right++; + return 1; + }else{ + return 0; + } + } + + + /** + * @param array + * @param size + * @return 返回插入成功的字节数 + */ + public int prependByteArray(byte[] array,SizeT size){ + if(check(size)&&(size.compareTo(array.length)<=0)){ + if(this.isEstimator){ + this.left-=array.length; + return size.getVlIntValue2Int(); + }else{ + System.arraycopy(array,0,this.buffer, + this.left-size.getVlIntValue2Int()+1,size.getVlIntValue2Int()); + this.left-=array.length; + return size.getVlIntValue2Int(); + } + } + return 0; + } + + /** + * @param array + * @param size + * @return 返回插入成功的字节数 + */ + public int appendByteArray(byte[] array,SizeT size){ + if(check(size)&&(size.compareTo(array.length)<=0)){ + if(this.isEstimator){ + this.right+=array.length; + return size.getVlIntValue2Int(); + }else{ + System.arraycopy(array,0,this.buffer, + this.right,size.getVlIntValue2Int()); + this.right+=array.length; + return size.getVlIntValue2Int(); + } + } + return 0; + } + + + +} diff --git a/src/main/java/encoding/SizeT.java b/src/main/java/encoding/SizeT.java index 0d6c599..9a20daf 100644 --- a/src/main/java/encoding/SizeT.java +++ b/src/main/java/encoding/SizeT.java @@ -1,4 +1,4 @@ -package main.java.encoding; +package encoding; import java.math.BigInteger; @@ -7,6 +7,7 @@ import static java.lang.Math.pow; /* * @Author: Wang Feng * @Description:变长无符号整型,用于表示TLV中的T和L + * todo: 本类需要在VlInt经过彻底测试之后,再进行完善。或可直接继承vlint * @Version: 1.0.0 * @Date: 18:13 2021/3/1 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 @@ -68,22 +69,27 @@ public class SizeT { this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue); } + public SizeT(long l){ + this.VlIntValue=BigInteger.valueOf(l); + this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue); + } + // todo:传入一个long,将它解析成一个VlInt // 将vlint转为一个int输出:需要判断size是不是小于4(1 or 3) - public Integer getVlIntValue2Int(){ + public int getVlIntValue2Int(){ if(this.SizeOfVarNumber()<4){ return VlIntValue.intValue(); } - return null; + return Integer.parseInt(null); } // 将vlint转为一个long输出:需要判断size是不是小于8(5) - public Long getVlIntValue2Long(){ + public long getVlIntValue2Long(){ if(this.SizeOfVarNumber()<8){ return VlIntValue.longValue(); } - return null; + return Long.parseLong(null); } // 将vlint转为一个biginteger输出:需要判断size是不是等于9(9) @@ -113,6 +119,15 @@ public class SizeT { // todo: 判断vlint是否与某个long值相等 + /** + * 增加VlInt + * @param vlInt + * @return + */ + public int add(SizeT vlInt){ + return this.VlIntValue.add(vlInt.VlIntValue).intValue(); + } + /** * 判断与另一个VlInt的数值孰大孰小 * @param vlInt diff --git a/src/main/java/encoding/TLV.java b/src/main/java/encoding/TLV.java index 6a87749..c6d89d0 100644 --- a/src/main/java/encoding/TLV.java +++ b/src/main/java/encoding/TLV.java @@ -1,7 +1,7 @@ -package main.java.encoding; +package encoding; -import main.java.util.ByteHelper; +import util.ByteHelper; /* * @Author: Wang Feng diff --git a/src/main/java/encoding/VlInt.java b/src/main/java/encoding/VlInt.java index ea5ab5f..08851d4 100644 --- a/src/main/java/encoding/VlInt.java +++ b/src/main/java/encoding/VlInt.java @@ -1,7 +1,7 @@ -package main.java.encoding; +package encoding; -import main.java.util.ByteHelper; +import util.ByteHelper; import java.math.BigInteger; @@ -171,6 +171,15 @@ public class VlInt { return this.VlIntValue.subtract(vlInt.VlIntValue).intValue(); } + /** + * 增加VlInt + * @param vlInt + * @return + */ + public int add(VlInt vlInt){ + return this.VlIntValue.add(vlInt.VlIntValue).intValue(); + } + /** * 将BigInteger转为byte[按照变长无符号整数方式转] * @param bigInteger diff --git a/src/main/java/encoding/VlInt_V1.java b/src/main/java/encoding/VlInt_V1.java index 1d74a4e..69e9f97 100644 --- a/src/main/java/encoding/VlInt_V1.java +++ b/src/main/java/encoding/VlInt_V1.java @@ -1,4 +1,4 @@ -package main.java.encoding; +package encoding; import static java.lang.Math.pow; diff --git a/src/main/java/util/ByteHelper.java b/src/main/java/util/ByteHelper.java index fa2856a..8132d72 100644 --- a/src/main/java/util/ByteHelper.java +++ b/src/main/java/util/ByteHelper.java @@ -1,7 +1,7 @@ -package main.java.util; +package util; -import main.java.encoding.VlInt; +import encoding.VlInt; /* * @Author: Wang Feng