Fixed bug in extras segment parsing

This commit is contained in:
2026-03-18 19:01:16 +01:00
parent e9e329ccc1
commit 04166daeee
2 changed files with 95 additions and 43 deletions

View File

@@ -770,8 +770,12 @@ export class Frame implements IFrame {
let commentOffset: number = 0;
let commentBefore: string | undefined = undefined;
// eslint-disable-next-line no-useless-assignment
let match: RegExpMatchArray | null = null;
// Process successive 7-byte data extensions at the start of the comment.
let ext = comment.trimStart();
comment = comment.trimStart();
let ext = comment;
while (ext.length >= 7) {
// We first process the altitude marker, because it may appear anywhere
// in the comment and we want to extract it and its value before
@@ -796,23 +800,25 @@ export class Frame implements IFrame {
type: FieldType.STRING,
name: "altitude marker",
data: new TextEncoder().encode("/A=").buffer,
value: "/A=",
length: 3
},
{
type: FieldType.STRING,
name: "altitude",
data: new TextEncoder().encode(altMatch[1]).buffer,
length: altMatch[1].length,
value: altitude.toFixed(3) + "m"
value: altitude.toFixed(3) + "m",
length: 6
}
];
}
if (altitudeOffset > 0) {
// Splice the comment into "before" and "after" around the altitude token.
commentBefore = comment.substring(0, altitudeOffset).trimEnd();
comment = comment.substring(altitudeOffset + altMatch[0].length).trimStart();
ext = commentBefore + comment; // Update ext to reflect the new comment with altitude token removed
// Reset the comment with the altitude marker removed.
commentBefore = comment.substring(0, altitudeOffset);
comment = comment.substring(altitudeOffset + altMatch[0].length);
ext = commentBefore; // Continue processing extensions in the part of the comment before the altitude marker
commentOffset = 0; // Reset
continue;
}
@@ -824,42 +830,46 @@ export class Frame implements IFrame {
}
// RNGrrrr -> pre-calculated range in miles (4 digits)
if (ext.startsWith("RNG")) {
const r = ext.substring(3, 7);
if (/^\d{4}$/.test(r)) {
extras.range = milesToMeters(parseInt(r, 10)) / 1000.0; // Convert to kilometers
if (withStructure) {
(altitudeOffset !== undefined && commentOffset < altitudeOffset ? beforeFields : fields).push(
{
type: FieldType.STRING,
name: "range marker",
value: "RNG",
length: 3
},
{
type: FieldType.STRING,
name: "range (rrrr)",
length: 4,
value: extras.range.toString() + "km"
}
);
}
// remove range token from ext and advance ext for further parsing
commentOffset += 7;
ext = ext.substring(7).trimStart();
continue;
if ((match = ext.match(/^RNG(\d{4})/))) {
const r = match[1];
extras.range = milesToMeters(parseInt(r, 10)) / 1000.0; // Convert to kilometers
if (withStructure) {
(altitudeOffset !== undefined && commentOffset < altitudeOffset ? beforeFields : fields).push(
{
type: FieldType.STRING,
name: "range marker",
value: "RNG",
length: 3
},
{
type: FieldType.STRING,
name: "range (rrrr)",
length: 4,
value: extras.range.toString() + "km"
}
);
}
// remove range token from ext and advance ext for further parsing
if (commentBefore !== undefined && commentBefore.length > 0) {
commentBefore = commentBefore.substring(7);
ext = commentBefore;
} else {
commentOffset += 7;
ext = ext.substring(7);
}
continue;
}
// PHGphgd
if (!extras.phg && ext.startsWith("PHG")) {
//if (!extras.phg && ext.startsWith("PHG")) {
if (!extras.phg && (match = ext.match(/^PHG([0-9 ])([0-9 ])([0-9 ])([0-9 ])/))) {
// PHGphgd: p = power (0-9 or space), h = height (0-9 or space), g = gain (0-9 or space), d = directivity (0-9 or space)
const p = ext.charAt(3);
const h = ext.charAt(4);
const g = ext.charAt(5);
const d = ext.charAt(6);
const p = match[1];
const h = match[2];
const g = match[3];
const d = match[4];
const pNum = parseInt(p, 10);
const powerWatts = Number.isNaN(pNum) ? undefined : pNum * pNum;
const hIndex = h.charCodeAt(0) - 48;
@@ -1028,7 +1038,6 @@ export class Frame implements IFrame {
}
// remove course/speed token from comment and advance ext for further parsing
comment = comment.substring(7).trimStart();
ext = ext.substring(7).trimStart();
// If there is an 8-byte DF/NRQ following (leading '/'), parse that too
@@ -1068,8 +1077,13 @@ export class Frame implements IFrame {
}
// Export comment with extras fields removed, if any were parsed.
comment = comment.substring(commentOffset).trimStart();
extras.comment = comment;
if (commentOffset > 0 && commentBefore !== undefined && commentBefore.length > 0) {
extras.comment = commentBefore.substring(commentOffset) + comment;
} else if (commentBefore !== undefined && commentBefore.length > 0) {
extras.comment = commentBefore + comment;
} else {
extras.comment = comment;
}
if (withStructure) {
const commentBeforeFields: Field[] = commentBefore
@@ -1095,7 +1109,7 @@ export class Frame implements IFrame {
: [];
// Insert the altitude fields at the correct position in the comment section based on where the altitude token was located in the original comment. If there was no altitude token, put all fields at the start of the comment section.
extras.fields = [...commentBeforeFields, ...beforeFields, ...altitudeFields, ...fields, ...commentFields];
extras.fields = [...beforeFields, ...commentBeforeFields, ...altitudeFields, ...fields, ...commentFields];
}
return extras as Extras;