diff --git a/src/main/java/component/CanBePrefix.java b/src/main/java/component/CanBePrefix.java index 8cdae09..8bdb5fb 100644 --- a/src/main/java/component/CanBePrefix.java +++ b/src/main/java/component/CanBePrefix.java @@ -76,7 +76,7 @@ public class CanBePrefix implements TlvComponentBase,InitialAble, IEncodingAble @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvCanBePrefix))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvCanBePrefix))){ return false; } diff --git a/src/main/java/component/CongestionMark.java b/src/main/java/component/CongestionMark.java index f2d044b..dd41304 100644 --- a/src/main/java/component/CongestionMark.java +++ b/src/main/java/component/CongestionMark.java @@ -78,7 +78,7 @@ public class CongestionMark implements TlvComponentBase,InitialAble, IEncodingAb @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvCongestionMark))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvCongestionMark))){ return false; } diff --git a/src/main/java/component/FreshnessPeriod.java b/src/main/java/component/FreshnessPeriod.java index bb07c1c..0bb27fd 100644 --- a/src/main/java/component/FreshnessPeriod.java +++ b/src/main/java/component/FreshnessPeriod.java @@ -78,7 +78,7 @@ public class FreshnessPeriod implements TlvComponentBase,InitialAble, IEncodingA @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvFreshnessPeriod))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvFreshnessPeriod))){ return false; } diff --git a/src/main/java/component/HopLimit.java b/src/main/java/component/HopLimit.java index 6c26e96..99be99d 100644 --- a/src/main/java/component/HopLimit.java +++ b/src/main/java/component/HopLimit.java @@ -73,7 +73,7 @@ public class HopLimit implements TlvComponentBase,InitialAble, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvHopLimit))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvHopLimit))){ return false; } diff --git a/src/main/java/component/IdentifierComponent.java b/src/main/java/component/IdentifierComponent.java index d48540d..87afd4e 100644 --- a/src/main/java/component/IdentifierComponent.java +++ b/src/main/java/component/IdentifierComponent.java @@ -8,9 +8,9 @@ package component; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ -import encoding.Block; -import encoding.Encoder; -import encoding.IEncodingAble; +import encoding.*; +import util.ByteHelper; +import util.StringHelper; // @Description: // 1. 参考 => https://named-data.net/doc/tech-memos/naming-conventions.pdf ,借鉴但不是按这个实现的 @@ -25,23 +25,201 @@ import encoding.IEncodingAble; // 0x01 非负整数(可以用1、2、4、8个字节表示) // 0x02 任意字节数组 public class IdentifierComponent implements TlvComponentBase, IEncodingAble { - private Block block; + + private Block identifierBlock; // IdentifierComponent数据以TLV形式存储下来 private byte marker; // 标记 => 用来区分不同类型的 IdentifierComponent private String stringValue; // 如果 Marker == 0x00,则本组件存储一个字符串 private long intValue; // 如果 Marker == 0x01,则本组件存储一个非负整型 private byte[] byteArrayValue; // 如果 Marker == 0x02,则本组件存储一个字节数组 - public static final byte MarkerString = 0x00; - public static final byte MarkerNonNegativeInteger = 0x01; - public static final byte MarkerByteArray = 0x02; + private static final byte MarkerString = 0x00; + private static final byte MarkerNonNegativeInteger = 0x01; + private static final byte MarkerByteArray = 0x02; + /** + * 用于判断某个字节是否在已分配的Marker列表当中 + * @param marker + * @return + */ + private boolean isInMarker(byte marker){ + if((marker==MarkerString)||(marker==MarkerNonNegativeInteger)||(marker==MarkerByteArray)){ + return true; + }else{ + return false; + } + } + + /** + * 根据一个字符串构造一个 IdentifierComponent + * @param nameComponent + */ + public IdentifierComponent(String nameComponent){ + this.identifierBlock=new Block(); + this.identifierBlock.setType(new VlInt(TLV.TlvIdentifierComponent)); + this.identifierBlock.setLength(new VlInt(nameComponent.length()+1)); + byte[] value=new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; + value[0]=MarkerString; + System.arraycopy(nameComponent.getBytes(),0,value,1,nameComponent.getBytes().length); + this.identifierBlock.setValue(value); + this.marker=MarkerString; + this.stringValue=nameComponent; + } + + /** + * 根据一个非负整数构造一个 IdentifierComponent + * @param intValue + */ + 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[] value=new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; + value[0]=MarkerNonNegativeInteger; + System.arraycopy(new VlInt(intValue).getVlIntBytes(),0,value,1,new VlInt(intValue).size()); + this.identifierBlock.setValue(value); + this.marker=MarkerNonNegativeInteger; + this.intValue=intValue; + } + + /** + * 根据一个字节数组构造一个 IdentifierComponent + * @param arr + */ + public IdentifierComponent(byte[] arr){ + this.identifierBlock=new Block(); + this.identifierBlock.setType(new VlInt(TLV.TlvIdentifierComponent)); + this.identifierBlock.setLength(new VlInt(arr.length+1)); + byte[] value=new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; + value[0]=MarkerByteArray; + System.arraycopy(arr,0,value,1,arr.length); + this.identifierBlock.setValue(value); + this.marker=MarkerByteArray; + this.byteArrayValue=arr; + } + + /** + * 根据一个 TLV Block 创建一个 IdentifierComponent + * @param block + * @return + */ + public static IdentifierComponent createIdentifierComponentByBlock(Block block){ + IdentifierComponent identifierComponent=new IdentifierComponent(0); + identifierComponent.wireDecode(block); + return identifierComponent; + } + + /** + * 以字符串形式获取本 IdentifierComponent 的值 + * @return + */ + public String getString(){ + return this.stringValue; + } + + /** + * 以非负整数的形式获取本 IdentifierComponent 的值 + * @return + */ + public long getNonNegativeInteger(){ + return this.intValue; + } + + /** + * 以字节数组的形式获取本 IdentifierComponent 的值 + * @return + */ + public byte[] getByteArray(){ + return this.byteArrayValue; + } + + /** + * 判断当前 IdentifierComponent 是否是存储字符串的类型 + * @return + */ + public boolean isString(){ + return this.marker==MarkerString; + } + + /** + * 判断当前 IdentifierComponent 是否是存储非负整数的类型 + * @return + */ + public boolean isNonNegativeInteger(){ + return this.marker==MarkerNonNegativeInteger; + } + + /** + * 判断当前 IdentifierComponent 是否是存储字节数组的类型 + * @return + */ + public boolean isByteArray(){ + return this.marker==MarkerByteArray; + } + + /** + * 线速编码,将 IdentifierComponent 编码成网络中传输的字节数组格式 + * @param encoder + * @return + */ @Override public int wireEncode(Encoder encoder) { - return 0; + return this.identifierBlock.encode(encoder); } + /** + * 线速解码,将TLV Block解码成 IdentifierComponent + * @param block + * @return + */ @Override public boolean wireDecode(Block block) { - return false; + this.identifierBlock=new Block(block); + + //todo:越界问题 + int length=this.identifierBlock.getLength().getVlIntValue2Int(); + byte[] value=this.identifierBlock.getValue(); + + // 要求TLV-LENGTH至少为1,因为 IdentifierComponent 使用 TLV-VALUE 中的第一个字节作为Marker + if(length<1){ + return false; + } + + // 判断Marker是否有效 + if(!isInMarker(value[0])){ + return false; + } + this.marker=value[0]; + + // 根据不同类型的Marker,给不同的成员赋值 + byte[] v=ByteHelper.getTailBytes(value,1); + if(isString()){ + this.stringValue=new String(v); + }else if(isNonNegativeInteger()){ + // 如果Marker指定是非负整型,则TLV-LENGTH的有效值为2、3、5、9 + if((length!=2)&&(length!=3)&&(length!=5)&&(length!=9)){ + return false; + } + this.intValue=TLV.readNonNegativeInteger(v,0,v.length); + }else{ // byte[] + this.byteArrayValue=v; + } + + return true; + } + + /** + * 将 IdentifierComponent 使用百分号编码规则编码 + * @return + */ + public String toUri(){ + if(isString()){ + return StringHelper.escape(this.stringValue); + }else if(isNonNegativeInteger()){ +// return StringHelper.FormatUint(this.intValue,10); + // todo: 需要对long类型按照指定编码规则编码成字符串 + return ""; + }else{ + return StringHelper.escape(new String(this.byteArrayValue)); + } } } diff --git a/src/main/java/component/InterestLifeTime.java b/src/main/java/component/InterestLifeTime.java index b7ec99f..606c758 100644 --- a/src/main/java/component/InterestLifeTime.java +++ b/src/main/java/component/InterestLifeTime.java @@ -78,7 +78,7 @@ public class InterestLifeTime implements TlvComponentBase,InitialAble, IEncoding @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvInterestLifeTime))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvInterestLifeTime))){ return false; } diff --git a/src/main/java/component/MustBeRefresh.java b/src/main/java/component/MustBeRefresh.java index c14ee00..a28d883 100644 --- a/src/main/java/component/MustBeRefresh.java +++ b/src/main/java/component/MustBeRefresh.java @@ -76,7 +76,7 @@ public class MustBeRefresh implements TlvComponentBase,InitialAble, IEncodingAbl @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvMustBeRefresh))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvMustBeRefresh))){ return false; } diff --git a/src/main/java/component/MutableDangerousField.java b/src/main/java/component/MutableDangerousField.java index 04450a9..194f73e 100644 --- a/src/main/java/component/MutableDangerousField.java +++ b/src/main/java/component/MutableDangerousField.java @@ -99,7 +99,7 @@ public class MutableDangerousField implements TlvComponentBase, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvReadOnlyField))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvReadOnlyField))){ return false; } diff --git a/src/main/java/component/MutableField.java b/src/main/java/component/MutableField.java index 546d6ab..822623a 100644 --- a/src/main/java/component/MutableField.java +++ b/src/main/java/component/MutableField.java @@ -69,7 +69,7 @@ public class MutableField implements TlvComponentBase,IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvMutableField))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvMutableField))){ return false; } @@ -80,11 +80,11 @@ public class MutableField implements TlvComponentBase,IEncodingAble { for (int i = 0; i < block.getSubElements().length(); i++) { Block subBlock=block.getSubElements().getBlock(i); - if(subBlock.getTlvType().isEqual(TLV.TlvMutableProtectField)){ + if(subBlock.getType().isEqual(TLV.TlvMutableProtectField)){ if(!this.mutableProtectField.wireDecode(subBlock)){ return false; } - }else if(subBlock.getTlvType().isEqual(TLV.TlvMutableDangerousField)){ + }else if(subBlock.getType().isEqual(TLV.TlvMutableDangerousField)){ if(!this.mutableDangerousField.wireDecode(subBlock)){ return false; } diff --git a/src/main/java/component/MutableProtectField.java b/src/main/java/component/MutableProtectField.java index bf889b8..6a3b6dd 100644 --- a/src/main/java/component/MutableProtectField.java +++ b/src/main/java/component/MutableProtectField.java @@ -99,7 +99,7 @@ public class MutableProtectField implements TlvComponentBase, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvReadOnlyField))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvReadOnlyField))){ return false; } diff --git a/src/main/java/component/NackHeader.java b/src/main/java/component/NackHeader.java index a82de63..6d204e6 100644 --- a/src/main/java/component/NackHeader.java +++ b/src/main/java/component/NackHeader.java @@ -78,7 +78,7 @@ public class NackHeader implements TlvComponentBase,InitialAble, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvNackHeader))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvNackHeader))){ return false; } diff --git a/src/main/java/component/Nonce.java b/src/main/java/component/Nonce.java index 1a88535..b81cac5 100644 --- a/src/main/java/component/Nonce.java +++ b/src/main/java/component/Nonce.java @@ -88,7 +88,7 @@ public class Nonce implements TlvComponentBase,InitialAble, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvNonce))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvNonce))){ return false; } diff --git a/src/main/java/component/Payload.java b/src/main/java/component/Payload.java index d26577a..087bec4 100644 --- a/src/main/java/component/Payload.java +++ b/src/main/java/component/Payload.java @@ -93,7 +93,7 @@ public class Payload implements TlvComponentBase,InitialAble, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvPayload))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvPayload))){ return false; } diff --git a/src/main/java/component/ReadOnlyField.java b/src/main/java/component/ReadOnlyField.java index 78d019c..214f2ef 100644 --- a/src/main/java/component/ReadOnlyField.java +++ b/src/main/java/component/ReadOnlyField.java @@ -99,7 +99,7 @@ public class ReadOnlyField implements TlvComponentBase, IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查 Type 是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvReadOnlyField))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvReadOnlyField))){ return false; } diff --git a/src/main/java/component/TTL.java b/src/main/java/component/TTL.java index 35fe92b..b12b33f 100644 --- a/src/main/java/component/TTL.java +++ b/src/main/java/component/TTL.java @@ -88,7 +88,7 @@ public class TTL implements IEncodingAble { @Override public boolean wireDecode(Block block) { // 检查Type是否正确 - if(!TLV.expectType(block.getTlvType(),new VlInt(TLV.TlvTTL))){ + if(!TLV.expectType(block.getType(),new VlInt(TLV.TlvTTL))){ return false; } long value=TLV.readNonNegativeInteger(block.getValue(),0,block.getLength().getVlIntValue2Int()); diff --git a/src/main/java/encoding/Block.java b/src/main/java/encoding/Block.java index ed95fcc..6cb00ce 100644 --- a/src/main/java/encoding/Block.java +++ b/src/main/java/encoding/Block.java @@ -20,6 +20,10 @@ public class Block { private ElementContainer elements; // TLV-sub-elements private byte[] raw; // TLV编码后的字节数组 + public Block(){ + this.tlvType=new VlInt(TLV.TlvInvalid); + } + /** * 从一个包含TLV的字节数组中构造一个 Block 对象 * @param buffer @@ -27,7 +31,7 @@ public class Block { * 则会对比解析到的 TLV-LENGTH 与 TLV-VALUE的实际长度是否匹配 * @return */ - public Block createBlockByBuffer(byte[] buffer,boolean verifyLength){ + public static Block createBlockByBuffer(byte[] buffer,boolean verifyLength){ if(buffer.length==0){ return null; } @@ -57,7 +61,7 @@ public class Block { * @param verifyLength * @return */ - public Block createBlockByTypeLengthBuffer(VlInt tlvType,VlInt tlvLength,byte[] buffer,boolean verifyLength){ + public static Block createBlockByTypeLengthBuffer(VlInt tlvType,VlInt tlvLength,byte[] buffer,boolean verifyLength){ return new Block(tlvType,tlvLength,buffer,verifyLength); } @@ -103,14 +107,18 @@ public class Block { } public Block(Block block){ - + this.tlvType=block.tlvType; + this.length=block.length; + this.value=block.value; + this.elements=block.elements; + this.raw=block.raw; } - public VlInt getTlvType() { + public VlInt getType() { return tlvType; } - public void setTlvType(VlInt tlvType) { + public void setType(VlInt tlvType) { this.tlvType = tlvType; } diff --git a/src/main/java/encoding/ElementContainer.java b/src/main/java/encoding/ElementContainer.java index c57f682..851ff23 100644 --- a/src/main/java/encoding/ElementContainer.java +++ b/src/main/java/encoding/ElementContainer.java @@ -55,7 +55,7 @@ public class ElementContainer{ public void removeElements(VlInt tlvType){ List elementContainer=new LinkedList<>(); for(Block block: this.elementContainer){ - if(!block.getTlvType().isEqual(tlvType)){ + if(!block.getType().isEqual(tlvType)){ elementContainer.add(block); } } @@ -69,7 +69,7 @@ public class ElementContainer{ */ public Block getElement(VlInt tlvType){ for(Block block: this.elementContainer){ - if(block.getTlvType().isEqual(tlvType)){ + if(block.getType().isEqual(tlvType)){ return block; } } diff --git a/src/main/java/encoding/Encoder.java b/src/main/java/encoding/Encoder.java index 0a2f870..cee4bf6 100644 --- a/src/main/java/encoding/Encoder.java +++ b/src/main/java/encoding/Encoder.java @@ -256,7 +256,7 @@ public class Encoder { * @return */ public int prependBlock(Block block){ - return this.prependByteArrayBlock(block.getTlvType(),block.getValue(),new SizeT(block.getLength())); + return this.prependByteArrayBlock(block.getType(),block.getValue(),new SizeT(block.getLength())); } /** @@ -265,7 +265,7 @@ public class Encoder { * @return */ public int appendBlock(Block block){ - return this.appendByteArrayBlock(block.getTlvType(),block.getValue(),new SizeT(block.getLength())); + return this.appendByteArrayBlock(block.getType(),block.getValue(),new SizeT(block.getLength())); } /** diff --git a/src/main/java/util/ByteHelper.java b/src/main/java/util/ByteHelper.java index 8132d72..2ec0512 100644 --- a/src/main/java/util/ByteHelper.java +++ b/src/main/java/util/ByteHelper.java @@ -12,6 +12,19 @@ import encoding.VlInt; */ public class ByteHelper { + /** + * 获取从start到末尾的字节数组 + * @param buffer + * @param startIndex + * @return + */ + public static byte[] getTailBytes(byte[] buffer,int startIndex){ + int len=buffer.length-startIndex; + byte[] newBytes=new byte[len]; + System.arraycopy(buffer,startIndex,newBytes,0,len); + return newBytes; + } + /** * 从byte[]数组指定开始位置获取第一个字节 * todo: start位置可能是大于int类型的数值 diff --git a/src/main/java/util/StringHelper.java b/src/main/java/util/StringHelper.java new file mode 100644 index 0000000..92470d2 --- /dev/null +++ b/src/main/java/util/StringHelper.java @@ -0,0 +1,40 @@ +package util; + +/* + * @Author: Wang Feng + * @Description: + * @Version: 1.0.0 + * @Date: 11:27 2021/3/10 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class StringHelper { + + /** + * 对字符串实施百分号编码 + * // @Description: + * // 1. 具体编码的定义参见:RFC 3986 section 2 + * // 2. 将除了字母('a'~'z', 'A'~'Z')、数字('0' ~ '9')和指定特殊字符('-', '.', '_', '~') + * // 之外的所有字符都进行百分号编码。 + * // 3. 对字符串中的每个UTF-8字符c(用八位一个字节表示)进行如下规则的编码: + * // a. 首先将一个八位字节分为两个部分,hi = (c % 0xf0) >> 4 ; lo = c % 0xf。hi 和 lo 均为两个字节表示的数字,范围为(0~15) + * // b. 然后分别用 hi 和 lo 作为索引,从 "0123456789ABCDEF" 字符串取指定位置的字符,最后编码的结果如下表示: + * // '%' + "0123456789ABCDEF"[hi] + "0123456789ABCDEF"[lo] + * // c. 相当于每个需要编码的字符都编码成了一个%开头的三个字符表示 + * @param str + * @return + */ + public static String escape(String str){ + return ""; + } + + /** + * 对字符串实施百分号解码 + * @param str + * @return + */ + public static String unescape(String str){ + return ""; + } + + +} diff --git a/src/test/java/others/HumanImpl.java b/src/test/java/others/HumanImpl.java index 4385ccb..b9802a0 100644 --- a/src/test/java/others/HumanImpl.java +++ b/src/test/java/others/HumanImpl.java @@ -19,8 +19,11 @@ public class HumanImpl implements God,Animal { } public static void main(String[] args){ - HumanImpl h=new HumanImpl(); - h.sayHi(); - h.makeWorld(); +// HumanImpl h=new HumanImpl(); +// h.sayHi(); +// h.makeWorld(); + String ss="hello"; + System.out.println(ss.length()); + System.out.println(ss.getBytes().length); } }