UNPKG

@ndn/lp

Version:
90 lines (89 loc) 2.71 kB
import { concatBuffers, evict } from "@ndn/util"; import { LpPacket } from "./packet_node.js"; class PartialPacket { seqNumBase; constructor(seqNumBase) { this.seqNumBase = seqNumBase; } buffer = []; accepted = 0; payloadLength = 0; accept(fragment) { if (this.accepted === 0) { // first this.buffer.length = fragment.fragCount; this.acceptOne(fragment); return undefined; } if (fragment.fragCount !== this.buffer.length) { // mismatch return false; } if (this.buffer[fragment.fragIndex]) { // duplicate return undefined; } this.acceptOne(fragment); if (this.accepted === this.buffer.length) { return this.reassemble(); } return undefined; } acceptOne(fragment) { this.buffer[fragment.fragIndex] = fragment; ++this.accepted; this.payloadLength += fragment.payload?.length ?? 0; } reassemble() { const full = Object.assign(new LpPacket(), this.buffer[0].l3); const parts = []; for (const fragment of this.buffer) { const part = fragment.payload; if (part) { parts.push(part); } } full.payload = concatBuffers(parts, this.payloadLength); return full; } } /** NDNLPv2 reassembler. */ export class Reassembler { capacity; constructor(capacity) { this.capacity = capacity; } partials = new Map(); /** * Process a fragment. * @returns Fully reassembled packet, or undefined if packet is not yet complete. */ accept(fragment) { if (fragment.fragCount === 1) { // not fragmented return fragment; } if (fragment.fragSeqNum === undefined || fragment.fragIndex >= fragment.fragCount) { // bad fragment return undefined; } const seqNumBase = BigInt.asUintN(64, fragment.fragSeqNum - BigInt(fragment.fragIndex)); const partial = this.getPartial(seqNumBase); const result = partial.accept(fragment); if (result) { return result; } if (result !== false) { this.putPartial(partial); } return undefined; } getPartial(seqNumBase) { const partial = this.partials.get(seqNumBase); if (partial) { this.partials.delete(seqNumBase); return partial; } return new PartialPacket(seqNumBase); } putPartial(partial) { this.partials.set(partial.seqNumBase, partial); evict(this.capacity, this.partials); } }