Count and detach a repeatable TLV's occurrences in reassembly, and let only byte or integer tags repeat
Mirror / push (push) Successful in 4s
Test / lint (pull_request) Successful in 21s
Test / test (18) (pull_request) Successful in 29s
Test / test (20) (pull_request) Successful in 30s
Test / test (22) (pull_request) Successful in 35s
Test / test (24) (pull_request) Successful in 30s
Test / test (26) (pull_request) Successful in 29s
Mirror / push (push) Successful in 4s
Test / lint (pull_request) Successful in 21s
Test / test (18) (pull_request) Successful in 29s
Test / test (20) (pull_request) Successful in 30s
Test / test (22) (pull_request) Successful in 35s
Test / test (24) (pull_request) Successful in 30s
Test / test (26) (pull_request) Successful in 29s
This commit is contained in:
+2
-59
@@ -1,6 +1,6 @@
|
||||
import type { CommandDefinition, CommandName, PduParams, PduParamsInput } from './defs/commands.ts';
|
||||
import type { ErrorName } from './defs/errors.ts';
|
||||
import type { ParamValue, TlvValue } from './defs/types.ts';
|
||||
import type { ParamValue } from './defs/types.ts';
|
||||
import type { PduHeader } from './pdu-refusal.ts';
|
||||
import type { Result, VoidResult } from './result.ts';
|
||||
import type { Tlv, TlvInput } from './defs/tlvs.ts';
|
||||
@@ -10,7 +10,7 @@ import { hasUdh } from './defs/constants.ts';
|
||||
import { decodeMessage, encodeBody } from './message.ts';
|
||||
import { errorNameById, errors, isErrorName } from './defs/errors.ts';
|
||||
import { paramNumber, valueText } from './defs/types.ts';
|
||||
import { tagIdOf, tlvDefault, tlvs, tlvsById, writeTlvs } from './defs/tlvs.ts';
|
||||
import { parseTlvs, tagIdOf, tlvs, writeTlvs } from './defs/tlvs.ts';
|
||||
|
||||
/** The highest sequence number this library hands out; SMPP 3.4 4.7.1 reserves 0x7fffffff. */
|
||||
export const maxSeqNr = 2147483646;
|
||||
@@ -262,63 +262,6 @@ export function objToPdu<C extends CommandName>(obj: PduObjectInput<C>): Result<
|
||||
);
|
||||
}
|
||||
|
||||
type Repeats = { buffers: Map<string, Buffer[]>; numbers: Map<string, number[]> };
|
||||
|
||||
/** A repeatable tag's occurrences so far, `value` appended; a value no TLV type reads is undefined. */
|
||||
function tlvValue(value: ParamValue, key: string, multiple: boolean | undefined, repeats: Repeats): TlvValue | undefined {
|
||||
if (Buffer.isBuffer(value)) return multiple === true ? appended(repeats.buffers, key, value) : value;
|
||||
if (typeof value === 'number') return multiple === true ? appended(repeats.numbers, key, value) : value;
|
||||
if (typeof value === 'string' && multiple !== true) return value;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function appended<T>(lists: Map<string, T[]>, key: string, value: T): T[] {
|
||||
const list = lists.get(key) ?? [];
|
||||
|
||||
list.push(value);
|
||||
lists.set(key, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function readTlv(pdu: Buffer, offset: number, repeats: Repeats): Result<{ key: string; octets: number; tlv: Tlv }> {
|
||||
const tagId = pdu.readUInt16BE(offset);
|
||||
const tagLength = pdu.readUInt16BE(offset + 2);
|
||||
|
||||
if (offset + 4 + tagLength > pdu.length) {
|
||||
return { err: new Error(`TLV ${String(tagId)} runs past the end of the PDU`) };
|
||||
}
|
||||
|
||||
const definition = tlvsById[tagId];
|
||||
const read = (definition?.type ?? tlvDefault).read(pdu, offset + 4, tagLength);
|
||||
|
||||
if (read.err) return { err: read.err };
|
||||
|
||||
const key = definition?.tag ?? tagId.toString();
|
||||
const tagValue = tlvValue(read.value, key, definition?.multiple, repeats);
|
||||
|
||||
if (tagValue === undefined) return { err: new Error(`TLV ${String(tagId)} read as a value no TLV holds`) };
|
||||
|
||||
return { key, octets: 4 + tagLength, tlv: { tagId, tagName: definition?.tag, tagValue } };
|
||||
}
|
||||
|
||||
function parseTlvs(pdu: Buffer, start: number): Result<{ offset: number; tlvs: Record<string, Tlv> }> {
|
||||
const repeats: Repeats = { buffers: new Map(), numbers: new Map() };
|
||||
const tlvs: Record<string, Tlv> = {};
|
||||
let offset = start;
|
||||
|
||||
while (offset + 4 <= pdu.length) {
|
||||
const read = readTlv(pdu, offset, repeats);
|
||||
|
||||
if (read.err) return { err: read.err };
|
||||
|
||||
tlvs[read.key] = read.tlv;
|
||||
offset += read.octets;
|
||||
}
|
||||
|
||||
return { offset, tlvs };
|
||||
}
|
||||
|
||||
function readParams(
|
||||
cmdName: CommandName,
|
||||
|
||||
Reference in New Issue
Block a user