UNPKG

pdf-lib

Version:

Create and modify PDF files with JavaScript

68 lines (56 loc) 2.41 kB
import { ReparseError } from 'src/core/errors'; import PDFName from 'src/core/objects/PDFName'; import PDFNumber from 'src/core/objects/PDFNumber'; import PDFRawStream from 'src/core/objects/PDFRawStream'; import PDFRef from 'src/core/objects/PDFRef'; import ByteStream from 'src/core/parser/ByteStream'; import PDFObjectParser from 'src/core/parser/PDFObjectParser'; import { waitForTick } from 'src/utils'; class PDFObjectStreamParser extends PDFObjectParser { static forStream = ( rawStream: PDFRawStream, shouldWaitForTick?: () => boolean, ) => new PDFObjectStreamParser(rawStream, shouldWaitForTick); private alreadyParsed: boolean; private readonly shouldWaitForTick: () => boolean; private readonly firstOffset: number; private readonly objectCount: number; constructor(rawStream: PDFRawStream, shouldWaitForTick?: () => boolean) { super(ByteStream.fromPDFRawStream(rawStream), rawStream.dict.context); const { dict } = rawStream; this.alreadyParsed = false; this.shouldWaitForTick = shouldWaitForTick || (() => false); this.firstOffset = dict.lookup(PDFName.of('First'), PDFNumber).asNumber(); this.objectCount = dict.lookup(PDFName.of('N'), PDFNumber).asNumber(); } async parseIntoContext(): Promise<void> { if (this.alreadyParsed) { throw new ReparseError('PDFObjectStreamParser', 'parseIntoContext'); } this.alreadyParsed = true; const offsetsAndObjectNumbers = this.parseOffsetsAndObjectNumbers(); for (let idx = 0, len = offsetsAndObjectNumbers.length; idx < len; idx++) { const { objectNumber, offset } = offsetsAndObjectNumbers[idx]; this.bytes.moveTo(this.firstOffset + offset); const object = this.parseObject(); const ref = PDFRef.of(objectNumber, 0); this.context.assign(ref, object); if (this.shouldWaitForTick()) await waitForTick(); } } private parseOffsetsAndObjectNumbers(): { objectNumber: number; offset: number; }[] { const offsetsAndObjectNumbers = []; for (let idx = 0, len = this.objectCount; idx < len; idx++) { this.skipWhitespaceAndComments(); const objectNumber = this.parseRawInt(); this.skipWhitespaceAndComments(); const offset = this.parseRawInt(); offsetsAndObjectNumbers.push({ objectNumber, offset }); } return offsetsAndObjectNumbers; } } export default PDFObjectStreamParser;