Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Mbstring.php

Zuletzt modifiziert: 01.05.2026, 11:26 - Dateigröße: 36.36 KiB


0001  <?php
0002   
0003  /*
0004   * This file is part of the Symfony package.
0005   *
0006   * (c) Fabien Potencier <fabien@symfony.com>
0007   *
0008   * For the full copyright and license information, please view the LICENSE
0009   * file that was distributed with this source code.
0010   */
0011   
0012  namespace Symfony\Polyfill\Mbstring;
0013   
0014  /**
0015   * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
0016   *
0017   * Implemented:
0018   * - mb_chr                  - Returns a specific character from its Unicode code point
0019   * - mb_convert_encoding     - Convert character encoding
0020   * - mb_convert_variables    - Convert character code in variable(s)
0021   * - mb_decode_mimeheader    - Decode string in MIME header field
0022   * - mb_encode_mimeheader    - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
0023   * - mb_decode_numericentity - Decode HTML numeric string reference to character
0024   * - mb_encode_numericentity - Encode character to HTML numeric string reference
0025   * - mb_convert_case         - Perform case folding on a string
0026   * - mb_detect_encoding      - Detect character encoding
0027   * - mb_get_info             - Get internal settings of mbstring
0028   * - mb_http_input           - Detect HTTP input character encoding
0029   * - mb_http_output          - Set/Get HTTP output character encoding
0030   * - mb_internal_encoding    - Set/Get internal character encoding
0031   * - mb_list_encodings       - Returns an array of all supported encodings
0032   * - mb_ord                  - Returns the Unicode code point of a character
0033   * - mb_output_handler       - Callback function converts character encoding in output buffer
0034   * - mb_scrub                - Replaces ill-formed byte sequences with substitute characters
0035   * - mb_strlen               - Get string length
0036   * - mb_strpos               - Find position of first occurrence of string in a string
0037   * - mb_strrpos              - Find position of last occurrence of a string in a string
0038   * - mb_str_split            - Convert a string to an array
0039   * - mb_strtolower           - Make a string lowercase
0040   * - mb_strtoupper           - Make a string uppercase
0041   * - mb_substitute_character - Set/Get substitution character
0042   * - mb_substr               - Get part of string
0043   * - mb_stripos              - Finds position of first occurrence of a string within another, case insensitive
0044   * - mb_stristr              - Finds first occurrence of a string within another, case insensitive
0045   * - mb_strrchr              - Finds the last occurrence of a character in a string within another
0046   * - mb_strrichr             - Finds the last occurrence of a character in a string within another, case insensitive
0047   * - mb_strripos             - Finds position of last occurrence of a string within another, case insensitive
0048   * - mb_strstr               - Finds first occurrence of a string within another
0049   * - mb_strwidth             - Return width of string
0050   * - mb_substr_count         - Count the number of substring occurrences
0051   * - mb_ucfirst              - Make a string's first character uppercase
0052   * - mb_lcfirst              - Make a string's first character lowercase
0053   * - mb_trim                 - Strip whitespace (or other characters) from the beginning and end of a string
0054   * - mb_ltrim                - Strip whitespace (or other characters) from the beginning of a string
0055   * - mb_rtrim                - Strip whitespace (or other characters) from the end of a string
0056   *
0057   * Not implemented:
0058   * - mb_convert_kana         - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
0059   * - mb_ereg_*               - Regular expression with multibyte support
0060   * - mb_parse_str            - Parse GET/POST/COOKIE data and set global variable
0061   * - mb_preferred_mime_name  - Get MIME charset string
0062   * - mb_regex_encoding       - Returns current encoding for multibyte regex as string
0063   * - mb_regex_set_options    - Set/Get the default options for mbregex functions
0064   * - mb_send_mail            - Send encoded mail
0065   * - mb_split                - Split multibyte string using regular expression
0066   * - mb_strcut               - Get part of string
0067   * - mb_strimwidth           - Get truncated string with specified width
0068   *
0069   * @author Nicolas Grekas <p@tchwork.com>
0070   *
0071   * @internal
0072   */
0073  final class Mbstring
0074  {
0075      public const MB_CASE_FOLD = \PHP_INT_MAX;
0076   
0077      private const SIMPLE_CASE_FOLD = [
0078          ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"],
0079          ['μ', 's', 'ι',        'σ', 'β',        'θ',        'φ',        'π',        'κ',        'ρ',        'ε',        "\xE1\xB9\xA1", 'ι'],
0080      ];
0081   
0082      private static $encodingList = ['ASCII', 'UTF-8'];
0083      private static $language = 'neutral';
0084      private static $internalEncoding = 'UTF-8';
0085   
0086      public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
0087      {
0088          if (\is_array($s)) {
0089              $r = [];
0090              foreach ($s as $str) {
0091                  $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
0092              }
0093   
0094              return $r;
0095          }
0096   
0097          if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) {
0098              $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
0099          } else {
0100              $fromEncoding = self::getEncoding($fromEncoding);
0101          }
0102   
0103          $toEncoding = self::getEncoding($toEncoding);
0104   
0105          if ('BASE64' === $fromEncoding) {
0106              $s = base64_decode($s);
0107              $fromEncoding = $toEncoding;
0108          }
0109   
0110          if ('BASE64' === $toEncoding) {
0111              return base64_encode($s);
0112          }
0113   
0114          if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
0115              if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
0116                  $fromEncoding = 'Windows-1252';
0117              }
0118              if ('UTF-8' !== $fromEncoding) {
0119                  $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
0120              }
0121   
0122              return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
0123          }
0124   
0125          if ('HTML-ENTITIES' === $fromEncoding) {
0126              $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8');
0127              $fromEncoding = 'UTF-8';
0128          }
0129   
0130          return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
0131      }
0132   
0133      public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
0134      {
0135          $ok = true;
0136          array_walk_recursive($vars, static function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
0137              if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
0138                  $ok = false;
0139              }
0140          });
0141   
0142          return $ok ? $fromEncoding : false;
0143      }
0144   
0145      public static function mb_decode_mimeheader($s)
0146      {
0147          return iconv_mime_decode($s, 2, self::$internalEncoding);
0148      }
0149   
0150      public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
0151      {
0152          trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING);
0153      }
0154   
0155      public static function mb_decode_numericentity($s, $convmap, $encoding = null)
0156      {
0157          if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
0158              trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
0159   
0160              return null;
0161          }
0162   
0163          if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) {
0164              return false;
0165          }
0166   
0167          if (null !== $encoding && !\is_scalar($encoding)) {
0168              trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
0169   
0170              return '';  // Instead of null (cf. mb_encode_numericentity).
0171          }
0172   
0173          $s = (string) $s;
0174          if ('' === $s) {
0175              return '';
0176          }
0177   
0178          $encoding = self::getEncoding($encoding);
0179   
0180          if ('UTF-8' === $encoding) {
0181              $encoding = null;
0182              if (!preg_match('//u', $s)) {
0183                  $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
0184              }
0185          } else {
0186              $s = iconv($encoding, 'UTF-8//IGNORE', $s);
0187          }
0188   
0189          $cnt = floor(\count($convmap) / 4) * 4;
0190   
0191          for ($i = 0; $i < $cnt; $i += 4) {
0192              // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
0193              $convmap[$i] += $convmap[$i + 2];
0194              $convmap[$i + 1] += $convmap[$i + 2];
0195          }
0196   
0197          $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))'.(\PHP_VERSION_ID >= 80200 ? '' : '(?!&)').';?/', static function (array $m) use ($cnt, $convmap) {
0198              $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
0199              for ($i = 0; $i < $cnt; $i += 4) {
0200                  if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
0201                      return self::mb_chr($c - $convmap[$i + 2]);
0202                  }
0203              }
0204   
0205              return $m[0];
0206          }, $s);
0207   
0208          if (null === $encoding) {
0209              return $s;
0210          }
0211   
0212          return iconv('UTF-8', $encoding.'//IGNORE', $s);
0213      }
0214   
0215      public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
0216      {
0217          if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
0218              trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
0219   
0220              return null;
0221          }
0222   
0223          if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) {
0224              return false;
0225          }
0226   
0227          if (null !== $encoding && !\is_scalar($encoding)) {
0228              trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
0229   
0230              return null;  // Instead of '' (cf. mb_decode_numericentity).
0231          }
0232   
0233          if (null !== $is_hex && !\is_scalar($is_hex)) {
0234              trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING);
0235   
0236              return null;
0237          }
0238   
0239          $s = (string) $s;
0240          if ('' === $s) {
0241              return '';
0242          }
0243   
0244          $encoding = self::getEncoding($encoding);
0245   
0246          if ('UTF-8' === $encoding) {
0247              $encoding = null;
0248              if (!preg_match('//u', $s)) {
0249                  $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
0250              }
0251          } else {
0252              $s = iconv($encoding, 'UTF-8//IGNORE', $s);
0253          }
0254   
0255          static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
0256   
0257          $cnt = floor(\count($convmap) / 4) * 4;
0258          $i = 0;
0259          $len = \strlen($s);
0260          $result = '';
0261   
0262          while ($i < $len) {
0263              $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
0264              $uchr = substr($s, $i, $ulen);
0265              $i += $ulen;
0266              $c = self::mb_ord($uchr);
0267   
0268              for ($j = 0; $j < $cnt; $j += 4) {
0269                  if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
0270                      $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
0271                      $result .= $is_hex ? \sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
0272                      continue 2;
0273                  }
0274              }
0275              $result .= $uchr;
0276          }
0277   
0278          if (null === $encoding) {
0279              return $result;
0280          }
0281   
0282          return iconv('UTF-8', $encoding.'//IGNORE', $result);
0283      }
0284   
0285      public static function mb_convert_case($s, $mode, $encoding = null)
0286      {
0287          $s = (string) $s;
0288          if ('' === $s) {
0289              return '';
0290          }
0291   
0292          $encoding = self::getEncoding($encoding);
0293   
0294          if ('UTF-8' === $encoding) {
0295              $encoding = null;
0296              if (!preg_match('//u', $s)) {
0297                  $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
0298              }
0299          } else {
0300              $s = iconv($encoding, 'UTF-8//IGNORE', $s);
0301          }
0302   
0303          if (\MB_CASE_TITLE == $mode) {
0304              static $titleRegexp = null;
0305              if (null === $titleRegexp) {
0306                  $titleRegexp = self::getData('titleCaseRegexp');
0307              }
0308              $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s);
0309          } else {
0310              if (\MB_CASE_UPPER == $mode) {
0311                  static $upper = null;
0312                  if (null === $upper) {
0313                      $upper = self::getData('upperCase');
0314                  }
0315                  $map = $upper;
0316              } else {
0317                  if (self::MB_CASE_FOLD === $mode) {
0318                      static $caseFolding = null;
0319                      if (null === $caseFolding) {
0320                          $caseFolding = self::getData('caseFolding');
0321                      }
0322                      $s = strtr($s, $caseFolding);
0323                  }
0324   
0325                  static $lower = null;
0326                  if (null === $lower) {
0327                      $lower = self::getData('lowerCase');
0328                  }
0329                  $map = $lower;
0330              }
0331   
0332              static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
0333   
0334              $i = 0;
0335              $len = \strlen($s);
0336   
0337              while ($i < $len) {
0338                  $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
0339                  $uchr = substr($s, $i, $ulen);
0340                  $i += $ulen;
0341   
0342                  if (isset($map[$uchr])) {
0343                      $uchr = $map[$uchr];
0344                      $nlen = \strlen($uchr);
0345   
0346                      if ($nlen == $ulen) {
0347                          $nlen = $i;
0348                          do {
0349                              $s[--$nlen] = $uchr[--$ulen];
0350                          } while ($ulen);
0351                      } else {
0352                          $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
0353                          $len += $nlen - $ulen;
0354                          $i += $nlen - $ulen;
0355                      }
0356                  }
0357              }
0358          }
0359   
0360          if (null === $encoding) {
0361              return $s;
0362          }
0363   
0364          return iconv('UTF-8', $encoding.'//IGNORE', $s);
0365      }
0366   
0367      public static function mb_internal_encoding($encoding = null)
0368      {
0369          if (null === $encoding) {
0370              return self::$internalEncoding;
0371          }
0372   
0373          $normalizedEncoding = self::getEncoding($encoding);
0374   
0375          if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
0376              self::$internalEncoding = $normalizedEncoding;
0377   
0378              return true;
0379          }
0380   
0381          if (80000 > \PHP_VERSION_ID) {
0382              return false;
0383          }
0384   
0385          throw new \ValueError(\sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding));
0386      }
0387   
0388      public static function mb_language($lang = null)
0389      {
0390          if (null === $lang) {
0391              return self::$language;
0392          }
0393   
0394          switch ($normalizedLang = strtolower($lang)) {
0395              case 'uni':
0396              case 'neutral':
0397                  self::$language = $normalizedLang;
0398   
0399                  return true;
0400          }
0401   
0402          if (80000 > \PHP_VERSION_ID) {
0403              return false;
0404          }
0405   
0406          throw new \ValueError(\sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang));
0407      }
0408   
0409      public static function mb_list_encodings()
0410      {
0411          return ['UTF-8'];
0412      }
0413   
0414      public static function mb_encoding_aliases($encoding)
0415      {
0416          switch (strtoupper($encoding)) {
0417              case 'UTF8':
0418              case 'UTF-8':
0419                  return ['utf8'];
0420          }
0421   
0422          return false;
0423      }
0424   
0425      public static function mb_check_encoding($var = null, $encoding = null)
0426      {
0427          if (null === $encoding) {
0428              if (null === $var) {
0429                  return false;
0430              }
0431              $encoding = self::$internalEncoding;
0432          }
0433   
0434          if (!\is_array($var)) {
0435              return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var);
0436          }
0437   
0438          foreach ($var as $key => $value) {
0439              if (!self::mb_check_encoding($key, $encoding)) {
0440                  return false;
0441              }
0442              if (!self::mb_check_encoding($value, $encoding)) {
0443                  return false;
0444              }
0445          }
0446   
0447          return true;
0448      }
0449   
0450      public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
0451      {
0452          if (null === $encodingList) {
0453              $encodingList = self::$encodingList;
0454          } else {
0455              if (!\is_array($encodingList)) {
0456                  $encodingList = array_map('trim', explode(',', $encodingList));
0457              }
0458              $encodingList = array_map('strtoupper', $encodingList);
0459          }
0460   
0461          foreach ($encodingList as $enc) {
0462              switch ($enc) {
0463                  case 'ASCII':
0464                      if (!preg_match('/[\x80-\xFF]/', $str)) {
0465                          return $enc;
0466                      }
0467                      break;
0468   
0469                  case 'UTF8':
0470                  case 'UTF-8':
0471                      if (preg_match('//u', $str)) {
0472                          return 'UTF-8';
0473                      }
0474                      break;
0475   
0476                  default:
0477                      if (0 === strncmp($enc, 'ISO-8859-', 9)) {
0478                          return $enc;
0479                      }
0480              }
0481          }
0482   
0483          return false;
0484      }
0485   
0486      public static function mb_detect_order($encodingList = null)
0487      {
0488          if (null === $encodingList) {
0489              return self::$encodingList;
0490          }
0491   
0492          if (!\is_array($encodingList)) {
0493              $encodingList = array_map('trim', explode(',', $encodingList));
0494          }
0495          $encodingList = array_map('strtoupper', $encodingList);
0496   
0497          foreach ($encodingList as $enc) {
0498              switch ($enc) {
0499                  default:
0500                      if (strncmp($enc, 'ISO-8859-', 9)) {
0501                          return false;
0502                      }
0503                      // no break
0504                  case 'ASCII':
0505                  case 'UTF8':
0506                  case 'UTF-8':
0507              }
0508          }
0509   
0510          self::$encodingList = $encodingList;
0511   
0512          return true;
0513      }
0514   
0515      public static function mb_strlen($s, $encoding = null)
0516      {
0517          $encoding = self::getEncoding($encoding);
0518          if ('CP850' === $encoding || 'ASCII' === $encoding) {
0519              return \strlen($s);
0520          }
0521   
0522          return @iconv_strlen($s, $encoding);
0523      }
0524   
0525      public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
0526      {
0527          $encoding = self::getEncoding($encoding);
0528          if ('CP850' === $encoding || 'ASCII' === $encoding) {
0529              return strpos($haystack, $needle, $offset);
0530          }
0531   
0532          $needle = (string) $needle;
0533          if ('' === $needle) {
0534              if (80000 > \PHP_VERSION_ID) {
0535                  trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING);
0536   
0537                  return false;
0538              }
0539   
0540              return 0;
0541          }
0542   
0543          return iconv_strpos($haystack, $needle, $offset, $encoding);
0544      }
0545   
0546      public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
0547      {
0548          $encoding = self::getEncoding($encoding);
0549          if ('CP850' === $encoding || 'ASCII' === $encoding) {
0550              return strrpos($haystack, $needle, $offset);
0551          }
0552   
0553          if ($offset != (int) $offset) {
0554              $offset = 0;
0555          } elseif ($offset = (int) $offset) {
0556              if ($offset < 0) {
0557                  if (0 > $offset += self::mb_strlen($needle)) {
0558                      $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
0559                  }
0560                  $offset = 0;
0561              } else {
0562                  $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
0563              }
0564          }
0565   
0566          $pos = '' !== $needle || 80000 > \PHP_VERSION_ID
0567              ? iconv_strrpos($haystack, $needle, $encoding)
0568              : self::mb_strlen($haystack, $encoding);
0569   
0570          return false !== $pos ? $offset + $pos : false;
0571      }
0572   
0573      public static function mb_str_split($string, $split_length = 1, $encoding = null)
0574      {
0575          if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
0576              trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING);
0577   
0578              return null;
0579          }
0580   
0581          if (1 > $split_length = (int) $split_length) {
0582              if (80000 > \PHP_VERSION_ID) {
0583                  trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
0584   
0585                  return false;
0586              }
0587   
0588              throw new \ValueError('Argument #2 ($length) must be greater than 0');
0589          }
0590   
0591          if (null === $encoding) {
0592              $encoding = mb_internal_encoding();
0593          }
0594   
0595          if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
0596              $rx = '/(';
0597              while (65535 < $split_length) {
0598                  $rx .= '.{65535}';
0599                  $split_length -= 65535;
0600              }
0601              $rx .= '.{'.$split_length.'})/us';
0602   
0603              return preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
0604          }
0605   
0606          $result = [];
0607          $length = mb_strlen($string, $encoding);
0608   
0609          for ($i = 0; $i < $length; $i += $split_length) {
0610              $result[] = mb_substr($string, $i, $split_length, $encoding);
0611          }
0612   
0613          return $result;
0614      }
0615   
0616      public static function mb_strtolower($s, $encoding = null)
0617      {
0618          return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding);
0619      }
0620   
0621      public static function mb_strtoupper($s, $encoding = null)
0622      {
0623          return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding);
0624      }
0625   
0626      public static function mb_substitute_character($c = null)
0627      {
0628          if (null === $c) {
0629              return 'none';
0630          }
0631          if (0 === strcasecmp($c, 'none')) {
0632              return true;
0633          }
0634          if (80000 > \PHP_VERSION_ID) {
0635              return false;
0636          }
0637          if (\is_int($c) || 'long' === $c || 'entity' === $c) {
0638              return false;
0639          }
0640   
0641          throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint');
0642      }
0643   
0644      public static function mb_substr($s, $start, $length = null, $encoding = null)
0645      {
0646          $encoding = self::getEncoding($encoding);
0647          if ('CP850' === $encoding || 'ASCII' === $encoding) {
0648              return (string) substr($s, $start, null === $length ? 2147483647 : $length);
0649          }
0650   
0651          if ($start < 0) {
0652              $start = iconv_strlen($s, $encoding) + $start;
0653              if ($start < 0) {
0654                  $start = 0;
0655              }
0656          }
0657   
0658          if (null === $length) {
0659              $length = 2147483647;
0660          } elseif ($length < 0) {
0661              $length = iconv_strlen($s, $encoding) + $length - $start;
0662              if ($length < 0) {
0663                  return '';
0664              }
0665          }
0666   
0667          return (string) iconv_substr($s, $start, $length, $encoding);
0668      }
0669   
0670      public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
0671      {
0672          [$haystack, $needle] = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [
0673              self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding),
0674              self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding),
0675          ]);
0676   
0677          return self::mb_strpos($haystack, $needle, $offset, $encoding);
0678      }
0679   
0680      public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
0681      {
0682          $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
0683   
0684          return self::getSubpart($pos, $part, $haystack, $encoding);
0685      }
0686   
0687      public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
0688      {
0689          $encoding = self::getEncoding($encoding);
0690          if ('CP850' === $encoding || 'ASCII' === $encoding) {
0691              $pos = strrpos($haystack, $needle);
0692          } else {
0693              $needle = self::mb_substr($needle, 0, 1, $encoding);
0694              $pos = iconv_strrpos($haystack, $needle, $encoding);
0695          }
0696   
0697          return self::getSubpart($pos, $part, $haystack, $encoding);
0698      }
0699   
0700      public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
0701      {
0702          $needle = self::mb_substr($needle, 0, 1, $encoding);
0703          $pos = self::mb_strripos($haystack, $needle, $encoding);
0704   
0705          return self::getSubpart($pos, $part, $haystack, $encoding);
0706      }
0707   
0708      public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
0709      {
0710          $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding);
0711          $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding);
0712   
0713          $haystack = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack);
0714          $needle = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle);
0715   
0716          return self::mb_strrpos($haystack, $needle, $offset, $encoding);
0717      }
0718   
0719      public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
0720      {
0721          $pos = strpos($haystack, $needle);
0722          if (false === $pos) {
0723              return false;
0724          }
0725          if ($part) {
0726              return substr($haystack, 0, $pos);
0727          }
0728   
0729          return substr($haystack, $pos);
0730      }
0731   
0732      public static function mb_get_info($type = 'all')
0733      {
0734          $info = [
0735              'internal_encoding' => self::$internalEncoding,
0736              'http_output' => 'pass',
0737              'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
0738              'func_overload' => 0,
0739              'func_overload_list' => 'no overload',
0740              'mail_charset' => 'UTF-8',
0741              'mail_header_encoding' => 'BASE64',
0742              'mail_body_encoding' => 'BASE64',
0743              'illegal_chars' => 0,
0744              'encoding_translation' => 'Off',
0745              'language' => self::$language,
0746              'detect_order' => self::$encodingList,
0747              'substitute_character' => 'none',
0748              'strict_detection' => 'Off',
0749          ];
0750   
0751          if ('all' === $type) {
0752              return $info;
0753          }
0754          if (isset($info[$type])) {
0755              return $info[$type];
0756          }
0757   
0758          return false;
0759      }
0760   
0761      public static function mb_http_input($type = '')
0762      {
0763          return false;
0764      }
0765   
0766      public static function mb_http_output($encoding = null)
0767      {
0768          return null !== $encoding ? 'pass' === $encoding : 'pass';
0769      }
0770   
0771      public static function mb_strwidth($s, $encoding = null)
0772      {
0773          $encoding = self::getEncoding($encoding);
0774   
0775          if ('UTF-8' !== $encoding) {
0776              $s = iconv($encoding, 'UTF-8//IGNORE', $s);
0777          }
0778   
0779          $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
0780   
0781          return ($wide << 1) + iconv_strlen($s, 'UTF-8');
0782      }
0783   
0784      public static function mb_substr_count($haystack, $needle, $encoding = null)
0785      {
0786          return substr_count($haystack, $needle);
0787      }
0788   
0789      public static function mb_output_handler($contents, $status)
0790      {
0791          return $contents;
0792      }
0793   
0794      public static function mb_chr($code, $encoding = null)
0795      {
0796          if (0x80 > $code %= 0x200000) {
0797              $s = \chr($code);
0798          } elseif (0x800 > $code) {
0799              $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
0800          } elseif (0x10000 > $code) {
0801              $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
0802          } else {
0803              $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
0804          }
0805   
0806          if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
0807              $s = mb_convert_encoding($s, $encoding, 'UTF-8');
0808          }
0809   
0810          return $s;
0811      }
0812   
0813      public static function mb_ord($s, $encoding = null)
0814      {
0815          if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
0816              $s = mb_convert_encoding($s, 'UTF-8', $encoding);
0817          }
0818   
0819          if (1 === \strlen($s)) {
0820              return \ord($s);
0821          }
0822   
0823          $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
0824          if (0xF0 <= $code) {
0825              return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
0826          }
0827          if (0xE0 <= $code) {
0828              return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
0829          }
0830          if (0xC0 <= $code) {
0831              return (($code - 0xC0) << 6) + $s[2] - 0x80;
0832          }
0833   
0834          return $code;
0835      }
0836   
0837      /** @return string|false */
0838      public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null)
0839      {
0840          if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) {
0841              if (\PHP_VERSION_ID < 80000) {
0842                  trigger_error('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH', \E_USER_WARNING);
0843   
0844                  return false;
0845              }
0846   
0847              throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
0848          }
0849   
0850          if (null === $encoding) {
0851              $encoding = self::mb_internal_encoding();
0852          } elseif (!self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given')) {
0853              return false;
0854          }
0855   
0856          if (self::mb_strlen($pad_string, $encoding) <= 0) {
0857              if (\PHP_VERSION_ID < 80000) {
0858                  trigger_error('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string', \E_USER_WARNING);
0859   
0860                  return false;
0861              }
0862   
0863              throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string');
0864          }
0865   
0866          $paddingRequired = $length - self::mb_strlen($string, $encoding);
0867   
0868          if ($paddingRequired < 1) {
0869              return $string;
0870          }
0871   
0872          switch ($pad_type) {
0873              case \STR_PAD_LEFT:
0874                  return self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding).$string;
0875              case \STR_PAD_RIGHT:
0876                  return $string.self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding);
0877              default:
0878                  $leftPaddingLength = floor($paddingRequired / 2);
0879                  $rightPaddingLength = $paddingRequired - $leftPaddingLength;
0880   
0881                  return self::mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.self::mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding);
0882          }
0883      }
0884   
0885      /** @return string|false */
0886      public static function mb_ucfirst(string $string, ?string $encoding = null)
0887      {
0888          if (null === $encoding) {
0889              $encoding = self::mb_internal_encoding();
0890          } elseif (!self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) {
0891              return false;
0892          }
0893   
0894          $firstChar = mb_substr($string, 0, 1, $encoding);
0895          $firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding);
0896   
0897          return $firstChar.mb_substr($string, 1, null, $encoding);
0898      }
0899   
0900      /** @return string|false */
0901      public static function mb_lcfirst(string $string, ?string $encoding = null)
0902      {
0903          if (null === $encoding) {
0904              $encoding = self::mb_internal_encoding();
0905          } elseif (!self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) {
0906              return false;
0907          }
0908   
0909          $firstChar = mb_substr($string, 0, 1, $encoding);
0910          $firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding);
0911   
0912          return $firstChar.mb_substr($string, 1, null, $encoding);
0913      }
0914   
0915      private static function getSubpart($pos, $part, $haystack, $encoding)
0916      {
0917          if (false === $pos) {
0918              return false;
0919          }
0920          if ($part) {
0921              return self::mb_substr($haystack, 0, $pos, $encoding);
0922          }
0923   
0924          return self::mb_substr($haystack, $pos, null, $encoding);
0925      }
0926   
0927      private static function html_encoding_callback(array $m)
0928      {
0929          $i = 1;
0930          $entities = '';
0931          $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8'));
0932   
0933          while (isset($m[$i])) {
0934              if (0x80 > $m[$i]) {
0935                  $entities .= \chr($m[$i++]);
0936                  continue;
0937              }
0938              if (0xF0 <= $m[$i]) {
0939                  $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
0940              } elseif (0xE0 <= $m[$i]) {
0941                  $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
0942              } else {
0943                  $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
0944              }
0945   
0946              $entities .= '&#'.$c.';';
0947          }
0948   
0949          return $entities;
0950      }
0951   
0952      private static function title_case(array $s)
0953      {
0954          return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8');
0955      }
0956   
0957      private static function getData($file)
0958      {
0959          if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
0960              return require $file;
0961          }
0962   
0963          return false;
0964      }
0965   
0966      private static function getEncoding($encoding)
0967      {
0968          if (null === $encoding) {
0969              return self::$internalEncoding;
0970          }
0971   
0972          if ('UTF-8' === $encoding) {
0973              return 'UTF-8';
0974          }
0975   
0976          $encoding = strtoupper($encoding);
0977   
0978          if ('8BIT' === $encoding || 'BINARY' === $encoding) {
0979              return 'CP850';
0980          }
0981   
0982          if ('UTF8' === $encoding) {
0983              return 'UTF-8';
0984          }
0985   
0986          if ('UTF-32' === $encoding) {
0987              return 'UTF-32BE';
0988          }
0989   
0990          if ('UTF-16' === $encoding) {
0991              return 'UTF-16BE';
0992          }
0993   
0994          return $encoding;
0995      }
0996   
0997      /** @return string|false */
0998      public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null)
0999      {
1000          return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
1001      }
1002   
1003      /** @return string|false */
1004      public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null)
1005      {
1006          return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
1007      }
1008   
1009      /** @return string|false */
1010      public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null)
1011      {
1012          return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
1013      }
1014   
1015      /** @return string|false */
1016      private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function)
1017      {
1018          if (null === $encoding) {
1019              $encoding = self::mb_internal_encoding();
1020          } elseif (!self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given')) {
1021              return false;
1022          }
1023   
1024          if ('' === $characters) {
1025              return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding);
1026          }
1027   
1028          if ('UTF-8' === $encoding) {
1029              $encoding = null;
1030              if (!preg_match('//u', $string)) {
1031                  $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string);
1032              }
1033              if (null !== $characters && !preg_match('//u', $characters)) {
1034                  $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters);
1035              }
1036          } else {
1037              $string = iconv($encoding, 'UTF-8//IGNORE', $string);
1038   
1039              if (null !== $characters) {
1040                  $characters = iconv($encoding, 'UTF-8//IGNORE', $characters);
1041              }
1042          }
1043   
1044          if (null === $characters) {
1045              $characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}";
1046          } else {
1047              $characters = preg_quote($characters);
1048          }
1049   
1050          $string = preg_replace(\sprintf($regex, $characters), '', $string);
1051   
1052          if (null === $encoding) {
1053              return $string;
1054          }
1055   
1056          return iconv('UTF-8', $encoding.'//IGNORE', $string);
1057      }
1058   
1059      private static function assertEncoding(string $encoding, string $errorFormat): bool
1060      {
1061          try {
1062              $validEncoding = @self::mb_check_encoding('', $encoding);
1063          } catch (\ValueError $e) {
1064              throw new \ValueError(\sprintf($errorFormat, $encoding));
1065          }
1066   
1067          if (!$validEncoding) {
1068              if (80000 > \PHP_VERSION_ID) {
1069                  trigger_error(\sprintf($errorFormat, $encoding), \E_USER_WARNING);
1070              } else {
1071                  throw new \ValueError(\sprintf($errorFormat, $encoding));
1072              }
1073          }
1074   
1075          return $validEncoding;
1076      }
1077  }
1078