PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.2.0
Independent Analytics – WordPress Analytics Plugin v2.2.0
2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / symfony / string / ByteString.php
independent-analytics / vendor / symfony / string Last commit date
Exception 2 years ago Inflector 2 years ago Resources 2 years ago Slugger 2 years ago AbstractString.php 2 years ago AbstractUnicodeString.php 2 years ago ByteString.php 2 years ago CodePointString.php 2 years ago LazyString.php 2 years ago UnicodeString.php 2 years ago
ByteString.php
406 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace IAWP_SCOPED\Symfony\Component\String;
12
13 use IAWP_SCOPED\Symfony\Component\String\Exception\ExceptionInterface;
14 use IAWP_SCOPED\Symfony\Component\String\Exception\InvalidArgumentException;
15 use IAWP_SCOPED\Symfony\Component\String\Exception\RuntimeException;
16 /**
17 * Represents a binary-safe string of bytes.
18 *
19 * @author Nicolas Grekas <p@tchwork.com>
20 * @author Hugo Hamon <hugohamon@neuf.fr>
21 *
22 * @throws ExceptionInterface
23 * @internal
24 */
25 class ByteString extends AbstractString
26 {
27 private const ALPHABET_ALPHANUMERIC = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
28 public function __construct(string $string = '')
29 {
30 $this->string = $string;
31 }
32 /*
33 * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03)
34 *
35 * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16
36 *
37 * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE).
38 *
39 * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/)
40 */
41 public static function fromRandom(int $length = 16, string $alphabet = null) : self
42 {
43 if ($length <= 0) {
44 throw new InvalidArgumentException(\sprintf('A strictly positive length is expected, "%d" given.', $length));
45 }
46 $alphabet = $alphabet ?? self::ALPHABET_ALPHANUMERIC;
47 $alphabetSize = \strlen($alphabet);
48 $bits = (int) \ceil(\log($alphabetSize, 2.0));
49 if ($bits <= 0 || $bits > 56) {
50 throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.');
51 }
52 $ret = '';
53 while ($length > 0) {
54 $urandomLength = (int) \ceil(2 * $length * $bits / 8.0);
55 $data = \random_bytes($urandomLength);
56 $unpackedData = 0;
57 $unpackedBits = 0;
58 for ($i = 0; $i < $urandomLength && $length > 0; ++$i) {
59 // Unpack 8 bits
60 $unpackedData = $unpackedData << 8 | \ord($data[$i]);
61 $unpackedBits += 8;
62 // While we have enough bits to select a character from the alphabet, keep
63 // consuming the random data
64 for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) {
65 $index = $unpackedData & (1 << $bits) - 1;
66 $unpackedData >>= $bits;
67 // Unfortunately, the alphabet size is not necessarily a power of two.
68 // Worst case, it is 2^k + 1, which means we need (k+1) bits and we
69 // have around a 50% chance of missing as k gets larger
70 if ($index < $alphabetSize) {
71 $ret .= $alphabet[$index];
72 --$length;
73 }
74 }
75 }
76 }
77 return new static($ret);
78 }
79 public function bytesAt(int $offset) : array
80 {
81 $str = $this->string[$offset] ?? '';
82 return '' === $str ? [] : [\ord($str)];
83 }
84 public function append(string ...$suffix) : parent
85 {
86 $str = clone $this;
87 $str->string .= 1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix);
88 return $str;
89 }
90 public function camel() : parent
91 {
92 $str = clone $this;
93 $parts = \explode(' ', \trim(\ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $this->string))));
94 $parts[0] = 1 !== \strlen($parts[0]) && \ctype_upper($parts[0]) ? $parts[0] : \lcfirst($parts[0]);
95 $str->string = \implode('', $parts);
96 return $str;
97 }
98 public function chunk(int $length = 1) : array
99 {
100 if (1 > $length) {
101 throw new InvalidArgumentException('The chunk length must be greater than zero.');
102 }
103 if ('' === $this->string) {
104 return [];
105 }
106 $str = clone $this;
107 $chunks = [];
108 foreach (\str_split($this->string, $length) as $chunk) {
109 $str->string = $chunk;
110 $chunks[] = clone $str;
111 }
112 return $chunks;
113 }
114 public function endsWith($suffix) : bool
115 {
116 if ($suffix instanceof parent) {
117 $suffix = $suffix->string;
118 } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
119 return parent::endsWith($suffix);
120 } else {
121 $suffix = (string) $suffix;
122 }
123 return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase);
124 }
125 public function equalsTo($string) : bool
126 {
127 if ($string instanceof parent) {
128 $string = $string->string;
129 } elseif (\is_array($string) || $string instanceof \Traversable) {
130 return parent::equalsTo($string);
131 } else {
132 $string = (string) $string;
133 }
134 if ('' !== $string && $this->ignoreCase) {
135 return 0 === \strcasecmp($string, $this->string);
136 }
137 return $string === $this->string;
138 }
139 public function folded() : parent
140 {
141 $str = clone $this;
142 $str->string = \strtolower($str->string);
143 return $str;
144 }
145 public function indexOf($needle, int $offset = 0) : ?int
146 {
147 if ($needle instanceof parent) {
148 $needle = $needle->string;
149 } elseif (\is_array($needle) || $needle instanceof \Traversable) {
150 return parent::indexOf($needle, $offset);
151 } else {
152 $needle = (string) $needle;
153 }
154 if ('' === $needle) {
155 return null;
156 }
157 $i = $this->ignoreCase ? \stripos($this->string, $needle, $offset) : \strpos($this->string, $needle, $offset);
158 return \false === $i ? null : $i;
159 }
160 public function indexOfLast($needle, int $offset = 0) : ?int
161 {
162 if ($needle instanceof parent) {
163 $needle = $needle->string;
164 } elseif (\is_array($needle) || $needle instanceof \Traversable) {
165 return parent::indexOfLast($needle, $offset);
166 } else {
167 $needle = (string) $needle;
168 }
169 if ('' === $needle) {
170 return null;
171 }
172 $i = $this->ignoreCase ? \strripos($this->string, $needle, $offset) : \strrpos($this->string, $needle, $offset);
173 return \false === $i ? null : $i;
174 }
175 public function isUtf8() : bool
176 {
177 return '' === $this->string || \preg_match('//u', $this->string);
178 }
179 public function join(array $strings, string $lastGlue = null) : parent
180 {
181 $str = clone $this;
182 $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue . \array_pop($strings) : '';
183 $str->string = \implode($this->string, $strings) . $tail;
184 return $str;
185 }
186 public function length() : int
187 {
188 return \strlen($this->string);
189 }
190 public function lower() : parent
191 {
192 $str = clone $this;
193 $str->string = \strtolower($str->string);
194 return $str;
195 }
196 public function match(string $regexp, int $flags = 0, int $offset = 0) : array
197 {
198 $match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
199 if ($this->ignoreCase) {
200 $regexp .= 'i';
201 }
202 \set_error_handler(static function ($t, $m) {
203 throw new InvalidArgumentException($m);
204 });
205 try {
206 if (\false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
207 $lastError = \preg_last_error();
208 foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
209 if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
210 throw new RuntimeException('Matching failed with ' . $k . '.');
211 }
212 }
213 throw new RuntimeException('Matching failed with unknown error code.');
214 }
215 } finally {
216 \restore_error_handler();
217 }
218 return $matches;
219 }
220 public function padBoth(int $length, string $padStr = ' ') : parent
221 {
222 $str = clone $this;
223 $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_BOTH);
224 return $str;
225 }
226 public function padEnd(int $length, string $padStr = ' ') : parent
227 {
228 $str = clone $this;
229 $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT);
230 return $str;
231 }
232 public function padStart(int $length, string $padStr = ' ') : parent
233 {
234 $str = clone $this;
235 $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_LEFT);
236 return $str;
237 }
238 public function prepend(string ...$prefix) : parent
239 {
240 $str = clone $this;
241 $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $str->string;
242 return $str;
243 }
244 public function replace(string $from, string $to) : parent
245 {
246 $str = clone $this;
247 if ('' !== $from) {
248 $str->string = $this->ignoreCase ? \str_ireplace($from, $to, $this->string) : \str_replace($from, $to, $this->string);
249 }
250 return $str;
251 }
252 public function replaceMatches(string $fromRegexp, $to) : parent
253 {
254 if ($this->ignoreCase) {
255 $fromRegexp .= 'i';
256 }
257 if (\is_array($to)) {
258 if (!\is_callable($to)) {
259 throw new \TypeError(\sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class));
260 }
261 $replace = 'preg_replace_callback';
262 } else {
263 $replace = $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace';
264 }
265 \set_error_handler(static function ($t, $m) {
266 throw new InvalidArgumentException($m);
267 });
268 try {
269 if (null === ($string = $replace($fromRegexp, $to, $this->string))) {
270 $lastError = \preg_last_error();
271 foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
272 if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
273 throw new RuntimeException('Matching failed with ' . $k . '.');
274 }
275 }
276 throw new RuntimeException('Matching failed with unknown error code.');
277 }
278 } finally {
279 \restore_error_handler();
280 }
281 $str = clone $this;
282 $str->string = $string;
283 return $str;
284 }
285 public function reverse() : parent
286 {
287 $str = clone $this;
288 $str->string = \strrev($str->string);
289 return $str;
290 }
291 public function slice(int $start = 0, int $length = null) : parent
292 {
293 $str = clone $this;
294 $str->string = (string) \substr($this->string, $start, $length ?? \PHP_INT_MAX);
295 return $str;
296 }
297 public function snake() : parent
298 {
299 $str = $this->camel();
300 $str->string = \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], 'IAWP_SCOPED\\1_\\2', $str->string));
301 return $str;
302 }
303 public function splice(string $replacement, int $start = 0, int $length = null) : parent
304 {
305 $str = clone $this;
306 $str->string = \substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);
307 return $str;
308 }
309 public function split(string $delimiter, int $limit = null, int $flags = null) : array
310 {
311 if (1 > ($limit = $limit ?? \PHP_INT_MAX)) {
312 throw new InvalidArgumentException('Split limit must be a positive integer.');
313 }
314 if ('' === $delimiter) {
315 throw new InvalidArgumentException('Split delimiter is empty.');
316 }
317 if (null !== $flags) {
318 return parent::split($delimiter, $limit, $flags);
319 }
320 $str = clone $this;
321 $chunks = $this->ignoreCase ? \preg_split('{' . \preg_quote($delimiter) . '}iD', $this->string, $limit) : \explode($delimiter, $this->string, $limit);
322 foreach ($chunks as &$chunk) {
323 $str->string = $chunk;
324 $chunk = clone $str;
325 }
326 return $chunks;
327 }
328 public function startsWith($prefix) : bool
329 {
330 if ($prefix instanceof parent) {
331 $prefix = $prefix->string;
332 } elseif (!\is_string($prefix)) {
333 return parent::startsWith($prefix);
334 }
335 return '' !== $prefix && 0 === ($this->ignoreCase ? \strncasecmp($this->string, $prefix, \strlen($prefix)) : \strncmp($this->string, $prefix, \strlen($prefix)));
336 }
337 public function title(bool $allWords = \false) : parent
338 {
339 $str = clone $this;
340 $str->string = $allWords ? \ucwords($str->string) : \ucfirst($str->string);
341 return $str;
342 }
343 public function toUnicodeString(string $fromEncoding = null) : UnicodeString
344 {
345 return new UnicodeString($this->toCodePointString($fromEncoding)->string);
346 }
347 public function toCodePointString(string $fromEncoding = null) : CodePointString
348 {
349 $u = new CodePointString();
350 if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], \true) && \preg_match('//u', $this->string)) {
351 $u->string = $this->string;
352 return $u;
353 }
354 \set_error_handler(static function ($t, $m) {
355 throw new InvalidArgumentException($m);
356 });
357 try {
358 try {
359 $validEncoding = \false !== \mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', \true);
360 } catch (InvalidArgumentException $e) {
361 if (!\function_exists('iconv')) {
362 throw $e;
363 }
364 $u->string = \iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string);
365 return $u;
366 }
367 } finally {
368 \restore_error_handler();
369 }
370 if (!$validEncoding) {
371 throw new InvalidArgumentException(\sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252'));
372 }
373 $u->string = \mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252');
374 return $u;
375 }
376 public function trim(string $chars = " \t\n\r\x00\v\f") : parent
377 {
378 $str = clone $this;
379 $str->string = \trim($str->string, $chars);
380 return $str;
381 }
382 public function trimEnd(string $chars = " \t\n\r\x00\v\f") : parent
383 {
384 $str = clone $this;
385 $str->string = \rtrim($str->string, $chars);
386 return $str;
387 }
388 public function trimStart(string $chars = " \t\n\r\x00\v\f") : parent
389 {
390 $str = clone $this;
391 $str->string = \ltrim($str->string, $chars);
392 return $str;
393 }
394 public function upper() : parent
395 {
396 $str = clone $this;
397 $str->string = \strtoupper($str->string);
398 return $str;
399 }
400 public function width(bool $ignoreAnsiDecoration = \true) : int
401 {
402 $string = \preg_match('//u', $this->string) ? $this->string : \preg_replace('/[\\x80-\\xFF]/', '?', $this->string);
403 return (new CodePointString($string))->width($ignoreAnsiDecoration);
404 }
405 }
406