TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Charset;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
|
||||
|
||||
/**
|
||||
* Class for conversion between charsets
|
||||
*/
|
||||
#[Autoconfigure(public: true)]
|
||||
readonly class CharsetConverter
|
||||
{
|
||||
/**
|
||||
* Fallback character for chars with no equivalent.
|
||||
*/
|
||||
protected const FALLBACK_CHAR = '?';
|
||||
|
||||
public function __construct(
|
||||
private CharsetProvider $charsetProvider
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Converts all chars in the input UTF-8 string into integer numbers returned in an array.
|
||||
* All HTML entities (like & or £ or { or 㽝) will be detected as characters.
|
||||
* Also, instead of integer numbers the real UTF-8 char is returned.
|
||||
*
|
||||
* @param string $str Input string, UTF-8
|
||||
* @return array Output array with the char numbers
|
||||
*/
|
||||
public function utf8_to_numberarray(string $str): array
|
||||
{
|
||||
// Entities must be registered as well
|
||||
$str = html_entity_decode($str, ENT_COMPAT, 'utf-8');
|
||||
|
||||
// Do conversion:
|
||||
$strLen = strlen($str);
|
||||
$outArr = [];
|
||||
// Traverse each char in UTF-8 string.
|
||||
for ($a = 0; $a < $strLen; $a++) {
|
||||
$chr = $str[$a];
|
||||
$ord = ord($chr);
|
||||
// This means multibyte! (first byte!)
|
||||
if ($ord > 127) {
|
||||
// Since the first byte must have the 7th bit set we check that. Otherwise, we might be in the middle of a byte sequence.
|
||||
if ($ord & 64) {
|
||||
// Add first byte
|
||||
$buf = $chr;
|
||||
// For each byte in multibyte string...
|
||||
for ($b = 0; $b < 8; $b++) {
|
||||
// Shift it left and ...
|
||||
$ord <<= 1;
|
||||
// ... and with 8th bit - if that is set, then there are still bytes in sequence.
|
||||
if ($ord & 128) {
|
||||
$a++;
|
||||
// ... and add the next char.
|
||||
$buf .= $str[$a];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$outArr[] = $buf;
|
||||
} else {
|
||||
$outArr[] = self::FALLBACK_CHAR;
|
||||
}
|
||||
} else {
|
||||
$outArr[] = chr($ord);
|
||||
}
|
||||
}
|
||||
return $outArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 Multibyte character to a UNICODE number
|
||||
* Unit-tested by Kasper
|
||||
*
|
||||
* @param string $str UTF-8 multibyte character string
|
||||
* @param bool $hex If set, then a hex. number is returned.
|
||||
* @return ($hex is false ? int : string) UNICODE integer
|
||||
*/
|
||||
public function utf8CharToUnumber(string $str, bool $hex = false): int|string
|
||||
{
|
||||
// First char
|
||||
$ord = ord($str[0]);
|
||||
// This verifies that it IS a multibyte string
|
||||
if (($ord & 192) === 192) {
|
||||
$binBuf = '';
|
||||
$b = 0;
|
||||
// For each byte in multibyte string...
|
||||
for (; $b < 8; $b++) {
|
||||
// Shift it left and ...
|
||||
$ord <<= 1;
|
||||
// ... and with 8th bit - if that is set, then there are still bytes in sequence.
|
||||
if ($ord & 128) {
|
||||
$binBuf .= substr('00000000' . decbin(ord($str[$b + 1])), -6);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$binBuf = substr('00000000' . decbin(ord($str[0])), -(6 - $b)) . $binBuf;
|
||||
$int = bindec($binBuf);
|
||||
} else {
|
||||
$int = $ord;
|
||||
}
|
||||
return $hex ? 'x' . dechex((int)$int) : $int;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps all characters of a UTF-8 string.
|
||||
*
|
||||
* @param string $str UTF-8 string
|
||||
*/
|
||||
public function utf8_char_mapping(string $str): string
|
||||
{
|
||||
$out = '';
|
||||
for ($i = 0; isset($str[$i]); $i++) {
|
||||
$c = ord($str[$i]);
|
||||
$mbc = '';
|
||||
// single-byte (0xxxxxx)
|
||||
if (!($c & 128)) {
|
||||
$mbc = $str[$i];
|
||||
} elseif (($c & 192) === 192) {
|
||||
$bc = 0;
|
||||
// multibyte starting byte (11xxxxxx)
|
||||
for (; $c & 128; $c <<= 1) {
|
||||
$bc++;
|
||||
}
|
||||
// calculate number of bytes
|
||||
$mbc = substr($str, $i, $bc);
|
||||
$i += $bc - 1;
|
||||
}
|
||||
if ($this->charsetProvider->hasMultibyteChar('utf-8', $mbc)) {
|
||||
$out .= $this->charsetProvider->getByMultibyteChar('utf-8', $mbc);
|
||||
} else {
|
||||
$out .= $mbc;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user