From 186d7a48f7ab95e694cec28dfb32542ddd0d27be Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Mon, 29 Mar 2021 15:26:20 +0800 Subject: [PATCH] add test: IdentifierComponentTest --- .../java/component/IdentifierComponent.java | 121 ++++++++++++++++- src/main/java/encoding/Encoder.java | 2 +- src/main/java/encoding/TLV.java | 13 ++ src/main/java/encoding/VlInt.java | 1 + .../component/IdentifierComponentTest.java | 128 ++++++++++++++++++ 5 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 src/test/java/component/IdentifierComponentTest.java diff --git a/src/main/java/component/IdentifierComponent.java b/src/main/java/component/IdentifierComponent.java index 64cddef..c8e4dab 100644 --- a/src/main/java/component/IdentifierComponent.java +++ b/src/main/java/component/IdentifierComponent.java @@ -14,6 +14,8 @@ import util.ByteHelper; import util.ByteHelperException; import util.StringHelper; +import java.util.Arrays; + // @Description: // 1. 参考 => https://named-data.net/doc/tech-memos/naming-conventions.pdf ,借鉴但不是按这个实现的 // 2. 格式如下: @@ -27,16 +29,17 @@ import util.StringHelper; // 0x01 非负整数(可以用1、2、4、8个字节表示) // 0x02 任意字节数组 public class IdentifierComponent implements TlvComponentBase, IEncodingAble { - private Block identifierBlock; // IdentifierComponent数据以TLV形式存储下来 private byte marker; // 标记 => 用来区分不同类型的 IdentifierComponent private String stringValue; // 如果 Marker == 0x00,则本组件存储一个字符串 private long intValue; // 如果 Marker == 0x01,则本组件存储一个非负整型 private byte[] byteArrayValue; // 如果 Marker == 0x02,则本组件存储一个字节数组 - private static final byte MarkerString = 0x00; + private static final byte MarkerString = 0x00; private static final byte MarkerNonNegativeInteger = 0x01; - private static final byte MarkerByteArray = 0x02; + private static final byte MarkerByteArray = 0x02; + private static final byte MarkerVersionNumber = 0x03; + private static final byte MarkerFragmentNumber = 0x04; /** * 用于判断某个字节是否在已分配的Marker列表当中 @@ -45,13 +48,19 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { * @return */ private boolean isInMarker(byte marker) { - if ((marker == MarkerString) || (marker == MarkerNonNegativeInteger) || (marker == MarkerByteArray)) { + if ((marker == MarkerString) || (marker == MarkerNonNegativeInteger) + || (marker == MarkerByteArray) || (marker == MarkerVersionNumber) + || (marker == MarkerFragmentNumber)) { return true; } else { return false; } } + public IdentifierComponent(){ + this.identifierBlock = new Block(); + } + /** * 根据一个字符串构造一个 IdentifierComponent * @@ -82,7 +91,8 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { public IdentifierComponent(long intValue) { this.identifierBlock = new Block(); this.identifierBlock.setType(new VlInt(TLV.TlvIdentifierComponent)); - this.identifierBlock.setLength(new VlInt(new VlInt(intValue).size() + 1)); + byte[] uint64Array=Encoder.buildNonNegativeIntegerArr(intValue); + this.identifierBlock.setLength(new VlInt( uint64Array.length+ 1)); byte[] value = new byte[0]; try { value = new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; @@ -90,7 +100,7 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { e.printStackTrace(); } value[0] = MarkerNonNegativeInteger; - System.arraycopy(new VlInt(intValue).getVlIntBytes(), 0, value, 1, new VlInt(intValue).size()); + System.arraycopy(uint64Array, 0, value, 1, uint64Array.length); this.identifierBlock.setValue(value); this.marker = MarkerNonNegativeInteger; this.intValue = intValue; @@ -118,6 +128,38 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { this.byteArrayValue = arr; } + /** + * 创建一个语义为版本号的 IdentifierComponent + */ + public void buildVersionNumberIdentifierComponent(long versionNumber){ + this.identifierBlock.setType(new VlInt(TLV.TlvIdentifierComponent)); + int len=TLV.SizeOfNonNegativeInteger(versionNumber) + 1; + this.identifierBlock.setLength(new VlInt(len)); + byte[] value=new byte[len]; + value[0]=MarkerVersionNumber; + this.marker=MarkerVersionNumber; + System.arraycopy(Encoder.buildNonNegativeIntegerArr(versionNumber),0,value,1,len-1); + this.identifierBlock.setValue(value); + this.intValue=versionNumber; + } + + /** + * 创建一个语义为分段号的 IdentifierComponent + * @param fragmentNumber + */ + public void buildFragmentNumberIdentifierComponent(long fragmentNumber){ + this.identifierBlock = new Block(); + this.identifierBlock.setType(new VlInt(TLV.TlvIdentifierComponent)); + int len=TLV.SizeOfNonNegativeInteger(fragmentNumber) + 1; + this.identifierBlock.setLength(new VlInt(len)); + byte[] value=new byte[len]; + value[0]=MarkerFragmentNumber; + this.marker=MarkerFragmentNumber; + System.arraycopy(Encoder.buildNonNegativeIntegerArr(fragmentNumber),0,value,1,len-1); + this.identifierBlock.setValue(value); + this.intValue=fragmentNumber; + } + /** * 根据一个 TLV Block 创建一个 IdentifierComponent * @@ -128,6 +170,14 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { this.wireDecode(block); } + public byte getMarker() { + return marker; + } + + public Block getBlock() { + return identifierBlock; + } + /** * 以字符串形式获取本 IdentifierComponent 的值 * @@ -146,6 +196,22 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { return this.intValue; } + /** + * 以版本号的形式获取本 IdentifierComponent 的值 + * @return + */ + public long getVersionNumber() { + return this.intValue; + } + + /** + * 以分段号的形式获取本 IdentifierComponent 的值 + * @return + */ + public long getFragmentNumber() { + return this.intValue; + } + /** * 以字节数组的形式获取本 IdentifierComponent 的值 * @@ -182,6 +248,47 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { return this.marker == MarkerByteArray; } + /** + * 判断当前 IdentifierComponent 是否存储的是一个版本号语义的数字 + * @return + */ + public boolean isVersionNumber() { + return this.marker == MarkerVersionNumber; + } + + /** + * 判断当前 IdentifierComponent 是否存储的是一个分段号语义的数字 + * @return + */ + public boolean isFragmentNumber() { + return this.marker == MarkerFragmentNumber; + } + + /** + * 判断当前 IdentifierComponent 是否等于另一个 IdentifierComponent + * @param target + * @return + */ + public boolean isSame(IdentifierComponent target){ + if(target==null){ + return false; + } + if(this.marker==target.marker){ + if(this.isString()){ + return this.stringValue.equals(target.stringValue); + } + if((this.isNonNegativeInteger()&&target.isNonNegativeInteger())|| + (this.isVersionNumber()&&target.isVersionNumber())|| + (this.isFragmentNumber()&&target.isFragmentNumber())){ + return this.intValue==target.intValue; + } + if(this.isByteArray()){ + return Arrays.equals(this.byteArrayValue,target.byteArrayValue); + } + } + return false; + } + /** * 线速编码,将 IdentifierComponent 编码成网络中传输的字节数组格式 * @@ -226,7 +333,7 @@ public class IdentifierComponent implements TlvComponentBase, IEncodingAble { v = ByteHelper.getTailBytes(value, 1); if (isString()) { this.stringValue = new String(v); - } else if (isNonNegativeInteger()) { + } else if (isNonNegativeInteger()||isVersionNumber()||isFragmentNumber()) { // 如果Marker指定是非负整型,则TLV-LENGTH的有效值为2、3、5、9 if ((length != 2) && (length != 3) && (length != 5) && (length != 9)) { return false; diff --git a/src/main/java/encoding/Encoder.java b/src/main/java/encoding/Encoder.java index 9c8efb8..eb5dc50 100644 --- a/src/main/java/encoding/Encoder.java +++ b/src/main/java/encoding/Encoder.java @@ -137,7 +137,7 @@ public class Encoder { * @param uint64 * @return */ - public byte[] buildNonNegativeIntegerArr(long uint64){ + public static byte[] buildNonNegativeIntegerArr(long uint64){ VlInt vlInt=new VlInt(uint64); int len=vlInt.getVlIntBytes().length; if(uint64<=255){ diff --git a/src/main/java/encoding/TLV.java b/src/main/java/encoding/TLV.java index 093342b..7f56cde 100644 --- a/src/main/java/encoding/TLV.java +++ b/src/main/java/encoding/TLV.java @@ -69,6 +69,19 @@ public class TLV { // TODO: 目前TLV值的分配,第一轮分配都在500以内,如果以后分配更高值时,需要修改此处的限制 public static final int MaxTlvNum = 500; + + public static int SizeOfNonNegativeInteger(long v){ + if(v<=VlInt.uint8Max){ + return 1; + }else if(v<=VlInt.uint16Max){ + return 2; + }else if(v<=VlInt.uint32Max){ + return 4; + }else{ + return 8; + } + } + /** * 从字节数组中读出一个变长整型 * @param buffer diff --git a/src/main/java/encoding/VlInt.java b/src/main/java/encoding/VlInt.java index 108beaa..d1f4e1e 100644 --- a/src/main/java/encoding/VlInt.java +++ b/src/main/java/encoding/VlInt.java @@ -39,6 +39,7 @@ public class VlInt { public static final int VlIntSize5=5; public static final int VlIntSize9=9; + public static final long uint8Max= (long) (pow(2, 8)-1); public static final long uint16Max= (long) (pow(2, 16)-1); public static final long uint32Max= (long) (pow(2, 32)-1); public static final long uint64Max= Long.MAX_VALUE; //MIN1.0中此数用long的最大值表示 diff --git a/src/test/java/component/IdentifierComponentTest.java b/src/test/java/component/IdentifierComponentTest.java new file mode 100644 index 0000000..fc274cb --- /dev/null +++ b/src/test/java/component/IdentifierComponentTest.java @@ -0,0 +1,128 @@ +package component; + +import encoding.Block; +import encoding.BlockException; +import encoding.VlInt; +import org.junit.Test; +import util.ByteHelper; + +import java.util.Arrays; + +/* + * @Author: Wang Feng + * @Description: + * @Version: 1.0.0 + * @Date: 9:07 2021/3/26 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class IdentifierComponentTest { + //判断空字符串能否正常运行 + @Test + public void TestCreateIdentifierComponentByString(){ + String str=""; + IdentifierComponent got=new IdentifierComponent(str); + byte gotMaker=got.getMarker(); + String gotStr=got.getString(); + long gotInt=got.getNonNegativeInteger(); + byte[] gotByte=got.getByteArray(); + System.out.println("maker: "+gotMaker+" ,str: "+gotStr + +" ,int: "+gotInt+" ,byte: "+Arrays.toString(gotByte)+" ,value: " + + Arrays.toString(got.getBlock().getValue())); + System.out.println("isStr: "+got.isString()+" ,isInt: "+got.isNonNegativeInteger() + +" ,isByte: "+got.isByteArray()); + } + + //测试最大值是否正常运行 + @Test + public void TestCreateIdentifierComponentByNonNegativeInteger(){ + long l=Long.MAX_VALUE; +// System.out.println(ByteHelper); + IdentifierComponent got=new IdentifierComponent(l); + byte gotMaker=got.getMarker(); + String gotStr=got.getString(); + long gotInt=got.getNonNegativeInteger(); + byte[] gotByte=got.getByteArray(); + System.out.println("maker: "+gotMaker+" ,str: "+gotStr + +" ,int: "+gotInt+" ,byte: "+Arrays.toString(gotByte)+" ,value: " + + Arrays.toString(got.getBlock().getValue())); + System.out.println("isStr: "+got.isString()+" ,isInt: "+got.isNonNegativeInteger() + +" ,isByte: "+got.isByteArray()); + } + + // 根据一个字节数组构造一个 IdentifierComponent + @Test + public void CreateIdentifierComponentByByteArray(){ + byte[] genbyte={}; + IdentifierComponent got=new IdentifierComponent(genbyte); + byte gotMaker=got.getMarker(); + String gotStr=got.getString(); + long gotInt=got.getNonNegativeInteger(); + byte[] gotByte=got.getByteArray(); + System.out.println("maker: "+gotMaker+" ,str: "+gotStr + +" ,int: "+gotInt+" ,byte: "+Arrays.toString(gotByte)+" ,value: " + + Arrays.toString(got.getBlock().getValue())); + System.out.println("isStr: "+got.isString()+" ,isInt: "+got.isNonNegativeInteger() + +" ,isByte: "+got.isByteArray()); + } + + @Test + public void TestCreateIdentifierComponentByBlock() throws BlockException, ComponentException { + byte[] buf=new byte[8001]; + buf[0]=0x02; + Block block=new Block(new VlInt(241),new VlInt(8001),buf,true); + IdentifierComponent got=new IdentifierComponent(block); + byte gotMaker=got.getMarker(); + String gotStr=got.getString(); + long gotInt=got.getNonNegativeInteger(); + byte[] gotByte=got.getByteArray(); + System.out.println("maker: "+gotMaker+" ,str: "+gotStr + +" ,int: "+gotInt+" ,byte length: "+gotByte.length+" ,byte: " + +Arrays.toString(gotByte)+" ,value: " + + Arrays.toString(got.getBlock().getValue())); + System.out.println("isStr: "+got.isString()+" ,isInt: "+got.isNonNegativeInteger() + +" ,isByte: "+got.isByteArray()); + } + + @Test + public void TestIdentifier_WireDecode() throws BlockException, ComponentException { + TestCreateIdentifierComponentByBlock(); + } + + @Test + public void TestCreateVersionNumberIdentifierComponent(){ + long genInt=Long.MAX_VALUE; + IdentifierComponent got=new IdentifierComponent(); + got.buildVersionNumberIdentifierComponent(genInt); + byte gotMaker=got.getMarker(); + String gotStr=got.getString(); + long gotInt=got.getNonNegativeInteger(); + byte[] gotByte=got.getByteArray(); + System.out.println("maker: "+gotMaker+" ,str: "+gotStr + +" ,int: "+gotInt +// +" ,byte length: " +gotByte.length + +" ,byte: "+Arrays.toString(gotByte) + +" ,value: " + Arrays.toString(got.getBlock().getValue())); + System.out.println("isStr: "+got.isString()+" ,isInt: "+got.isNonNegativeInteger() + +" ,isByte: "+got.isByteArray()+" ,isVersion: "+got.isVersionNumber() + +" ,isFrame: "+got.isFragmentNumber()); + } + + @Test + public void TestCreateFragmentNumberIdentifierComponent(){ + long genInt=Long.MAX_VALUE; + IdentifierComponent got=new IdentifierComponent(); + got.buildFragmentNumberIdentifierComponent(genInt); + byte gotMaker=got.getMarker(); + String gotStr=got.getString(); + long gotInt=got.getNonNegativeInteger(); + byte[] gotByte=got.getByteArray(); + System.out.println("maker: "+gotMaker+" ,str: "+gotStr + +" ,int: "+gotInt +// +" ,byte length: " +gotByte.length + +" ,byte: "+Arrays.toString(gotByte) + +" ,value: " + Arrays.toString(got.getBlock().getValue())); + System.out.println("isStr: "+got.isString()+" ,isInt: "+got.isNonNegativeInteger() + +" ,isByte: "+got.isByteArray()+" ,isVersion: "+got.isVersionNumber() + +" ,isFrame: "+got.isFragmentNumber()); + } +}