parser = $parser; $this->read(); } /** * Extract all information from the pdf stream. * * @throws CrossReferenceException * @throws PdfTypeException */ protected function read() { $start = 0; $bufferLen = 20; $stream = $this->parser->getStreamReader(); $stream->reset($start, $bufferLen); $delemitters = preg_quote("\x00\x09\x0A\x0C\x0D\x20()<>[]", '/'); $regex = '/(\d+)[' . $delemitters . ']+(\d+)[' . $delemitters . ']+obj/U'; while (($buffer = $stream->getBuffer()) !== '') { \preg_match($regex, $buffer, $match, PREG_OFFSET_CAPTURE); $lastFound = 0; if (\count($match) > 0) { $objectNumber = $match[1][0]; $lastFound = $match[0][1]; $this->offsets[$objectNumber] = $start + $lastFound; } if (false !== ($pos = \strpos($buffer, 'trailer'))) { $stream->reset($start + $pos + 7); if (!isset($this->trailer)) { $this->trailer = PdfDictionary::create(); } $this->parser->getTokenizer()->clearStack(); $trailer = $this->parser->readValue(); foreach ($trailer->value as $key => $value) { if ($key === 'Prev') { continue; } $this->trailer->value[$key] = $value; } } $start += $lastFound + ($bufferLen / 2); $stream->reset($start, $bufferLen); } if (!isset($this->trailer)) { throw new CrossReferenceException( 'No trailer found.', CrossReferenceException::NO_TRAILER_FOUND ); } } /** * Get an offset by an object number. * * @param int $objectNumber * @return int|bool False if the offset was not found. */ public function getOffsetFor($objectNumber) { if (isset($this->offsets[$objectNumber])) { return $this->offsets[$objectNumber]; } return false; } /** * Get the trailer related to this cross reference. * * @return PdfDictionary */ public function getTrailer() { return $this->trailer; } }