package component; /* * @Author: Wang Feng * @Description: 名称组件 * todo: toUri()函数待完善 * @Version: 1.0.0 * @Date: 21:26 2021/3/9 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ import encoding.*; import util.ByteHelper; import util.ByteHelperException; import util.StringHelper; // @Description: // 1. 参考 => https://named-data.net/doc/tech-memos/naming-conventions.pdf ,借鉴但不是按这个实现的 // 2. 格式如下: // IdentifierComponent = 100 TLV-LENGTH // // *OCTET // Marker = OCTET // 3. Marker 用来标记不同类型的 IdentifierComponent,目前分配如下 // Marker value Description // 0x00 普通的UTF-8编码的字符串 // 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 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[0]; try { value = new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; } catch (VlIntException e) { e.printStackTrace(); } 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[0]; try { value = new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; } catch (VlIntException e) { e.printStackTrace(); } 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[0]; try { value = new byte[this.identifierBlock.getLength().getVlIntValue2Int()]; } catch (VlIntException e) { e.printStackTrace(); } 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 IdentifierComponent(Block block){ try { this.wireDecode(block); } catch (VlIntException e) { throw new Error("IdentifierComponent: wireDecode error. "+e.getMessage()); } } /** * 以字符串形式获取本 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) throws EncoderException { return this.identifierBlock.encode(encoder); } /** * 线速解码,将TLV Block解码成 IdentifierComponent * @param block * @return */ @Override public boolean wireDecode(Block block) throws VlIntException { this.identifierBlock=new Block(block); //todo:越界问题 int length= 0; 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= new byte[0]; try { v = ByteHelper.getTailBytes(value,1); } catch (ByteHelperException e) { e.printStackTrace(); } 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)); } } }