endByteOffsetInDecodedStream !== null && $this->startByteOffsetInDecodedStream > $this->endByteOffsetInDecodedStream) { throw new InvalidArgumentException(sprintf('Start offset %d should be before end offset %d', $this->startByteOffsetInDecodedStream, $this->endByteOffsetInDecodedStream)); } } #[Override] public function getDictionary(Document $document): Dictionary { if (isset($this->dictionary)) { return $this->dictionary; } $objectContent = trim($this->getContent($document)->toString()); if ($objectContent === '' || !str_starts_with($objectContent, '<<') || !str_ends_with($objectContent, '>>')) { return $this->dictionary = new Dictionary(); } $inMemoryStream = new InMemoryStream($objectContent); return $this->dictionary = DictionaryParser::parse($inMemoryStream, 0, $inMemoryStream->getSizeInBytes()); } #[Override] public function getContent(Document $document): Stream { $first = $this->storedInObject->getDictionary($document)->getValueForKey(DictionaryKey::FIRST, IntegerValue::class) ?? throw new RuntimeException('Expected a dictionary entry for "First", none found'); $content = substr( $this->storedInObject->getContent($document)->toString(), $first->value + $this->startByteOffsetInDecodedStream, $this->endByteOffsetInDecodedStream !== null ? $this->endByteOffsetInDecodedStream - $this->startByteOffsetInDecodedStream : null ); if (str_starts_with($content, '[') && str_ends_with($content, ']') && ($referenceValueArray = ReferenceValueArray::fromValue($content)) !== null) { $content = implode( '', array_map( fn (ReferenceValue $referenceValue) => ($document->getObject($referenceValue->objectNumber) ?? throw new ParseFailureException()) ->getStream() ->toString(), $referenceValueArray->referenceValues, ) ); } return FileStream::fromString($content); } }