cda8e9b112
Mirror / push (push) Has been cancelled
Test / lint (pull_request) Successful in 22s
Test / test (18) (pull_request) Successful in 31s
Test / test (22) (pull_request) Successful in 39s
Test / test (24) (pull_request) Successful in 31s
Test / test (26) (pull_request) Successful in 31s
Test / test (20) (pull_request) Successful in 36s
50 lines
1.6 KiB
TypeScript
50 lines
1.6 KiB
TypeScript
import type { ParamValue } from './defs/types.ts';
|
|
import type { PduObject } from './pdu.ts';
|
|
import { tlvOctets } from './defs/types.ts';
|
|
|
|
/** Wire reads hand back views, so retaining one PDU would pin the whole chunk it arrived in. */
|
|
export function detach(pduObj: PduObject): PduObject {
|
|
const params: Record<string, ParamValue> = {};
|
|
|
|
for (const [name, value] of Object.entries(pduObj.params)) {
|
|
params[name] = Buffer.isBuffer(value) ? Buffer.from(value) : value;
|
|
}
|
|
|
|
// short_message holds the same octets wherever it was not decoded, so one copy covers both.
|
|
const octets = Buffer.isBuffer(params.short_message)
|
|
? params.short_message
|
|
: pduObj.shortMessageOctets && Buffer.from(pduObj.shortMessageOctets);
|
|
|
|
return { ...pduObj, params, shortMessageOctets: octets };
|
|
}
|
|
|
|
// Measured heap beyond the octets, so a PDU of empty fields or empty TLVs is not free.
|
|
const pduObjectOverhead = 1000;
|
|
const tlvObjectOverhead = 300;
|
|
|
|
// A cstring param arrives as a string, and source_addr alone can carry most of a 1 MiB PDU.
|
|
function sizeOf(value: ParamValue): number {
|
|
if (Buffer.isBuffer(value)) return value.length;
|
|
|
|
return typeof value === 'string' ? value.length : 0;
|
|
}
|
|
|
|
/** Roughly the heap a detached PDU holds. */
|
|
export function retainedOctets(pduObj: PduObject): number {
|
|
let octets = pduObjectOverhead;
|
|
|
|
for (const value of Object.values(pduObj.params)) {
|
|
octets += sizeOf(value);
|
|
}
|
|
|
|
for (const tlv of Object.values(pduObj.tlvs)) {
|
|
if (tlv === undefined) continue;
|
|
|
|
const listed = Array.isArray(tlv.tagValue) ? tlv.tagValue.length : 0;
|
|
|
|
octets += tlvOctets(tlv.tagValue) + (1 + listed) * tlvObjectOverhead;
|
|
}
|
|
|
|
return octets;
|
|
}
|