firstPos(Marker::TRAILER, $startPos, $startPos + $nrOfBytes) ?? throw new ParseFailureException('Unable to locate trailer for crossReferenceTable'); $dictionary = DictionaryParser::parse($stream, $startTrailerPos + Marker::TRAILER->length(), $nrOfBytes - ($startTrailerPos + Marker::TRAILER->length() - $startPos)); $firstObjectNumber = $nrOfEntries = null; $crossReferenceSubSections = $crossReferenceEntries = []; $content = trim($stream->read($startPos, $startTrailerPos - $startPos)); $content = str_replace([WhitespaceCharacter::CARRIAGE_RETURN->value, WhitespaceCharacter::LINE_FEED->value . WhitespaceCharacter::LINE_FEED->value], WhitespaceCharacter::LINE_FEED->value, $content); foreach (explode(WhitespaceCharacter::LINE_FEED->value, $content) as $line) { $sections = explode(WhitespaceCharacter::SPACE->value, trim($line)); switch (count($sections)) { case 2: if ($firstObjectNumber !== null && $nrOfEntries !== null) { $crossReferenceSubSections[] = new CrossReferenceSubSection($firstObjectNumber, $nrOfEntries, ... $crossReferenceEntries); // Use previous objectNr and nrOfEntries } $crossReferenceEntries = []; $firstObjectNumber = (int) $sections[0]; $nrOfEntries = (int) $sections[1]; break; case 3: $crossReferenceEntries[] = match (CrossReferenceTableInUseOrFree::tryFrom(trim($sections[2]))) { CrossReferenceTableInUseOrFree::IN_USE => new CrossReferenceEntryInUseObject((int) $sections[0], (int) $sections[1]), CrossReferenceTableInUseOrFree::FREE => new CrossReferenceEntryFreeObject((int) $sections[0], (int) $sections[1]), null => throw new ParseFailureException(sprintf('Unrecognized crossReference table record type %s', trim($sections[2]))) }; break; default: throw new ParseFailureException(sprintf('Invalid line "%s", 2 or 3 sections expected, %d found', substr(trim($line), 0, 30), count($sections))); } } if ($firstObjectNumber !== null && $nrOfEntries !== null) { $crossReferenceSubSections[] = new CrossReferenceSubSection($firstObjectNumber, $nrOfEntries, ... $crossReferenceEntries); } return new CrossReferenceSection($dictionary, ... $crossReferenceSubSections); } }