@ndn/tlv
This package is part of NDNts, Named Data Networking libraries for the modern web.
This package implements Type-Length-Value structure encoder and decoder as specified in NDN Packet Format v0.3.
It has full support for TLV evolvability guidelines.
import { Encoder, Decoder, EvDecoder, NNI } from "@ndn/tlv";
import { Name, TT as nameTT } from "@ndn/packet";
import { strict as assert } from "assert";
Encoder
The Encoder has an internal buffer of Uint8Array
type.
It prepends any encodable items to the internal buffer, and reallocates a larger buffer when necessary.
let encoder = new Encoder();
encoder.encode(new Name("/A"));
assert.deepEqual(encoder.output, Uint8Array.of(0x07, 0x03, 0x08, 0x01, 0x41));
encoder = new Encoder();
encoder.encode([0xB0, Uint8Array.of(0xC0, 0xC1)]);
assert.deepEqual(encoder.output, Uint8Array.of(0xB0, 0x02, 0xC0, 0xC1));
encoder.encode(NNI(0x200110));
assert.deepEqual(encoder.output, Uint8Array.of(0x00, 0x20, 0x01, 0x10, 0xB0, 0x02, 0xC0, 0xC1));
encoder = new Encoder();
encoder.encode([0xB0, Uint8Array.of(0xC0, 0xC1), new Name("/A")]);
assert.deepEqual(encoder.output,
Uint8Array.of(0xB0, 0x07, 0xC0, 0xC1, 0x07, 0x03, 0x08, 0x01, 0x41));
Decoder
The Decoder is a basic sequential decoder.
let decoder = new Decoder(Uint8Array.of(0x08, 0x01, 0x41, 0xFF));
const { type, length, value } = decoder.read();
assert.equal(type, 0x08);
assert.equal(length, 1);
assert.deepEqual(value, Uint8Array.of(0x41));
assert.throws(() => decoder.read());
decoder = new Decoder(Uint8Array.of(0x07, 0x03, 0x08, 0x01, 0x41));
const name = decoder.decode(Name);
assert(name instanceof Name);
assert.equal(name.toString(), "/A");
EvDecoder
The EvDecoder is a decoder that is aware of TLV evolvability guidelines.
It's used to implement decoding functions of TLV objects, such as Interest.decodeFrom
.
Suppose we want to decode NLSR's LSDB Dataset:
Adjacency = ADJACENCY-TYPE TLV-LENGTH
Name
Uri
Cost
Uri = URI-TYPE TLV-LENGTH *VCHAR
Cost = COST-TYPE TLV-LENGTH nonNegativeInteger
ADJACENCY-TYPE = 0x84
URI-TYPE = 0x8D
COST-TYPE = 0x8C
class Adjacency {
public name: Name = new Name();
public uri: string = "";
public cost: number = 0;
}
const TT = {
...nameTT,
Adjacency: 0x84,
Cost: 0x8C,
Uri: 0x8D,
};
const EVD = new EvDecoder<Adjacency>("Adjacency", TT.Adjacency)
.add(TT.Name, (t, { decoder }) => t.name = decoder.decode(Name))
.add(TT.Uri, (t, { value }) => t.uri = new TextDecoder().decode(value))
.add(TT.Cost, (t, { nni }) => t.cost = nni);
const adjacencyWire = Uint8Array.of(
0x84, 0x0D,
0x07, 0x03, 0x08, 0x01, 0x41,
0x8D, 0x01, 0x42,
0xF0, 0x00,
0x8C, 0x01, 0x80,
);
const adjacencyDecoder = new Decoder(adjacencyWire);
const adjacency = EVD.decode(new Adjacency(), adjacencyDecoder);
assert.equal(adjacency.name.toString(), "/A");
assert.equal(adjacency.uri, "B");
assert.equal(adjacency.cost, 128);