/** * * @param int $offset * @return PdfIndirectObject * @throws PdfException */ protected function parseObjectFromOffset($offset) { $matches = array(); $object = array(); $this->stream->seek($offset); // assert "<x> <y> obj" if (false === $this->stream->consume([['/[0-9]/', '+'], ['/\\s/', '+'], ['/[0-9]/', '+'], ['/\\s/', '+'], 'obj', ['/[^a-z]/']], $matches)) { throw new PdfException('No object at ' . $offset); } $this->stream->seek(-1, SEEK_CUR); $object['id'] = (int) $matches[0]; $object['revision'] = (int) $matches[2]; // Load PDF object list($endPos, $value) = $this->objectParser->getNextObjectFromString($this->source, $this->stream->tell()); $this->stream->seek($endPos); // Assert key word if (false === $this->stream->consume([['/\\s/', '*'], ['/[a-z]/', '+'], ['/[^a-z]/']], $matches)) { throw new PdfException('No key word found at ' . $this->stream->tell()); } $this->stream->seek(-1, SEEK_CUR); $keyWord = $matches[1]; switch ($keyWord) { case 'stream': if (!$value instanceof PdfDictionary) { throw new PdfException('Value has to be a dictionary'); } $this->stream->push(); $length = $this->resolveRef($value->get('/Length')); $this->stream->pop(); $chars = $this->stream->read(2); if ($chars === "\r\n") { // nop } elseif ($chars[0] === "\n") { $this->stream->seek(-1, SEEK_CUR); } else { throw new PdfException('Expected \\n or \\r\\n after stream key word'); } $value = new PdfStreamObject($value, $this->stream->tell(), $length); $this->stream->seek($length, SEEK_CUR); // Assert "endstream" if (!$this->stream->consume([['/\\s/', '*'], 'endstream'])) { throw new PdfException('Expected endstream key word'); } // Assert "endobj" if (!$this->stream->consume([['/\\s/', '*'], 'endobj'])) { throw new PdfException('Expected endobj key word'); } break; case 'endobj': // nop break; default: throw new PdfException('Unexpected key word ' . $keyWord); break; } $object['value'] = $value; return new PdfIndirectObject($object['id'], $object['revision'], $object['value']); }
/** * * @param PdfStream $stream * @return PdfDictionary * @throws PdfException */ protected function parseTrailer(PdfStream $stream) { if (trim($stream->gets()) !== 'trailer') { throw new PdfException('trailer expected'); } list(, $object) = $this->objectParser->getNextObjectFromString($stream->getContents(), 0); if (!$object instanceof PdfDictionary) { throw new PdfException('No dictionary found in trailer'); } return $object; }