2026-01-09 07:13:59 +00:00

70 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Array;
use Override;
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\DictionaryValue;
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Reference\ReferenceValue;
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Reference\ReferenceValueArray;
use PrinsFrank\PdfParser\Exception\ParseFailureException;
use PrinsFrank\PdfParser\Exception\PdfParserException;
use PrinsFrank\PdfParser\Exception\RuntimeException;
/** @api */
class ArrayValue implements DictionaryValue {
/** @param list<int|string|ArrayValue|ReferenceValueArray|null> $value */
public function __construct(
public readonly array $value
) {
}
#[Override]
/** @throws PdfParserException */
public static function fromValue(string $valueString): null|self|ReferenceValueArray {
$valueString = trim($valueString);
if (!str_starts_with($valueString, '[') || !str_ends_with($valueString, ']')) {
return null;
}
$valueString = preg_replace('/(<[^>]*>)(?=<[^>]*>)/', '$1 $2', $valueString)
?? throw new RuntimeException('An error occurred while sanitizing array value');
$valueString = str_replace(['/', "\n"], [' /', ' '], rtrim(ltrim($valueString, '[ '), ' ]'));
$valueString = preg_replace('/\s+/', ' ', $valueString)
?? throw new RuntimeException('An error occurred while removing duplicate spaces from array value');
$values = explode(' ', $valueString);
if (count($values) % 3 === 0 && array_key_exists(2, $values) && $values[2] === 'R') {
return ReferenceValueArray::fromValue($valueString);
}
$array = [];
foreach ($values as $value) {
if (str_starts_with($value, '[') && str_ends_with($value, ']')) {
$array[] = self::fromValue($value);
} elseif ((string) (int) $value === $value) {
$array[] = (int) $value;
} elseif ($value !== '') {
$array[] = $value;
}
}
return new self($array);
}
public function toString(): string {
$string = '';
foreach ($this->value as $value) {
$string .= ' ' . match (true) {
is_int($value),
is_float($value),
is_string($value) => $value,
$value instanceof ArrayValue => $value->toString(),
$value instanceof ReferenceValueArray => implode(' ', array_map(fn (ReferenceValue $referenceValue) => $referenceValue->objectNumber . ' R', $value->referenceValues)),
default => throw new ParseFailureException('Unsupported array value type: ' . gettype($value)),
};
}
return '[' . trim($string) . ']';
}
}