• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/classes/general/punycode.php
  • Класс: CBXPunycode
  • Вызов: CBXPunycode::Utf8ToUcs4
private function Utf8ToUcs4($input)
{
	$output = [];
	$outputLength = 0;
	$inputLength = strlen($input);
	$mode = 'next';
	$test = 'none';
	$startByte = 0;
	$nextByte = 0;

	for ($i = 0; $i < $inputLength; $i++)
	{
		$v = ord($input[$i]);
		if ($v < 128)
		{
			$output[$outputLength] = $v;
			$outputLength++;
			if ($mode == 'add')
			{
				$this->AddError("UTF-8 / UCS-4 conversion failed: byte ".$i);
				return false;
			}
			continue;
		}
		if ($mode == 'next')
		{
			$startByte = $v;
			$mode = 'add';
			$test = 'range';
			if ($v >> 5 == 6)
			{
				$nextByte = 0;
				$v = ($v - 192) << 6;
			}
			elseif ($v >> 4 == 14)
			{
				$nextByte = 1;
				$v = ($v - 224) << 12;
			}
			elseif ($v >> 3 == 30)
			{
				$nextByte = 2;
				$v = ($v - 240) << 18;
			}
			elseif ($v >> 2 == 62)
			{
				$nextByte = 3;
				$v = ($v - 248) << 24;
			}
			elseif ($v >> 1 == 126)
			{
				$nextByte = 4;
				$v = ($v - 252) << 30;
			}
			else
			{
				$this->AddError("UTF-8 / UCS-4 conversion failed: byte ".$i);
				return false;
			}

			$output[$outputLength] = $v;
			$outputLength++;
			continue;
		}
		if ($mode == 'add')
		{
			if ($test == 'range')
			{
				$test = 'none';
				if (($v < 0xA0 && $startByte == 0xE0)
				    || ($v < 0x90 && $startByte == 0xF0)
				    || ($v > 0x8F && $startByte == 0xF4))
				{
					$this->AddError("UTF-8 / UCS-4 conversion failed: byte ".$i);
					return false;
				}
			}
			if ($v >> 6 == 2)
			{
				$v = ($v - 128) << ($nextByte * 6);
				$output[($outputLength - 1)] += $v;
				$nextByte--;
			}
			else
			{
				$this->AddError("UTF-8 / UCS-4 conversion failed: byte ".$i);
				return false;
			}
			if ($nextByte < 0)
				$mode = 'next';
		}
	}
	return $output;
}