Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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

Normalizer.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 9.03 KiB


001  <?php
002   
003  /*
004   * Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
005   *
006   * This library is free software; you can redistribute it and/or modify it
007   * under the terms of the (at your option):
008   * Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
009   * GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
010   */
011   
012  namespace Patchwork\PHP\Shim;
013   
014  /**
015   * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
016   *
017   * It has been validated with Unicode 6.3 Normalization Conformance Test.
018   * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
019   *
020   * @internal
021   */
022  class Normalizer
023  {
024      const NONE = 1;
025      const FORM_D = 2;
026      const FORM_KD = 3;
027      const FORM_C = 4;
028      const FORM_KC = 5;
029      const NFD = 2;
030      const NFKD = 3;
031      const NFC = 4;
032      const NFKC = 5;
033   
034      private static $C;
035      private static $D;
036      private static $KD;
037      private static $cC;
038      private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
039      private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
040   
041      public static function isNormalized($s, $form = self::NFC)
042      {
043          if ($form <= self::NONE || self::NFKC < $form) {
044              return false;
045          }
046          if (!isset($s[strspn($s .= '', self::$ASCII)])) {
047              return true;
048          }
049          if (self::NFC === $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) {
050              return true;
051          }
052   
053          return false; // Pretend false as quick checks implementented in PHP won't be so quick
054      }
055   
056      public static function normalize($s, $form = self::NFC)
057      {
058          if (!preg_match('//u', $s .= '')) {
059              return false;
060          }
061   
062          switch ($form) {
063              case self::NONE: return $s;
064              case self::NFC: $C = true; $K = false; break;
065              case self::NFD: $C = false; $K = false; break;
066              case self::NFKC: $C = true; $K = true; break;
067              case self::NFKD: $C = false; $K = true; break;
068              default: return false;
069          }
070   
071          if ('' === $s) {
072              return '';
073          }
074   
075          if ($K && null === self::$KD) {
076              self::$KD = self::getData('compatibilityDecomposition');
077          }
078   
079          if (null === self::$D) {
080              self::$D = self::getData('canonicalDecomposition');
081              self::$cC = self::getData('combiningClass');
082          }
083   
084          if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) {
085              mb_internal_encoding('8bit');
086          }
087   
088          $r = self::decompose($s, $K);
089   
090          if ($C) {
091              if (null === self::$C) {
092                  self::$C = self::getData('canonicalComposition');
093              }
094   
095              $r = self::recompose($r);
096          }
097          if (null !== $mbEncoding) {
098              mb_internal_encoding($mbEncoding);
099          }
100   
101          return $r;
102      }
103   
104      private static function recompose($s)
105      {
106          $ASCII = self::$ASCII;
107          $compMap = self::$C;
108          $combClass = self::$cC;
109          $ulenMask = self::$ulenMask;
110   
111          $result = $tail = '';
112   
113          $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"];
114          $len = strlen($s);
115   
116          $lastUchr = substr($s, 0, $i);
117          $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
118   
119          while ($i < $len) {
120              if ($s[$i] < "\x80") {
121                  // ASCII chars
122   
123                  if ($tail) {
124                      $lastUchr .= $tail;
125                      $tail = '';
126                  }
127   
128                  if ($j = strspn($s, $ASCII, $i + 1)) {
129                      $lastUchr .= substr($s, $i, $j);
130                      $i += $j;
131                  }
132   
133                  $result .= $lastUchr;
134                  $lastUchr = $s[$i];
135                  $lastUcls = 0;
136                  ++$i;
137                  continue;
138              }
139   
140              $ulen = $ulenMask[$s[$i] & "\xF0"];
141              $uchr = substr($s, $i, $ulen);
142   
143              if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr
144                  ||   $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
145                  || $lastUcls) {
146                  // Table lookup and combining chars composition
147   
148                  $ucls = isset($combClass[$uchr]) ? $combClass[$uchr] : 0;
149   
150                  if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
151                      $lastUchr = $compMap[$lastUchr.$uchr];
152                  } elseif ($lastUcls = $ucls) {
153                      $tail .= $uchr;
154                  } else {
155                      if ($tail) {
156                          $lastUchr .= $tail;
157                          $tail = '';
158                      }
159   
160                      $result .= $lastUchr;
161                      $lastUchr = $uchr;
162                  }
163              } else {
164                  // Hangul chars
165   
166                  $L = ord($lastUchr[2]) - 0x80;
167                  $V = ord($uchr[2]) - 0xA1;
168                  $T = 0;
169   
170                  $uchr = substr($s, $i + $ulen, 3);
171   
172                  if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") {
173                      $T = ord($uchr[2]) - 0xA7;
174                      0 > $T && $T += 0x40;
175                      $ulen += 3;
176                  }
177   
178                  $L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
179                  $lastUchr = chr(0xE0 | $L >> 12).chr(0x80 | $L >> 6 & 0x3F).chr(0x80 | $L & 0x3F);
180              }
181   
182              $i += $ulen;
183          }
184   
185          return $result.$lastUchr.$tail;
186      }
187   
188      private static function decompose($s, $c)
189      {
190          $result = '';
191   
192          $ASCII = self::$ASCII;
193          $decompMap = self::$D;
194          $combClass = self::$cC;
195          $ulenMask = self::$ulenMask;
196          if ($c) {
197              $compatMap = self::$KD;
198          }
199   
200          $c = array();
201          $i = 0;
202          $len = strlen($s);
203   
204          while ($i < $len) {
205              if ($s[$i] < "\x80") {
206                  // ASCII chars
207   
208                  if ($c) {
209                      ksort($c);
210                      $result .= implode('', $c);
211                      $c = array();
212                  }
213   
214                  $j = 1 + strspn($s, $ASCII, $i + 1);
215                  $result .= substr($s, $i, $j);
216                  $i += $j;
217                  continue;
218              }
219   
220              $ulen = $ulenMask[$s[$i] & "\xF0"];
221              $uchr = substr($s, $i, $ulen);
222              $i += $ulen;
223   
224              if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
225                  // Table lookup
226   
227                  if ($uchr !== $j = isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr)) {
228                      $uchr = $j;
229   
230                      $j = strlen($uchr);
231                      $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"];
232   
233                      if ($ulen != $j) {
234                          // Put trailing chars in $s
235   
236                          $j -= $ulen;
237                          $i -= $j;
238   
239                          if (0 > $i) {
240                              $s = str_repeat(' ', -$i).$s;
241                              $len -= $i;
242                              $i = 0;
243                          }
244   
245                          while ($j--) {
246                              $s[$i + $j] = $uchr[$ulen + $j];
247                          }
248   
249                          $uchr = substr($uchr, 0, $ulen);
250                      }
251                  }
252                  if (isset($combClass[$uchr])) {
253                      // Combining chars, for sorting
254   
255                      if (!isset($c[$combClass[$uchr]])) {
256                          $c[$combClass[$uchr]] = '';
257                      }
258                      $c[$combClass[$uchr]] .= $uchr;
259                      continue;
260                  }
261              } else {
262                  // Hangul chars
263   
264                  $uchr = unpack('C*', $uchr);
265                  $j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80;
266   
267                  $uchr = "\xE1\x84".chr(0x80 + (int) ($j / 588))
268                         ."\xE1\x85".chr(0xA1 + (int) (($j % 588) / 28));
269   
270                  if ($j %= 28) {
271                      $uchr .= $j < 25
272                          ? ("\xE1\x86".chr(0xA7 + $j))
273                          : ("\xE1\x87".chr(0x67 + $j));
274                  }
275              }
276              if ($c) {
277                  ksort($c);
278                  $result .= implode('', $c);
279                  $c = array();
280              }
281   
282              $result .= $uchr;
283          }
284   
285          if ($c) {
286              ksort($c);
287              $result .= implode('', $c);
288          }
289   
290          return $result;
291      }
292   
293      private static function getData($file)
294      {
295          if (file_exists($file = __DIR__.'/unidata/'.$file.'.ser')) {
296              return unserialize(file_get_contents($file));
297          }
298   
299          return false;
300      }
301  }
302