(firstToken: Token & { type: "number" })
| 168 | } |
| 169 | |
| 170 | private parseNumberOrRef(firstToken: Token & { type: "number" }): ParseResult { |
| 171 | const firstNum = firstToken.value; |
| 172 | |
| 173 | // Check for indirect reference pattern: int int R |
| 174 | // buf1 = first number (already read), buf2 = potential second number |
| 175 | if (!firstToken.isInteger) { |
| 176 | this.shift(); |
| 177 | return { object: PdfNumber.of(firstNum), hasStream: false }; |
| 178 | } |
| 179 | |
| 180 | // First number is integer, check if buf2 is also integer |
| 181 | if (this.buf2 === null || this.buf2.type !== "number" || !this.buf2.isInteger) { |
| 182 | this.shift(); |
| 183 | return { object: PdfNumber.of(firstNum), hasStream: false }; |
| 184 | } |
| 185 | |
| 186 | const secondNum = this.buf2.value; |
| 187 | |
| 188 | // Shift so buf1 = second number, buf2 = potential "R" |
| 189 | this.shift(); |
| 190 | |
| 191 | // Now check if buf2 is "R" |
| 192 | const potentialR = this.lookahead(); |
| 193 | if (potentialR !== null && potentialR.type === "keyword" && potentialR.value === "R") { |
| 194 | // It's a reference! Validate and consume. |
| 195 | return this.parseReference(firstNum, secondNum); |
| 196 | } |
| 197 | |
| 198 | // Not a reference - just the first number |
| 199 | // But we've already shifted past it! We need to return it |
| 200 | // and leave buf1 (second number) for next parse. |
| 201 | return { object: PdfNumber.of(firstNum), hasStream: false }; |
| 202 | } |
| 203 | |
| 204 | private parseReference(objNum: number, genNum: number): ParseResult { |
| 205 | // Validate reference values |
no test coverage detected