|
|
|
@ -20,7 +20,7 @@ export class MonoDisplayParser { |
|
|
|
|
|
|
|
|
|
|
|
// File header (12 bytes)
|
|
|
|
// File header (12 bytes)
|
|
|
|
const magic = r.readUint32(); |
|
|
|
const magic = r.readUint32(); |
|
|
|
if (magic !== MONOFORMAT_MAGIC_HEADER) throw new Error(`Bad magic 0x${magic.toString(16)} — expected 0x632B7EAF`); |
|
|
|
if (magic !== MONOFORMAT_MAGIC_HEADER) throw new Error(`Bad magic 0x${magic.toString(16)} - expected 0x632B7EAF`); |
|
|
|
|
|
|
|
|
|
|
|
const version = r.readUint32(); |
|
|
|
const version = r.readUint32(); |
|
|
|
if (version === 0 || version > 1) throw new Error(`Unsupported version ${version}`); |
|
|
|
if (version === 0 || version > 1) throw new Error(`Unsupported version ${version}`); |
|
|
|
@ -36,18 +36,19 @@ export class MonoDisplayParser { |
|
|
|
const sectionStart = r.offset; // start of section DATA
|
|
|
|
const sectionStart = r.offset; // start of section DATA
|
|
|
|
const dataSize = sectionSize - 4; |
|
|
|
const dataSize = sectionSize - 4; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sectionEnd = sectionStart + dataSize; |
|
|
|
switch (sectionType) { |
|
|
|
switch (sectionType) { |
|
|
|
case SectionType.ElementsAlways: |
|
|
|
case SectionType.ElementsAlways: |
|
|
|
sections.push(this.#parseElementsSection(r, SectionType.ElementsAlways, false)); |
|
|
|
sections.push(this.#parseElementsSection(r, SectionType.ElementsAlways, false, sectionEnd)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case SectionType.ElementsTimespan: |
|
|
|
case SectionType.ElementsTimespan: |
|
|
|
sections.push(this.#parseElementsSection(r, SectionType.ElementsTimespan, true)); |
|
|
|
sections.push(this.#parseElementsSection(r, SectionType.ElementsTimespan, true, sectionEnd)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case SectionType.CustomFont: |
|
|
|
case SectionType.CustomFont: |
|
|
|
sections.push(this.#parseCustomFont(r, dataSize)); |
|
|
|
sections.push(this.#parseCustomFont(r, dataSize)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
// Unknown — skip
|
|
|
|
// Unknown - skip
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -70,6 +71,7 @@ export class MonoDisplayParser { |
|
|
|
r: BinaryReader, |
|
|
|
r: BinaryReader, |
|
|
|
type: SectionType.ElementsAlways | SectionType.ElementsTimespan, |
|
|
|
type: SectionType.ElementsAlways | SectionType.ElementsTimespan, |
|
|
|
hasTimestamp: boolean, |
|
|
|
hasTimestamp: boolean, |
|
|
|
|
|
|
|
sectionEnd: number, |
|
|
|
): MonoFormatElementsAlways | MonoFormatElementsTimespan { |
|
|
|
): MonoFormatElementsAlways | MonoFormatElementsTimespan { |
|
|
|
const flags = this.#parseFlags(r.readUint16()); |
|
|
|
const flags = this.#parseFlags(r.readUint16()); |
|
|
|
const numElements = r.readUint16(); |
|
|
|
const numElements = r.readUint16(); |
|
|
|
@ -82,8 +84,11 @@ export class MonoDisplayParser { |
|
|
|
|
|
|
|
|
|
|
|
const elements: MonoFormatElement[] = []; |
|
|
|
const elements: MonoFormatElement[] = []; |
|
|
|
for (let i = 0; i < numElements; i++) { |
|
|
|
for (let i = 0; i < numElements; i++) { |
|
|
|
|
|
|
|
// Stop if fewer than 2 bytes remain in section (can't read element type)
|
|
|
|
|
|
|
|
if (r.offset + 2 > sectionEnd) break; |
|
|
|
const el = this.#parseElement(r); |
|
|
|
const el = this.#parseElement(r); |
|
|
|
if (el) elements.push(el); |
|
|
|
if (el === null) break; // unknown type - can't determine size, stop
|
|
|
|
|
|
|
|
elements.push(el); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (hasTimestamp) { |
|
|
|
if (hasTimestamp) { |
|
|
|
@ -112,7 +117,7 @@ export class MonoDisplayParser { |
|
|
|
case ElementType.ClippedText: return this.#parseClippedText(r, elementStart); |
|
|
|
case ElementType.ClippedText: return this.#parseClippedText(r, elementStart); |
|
|
|
case ElementType.HScrollText: return this.#parseHScrollText(r, elementStart); |
|
|
|
case ElementType.HScrollText: return this.#parseHScrollText(r, elementStart); |
|
|
|
default: |
|
|
|
default: |
|
|
|
// Unknown element type — cannot safely skip without knowing size; stop parsing section elements
|
|
|
|
// Unknown element type - cannot safely skip without knowing size; stop parsing section elements
|
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|