<?php
/*
* This file is part of Chevere.
*
* (c) Rodolfo Berrios <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chevere\VarDump\Processors;
use Chevere\Parameter\Interfaces\TypeInterface;
use Chevere\VarDump\Interfaces\ProcessorInterface;
use Chevere\VarDump\Interfaces\VarDumperInterface;
use Chevere\VarDump\Processors\Traits\ProcessorTrait;
final class StringProcessor implements ProcessorInterface
{
use ProcessorTrait;
public const CONTROL_CHARS = [
"\t" => '\t',
"\n" => '\n',
"\v" => '\v',
"\f" => '\f',
"\r" => '\r',
"\033" => '\e',
];
public const CONTROL_CHARS_RX = '/[\x00-\x1F\x7F]+/';
private string $charset = '';
private string $string = '';
public function __construct(
private VarDumperInterface $varDumper
) {
$this->assertType();
/** @var string $string */
$string = $this->varDumper->dumpable()->var();
$this->string = $string;
$charset = ini_get('php.output_encoding')
?: ini_get('default_charset')
?: 'UTF-8'; // @codeCoverageIgnore
$this->setCharset($charset);
if (! preg_match('//u', $this->string)) {
$this->handleBinaryString();
}
$this->info = 'length=' . mb_strlen($string);
}
public function type(): string
{
return TypeInterface::STRING;
}
public function write(): void
{
$this->varDumper->writer()->write(
implode(' ', [
$this->typeHighlighted(),
$this->varDumper->format()
->filterEncodedChars($this->string),
$this->highlightParentheses($this->info),
])
);
}
public function charset(): string
{
return $this->charset;
}
/**
* Sets the default character encoding to use for non-UTF8 strings.
*/
private function setCharset(string $charset): void
{
$charset = strtoupper($charset);
$this->charset = ($charset === 'UTF-8' || $charset === 'UTF8')
? 'CP1252'
: $charset;
}
private function handleBinaryString(): void
{
if (! function_exists('iconv')) {
return; // @codeCoverageIgnore
}
$this->string = <<<STRING
b"{$this->binaryDisplay($this->utf8Encode($this->string))}"
STRING;
}
private function binaryDisplay(string $value): string
{
$map = static::CONTROL_CHARS;
$startChar = '';
$endChar = '';
$value = preg_replace_callback(
static::CONTROL_CHARS_RX,
function ($c) use ($map, $startChar, $endChar) {
$s = $startChar;
$c = $c[$i = 0];
do {
$s .= $map[$c[$i]] ?? sprintf('\x%02X', ord($c[$i]));
} while (isset($c[++$i]));
return $s . $endChar;
},
$value,
-1,
$charCount
);
return $value ?? '';
}
/**
* Converts a non-UTF-8 string to UTF-8.
*/
private function utf8Encode(string $string): string
{
$converted = @iconv($this->charset, 'UTF-8', $string);
// @codeCoverageIgnoreStart
if ($converted !== false) {
return $converted;
}
$converted = @iconv('CP1252', 'UTF-8', $string);
if ($converted !== false && $this->charset !== 'CP1252') {
return $converted;
}
return @iconv('CP850', 'UTF-8', $string) ?: $string;
// @codeCoverageIgnoreEnd
}
}
|