Skip to content

Commit 2e4ca26

Browse files
committed
migration
1 parent 6e70718 commit 2e4ca26

1 file changed

Lines changed: 54 additions & 37 deletions

File tree

src/processors/nuvoice/helpers.ts

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,14 @@ function parseMemoryRecord(line: string): NuVoiceMemoryRecord {
580580
throw new Error(`Invalid NuVoice memory record: ${line}`);
581581
}
582582

583-
const markerLength = 4;
584-
const pageBytes = base.bodyBytes.slice(1, 3);
585-
const sequence = base.bodyBytes[3];
586-
const payloadBytes = base.bodyBytes.slice(markerLength);
587-
const parsedButton = parseNuVoiceButtonPayload(base.bodyBytes);
583+
const fullBytes = new Uint8Array(base.bodyBytes.length + 1);
584+
fullBytes[0] = 0x6d;
585+
fullBytes.set(base.bodyBytes, 1);
586+
587+
const pageBytes = fullBytes.slice(4, 6);
588+
const sequence = fullBytes[6];
589+
const payloadBytes = base.bodyBytes.slice(6);
590+
const parsedButton = parseNuVoiceButtonPayload(fullBytes);
588591
return {
589592
...base,
590593
type: 'm',
@@ -611,40 +614,42 @@ function textFromRecordBody(type: string, bodyBytes: Uint8Array): string | undef
611614
return `${type}${bytesToLatin1(bodyBytes)}`;
612615
}
613616

614-
function parseNuVoiceButtonPayload(bodyBytes: Uint8Array): NuVoiceButtonData | undefined {
615-
if (bodyBytes.length < 14) {
617+
function parseNuVoiceButtonPayload(fullBytes: Uint8Array): NuVoiceButtonData | undefined {
618+
if (fullBytes.length < 14 || fullBytes[0] !== 0x6d) {
616619
return undefined;
617620
}
618-
const formatMarker = bodyBytes[9];
621+
const formatMarker = fullBytes[9];
619622
if (formatMarker >= 1 && formatMarker <= 49) {
620-
return parseNuVoiceFormat1(bodyBytes, formatMarker);
623+
return parseNuVoiceFormat1(fullBytes, formatMarker);
621624
}
622625
if (formatMarker === 0) {
623-
return parseNuVoiceFormat2(bodyBytes);
626+
return parseNuVoiceFormat2(fullBytes);
624627
}
625-
if ([0x87, 0xaf, 0xcc, 0xff, 0xf5, 0xf0].includes(formatMarker)) {
626-
return parseNuVoiceFormat5(bodyBytes);
628+
if ([0x87, 0xaf, 0xcc, 0xff].includes(formatMarker)) {
629+
return parseNuVoiceFormat5(fullBytes);
627630
}
628631
return undefined;
629632
}
630633

631-
function parseNuVoiceFormat1(bodyBytes: Uint8Array, nameLength: number): NuVoiceButtonData {
634+
function parseNuVoiceFormat1(fullBytes: Uint8Array, nameLength: number): NuVoiceButtonData {
632635
let cursor = 10;
633-
const end = Math.min(cursor + nameLength, bodyBytes.length);
634-
const name = bytesToLatin1(bodyBytes.slice(cursor, end)).trim();
636+
const end = Math.min(cursor + nameLength, fullBytes.length);
637+
const name = bytesToLatin1(fullBytes.slice(cursor, end)).trim();
635638
cursor = end;
636-
if (cursor < bodyBytes.length && bodyBytes[cursor] === 0) {
639+
if (cursor < fullBytes.length && fullBytes[cursor] === 0) {
637640
cursor += 1;
638641
}
639-
let icon = undefined;
640-
if (cursor < bodyBytes.length) {
641-
const iconLength = bodyBytes[cursor];
642+
let icon: string | undefined;
643+
if (cursor < fullBytes.length) {
644+
const iconLength = fullBytes[cursor];
642645
cursor += 1;
643-
icon = bytesToLatin1(bodyBytes.slice(cursor, cursor + iconLength)).trim();
644-
cursor += iconLength;
646+
if (iconLength > 0 && cursor + iconLength <= fullBytes.length) {
647+
icon = bytesToLatin1(fullBytes.slice(cursor, cursor + iconLength)).trim();
648+
cursor += iconLength;
649+
}
645650
}
646651
const { speech, navigationType, navigationTarget, functions, randomChoiceTarget } =
647-
parseNuVoiceFunctions(bodyBytes.slice(cursor));
652+
parseNuVoiceFunctions(fullBytes.slice(cursor));
648653
return {
649654
name,
650655
icon,
@@ -656,32 +661,44 @@ function parseNuVoiceFormat1(bodyBytes: Uint8Array, nameLength: number): NuVoice
656661
};
657662
}
658663

659-
function parseNuVoiceFormat2(bodyBytes: Uint8Array): NuVoiceButtonData {
660-
let text = bytesToLatin1(bodyBytes.slice(11));
661-
while (text.endsWith('\u0000')) {
662-
text = text.slice(0, -1);
664+
function parseNuVoiceFormat2(fullBytes: Uint8Array): NuVoiceButtonData {
665+
let cursor = 10;
666+
while (cursor < fullBytes.length && fullBytes[cursor] === 0) {
667+
cursor += 1;
668+
}
669+
let end = cursor;
670+
while (end + 1 < fullBytes.length) {
671+
if (fullBytes[end] === 0x0d && fullBytes[end + 1] === 0x0a) {
672+
break;
673+
}
674+
end += 1;
663675
}
664-
text = text.trim();
676+
let textBytes = fullBytes.slice(cursor, end);
677+
textBytes = textBytes.filter((value) => value >= 0x20);
678+
const text = bytesToLatin1(textBytes).trim();
665679
return { name: text, speech: text, functions: [] };
666680
}
667681

668-
function parseNuVoiceFormat5(bodyBytes: Uint8Array): NuVoiceButtonData | undefined {
669-
if (bodyBytes.length < 14) {
682+
function parseNuVoiceFormat5(fullBytes: Uint8Array): NuVoiceButtonData | undefined {
683+
if (fullBytes.length < 14) {
670684
return undefined;
671685
}
672-
const nameLength = bodyBytes[13];
686+
const nameLength = fullBytes[13];
673687
let cursor = 14;
674-
const name = bytesToLatin1(bodyBytes.slice(cursor, cursor + nameLength)).trim();
688+
const name = bytesToLatin1(fullBytes.slice(cursor, cursor + nameLength)).trim();
675689
cursor += nameLength;
676-
if (cursor < bodyBytes.length && bodyBytes[cursor] === 0) {
690+
if (cursor < fullBytes.length && fullBytes[cursor] === 0) {
677691
cursor += 1;
678692
}
679-
const iconLength = bodyBytes[cursor] ?? 0;
680-
cursor += 1;
681-
const icon = bytesToLatin1(bodyBytes.slice(cursor, cursor + iconLength)).trim();
682-
cursor += iconLength;
693+
let icon: string | undefined;
694+
if (cursor < fullBytes.length) {
695+
const iconLength = fullBytes[cursor] ?? 0;
696+
cursor += 1;
697+
icon = bytesToLatin1(fullBytes.slice(cursor, cursor + iconLength)).trim();
698+
cursor += iconLength;
699+
}
683700
const { speech, navigationType, navigationTarget, functions, randomChoiceTarget } =
684-
parseNuVoiceFunctions(bodyBytes.slice(cursor));
701+
parseNuVoiceFunctions(fullBytes.slice(cursor));
685702
return {
686703
name,
687704
icon,

0 commit comments

Comments
 (0)