PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.0
Independent Analytics – WordPress Analytics Plugin v2.15.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 6 days ago Resources 6 days ago Slugger 6 days ago AbstractString.php 6 days ago AbstractUnicodeString.php 6 days ago ByteString.php 6 days ago CodePointString.php 6 days ago LazyString.php 6 days ago UnicodeString.php 6 days ago
ByteString.php
391 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 IAWPSCOPED\Symfony\Component\String;
12
13 use IAWPSCOPED\Symfony\Component\String\Exception\ExceptionInterface;
14 use IAWPSCOPED\Symfony\Component\String\Exception\InvalidArgumentException;
15 use IAWPSCOPED\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) : static
85 {
86 $str = clone $this;
87 $str->string .= 1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix);
88 return $str;
89 }
90 public function camel() : static
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(string|iterable|AbstractString $suffix) : bool
115 {
116 if ($suffix instanceof AbstractString) {
117 $suffix = $suffix->string;
118 } elseif (!\is_string($suffix)) {
119 return parent::endsWith($suffix);
120 }
121 return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase);
122 }
123 public function equalsTo(string|iterable|AbstractString $string) : bool
124 {
125 if ($string instanceof AbstractString) {
126 $string = $string->string;
127 } elseif (!\is_string($string)) {
128 return parent::equalsTo($string);
129 }
130 if ('' !== $string && $this->ignoreCase) {
131 return 0 === \strcasecmp($string, $this->string);
132 }
133 return $string === $this->string;
134 }
135 public function folded() : static
136 {
137 $str = clone $this;
138 $str->string = \strtolower($str->string);
139 return $str;
140 }
141 public function indexOf(string|iterable|AbstractString $needle, int $offset = 0) : ?int
142 {
143 if ($needle instanceof AbstractString) {
144 $needle = $needle->string;
145 } elseif (!\is_string($needle)) {
146 return parent::indexOf($needle, $offset);
147 }
148 if ('' === $needle) {
149 return null;
150 }
151 $i = $this->ignoreCase ? \stripos($this->string, $needle, $offset) : \strpos($this->string, $needle, $offset);
152 return \false === $i ? null : $i;
153 }
154 public function indexOfLast(string|iterable|AbstractString $needle, int $offset = 0) : ?int
155 {
156 if ($needle instanceof AbstractString) {
157 $needle = $needle->string;
158 } elseif (!\is_string($needle)) {
159 return parent::indexOfLast($needle, $offset);
160 }
161 if ('' === $needle) {
162 return null;
163 }
164 $i = $this->ignoreCase ? \strripos($this->string, $needle, $offset) : \strrpos($this->string, $needle, $offset);
165 return \false === $i ? null : $i;
166 }
167 public function isUtf8() : bool
168 {
169 return '' === $this->string || \preg_match('//u', $this->string);
170 }
171 public function join(array $strings, string $lastGlue = null) : static
172 {
173 $str = clone $this;
174 $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue . \array_pop($strings) : '';
175 $str->string = \implode($this->string, $strings) . $tail;
176 return $str;
177 }
178 public function length() : int
179 {
180 return \strlen($this->string);
181 }
182 public function lower() : static
183 {
184 $str = clone $this;
185 $str->string = \strtolower($str->string);
186 return $str;
187 }
188 public function match(string $regexp, int $flags = 0, int $offset = 0) : array
189 {
190 $match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
191 if ($this->ignoreCase) {
192 $regexp .= 'i';
193 }
194 \set_error_handler(static function ($t, $m) {
195 throw new InvalidArgumentException($m);
196 });
197 try {
198 if (\false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
199 $lastError = \preg_last_error();
200 foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
201 if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
202 throw new RuntimeException('Matching failed with ' . $k . '.');
203 }
204 }
205 throw new RuntimeException('Matching failed with unknown error code.');
206 }
207 } finally {
208 \restore_error_handler();
209 }
210 return $matches;
211 }
212 public function padBoth(int $length, string $padStr = ' ') : static
213 {
214 $str = clone $this;
215 $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_BOTH);
216 return $str;
217 }
218 public function padEnd(int $length, string $padStr = ' ') : static
219 {
220 $str = clone $this;
221 $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT);
222 return $str;
223 }
224 public function padStart(int $length, string $padStr = ' ') : static
225 {
226 $str = clone $this;
227 $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_LEFT);
228 return $str;
229 }
230 public function prepend(string ...$prefix) : static
231 {
232 $str = clone $this;
233 $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $str->string;
234 return $str;
235 }
236 public function replace(string $from, string $to) : static
237 {
238 $str = clone $this;
239 if ('' !== $from) {
240 $str->string = $this->ignoreCase ? \str_ireplace($from, $to, $this->string) : \str_replace($from, $to, $this->string);
241 }
242 return $str;
243 }
244 public function replaceMatches(string $fromRegexp, string|callable $to) : static
245 {
246 if ($this->ignoreCase) {
247 $fromRegexp .= 'i';
248 }
249 $replace = \is_array($to) || $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace';
250 \set_error_handler(static function ($t, $m) {
251 throw new InvalidArgumentException($m);
252 });
253 try {
254 if (null === ($string = $replace($fromRegexp, $to, $this->string))) {
255 $lastError = \preg_last_error();
256 foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
257 if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
258 throw new RuntimeException('Matching failed with ' . $k . '.');
259 }
260 }
261 throw new RuntimeException('Matching failed with unknown error code.');
262 }
263 } finally {
264 \restore_error_handler();
265 }
266 $str = clone $this;
267 $str->string = $string;
268 return $str;
269 }
270 public function reverse() : static
271 {
272 $str = clone $this;
273 $str->string = \strrev($str->string);
274 return $str;
275 }
276 public function slice(int $start = 0, int $length = null) : static
277 {
278 $str = clone $this;
279 $str->string = (string) \substr($this->string, $start, $length ?? \PHP_INT_MAX);
280 return $str;
281 }
282 public function snake() : static
283 {
284 $str = $this->camel();
285 $str->string = \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], 'IAWPSCOPED\\1_\\2', $str->string));
286 return $str;
287 }
288 public function splice(string $replacement, int $start = 0, int $length = null) : static
289 {
290 $str = clone $this;
291 $str->string = \substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);
292 return $str;
293 }
294 public function split(string $delimiter, int $limit = null, int $flags = null) : array
295 {
296 if (1 > ($limit = $limit ?? \PHP_INT_MAX)) {
297 throw new InvalidArgumentException('Split limit must be a positive integer.');
298 }
299 if ('' === $delimiter) {
300 throw new InvalidArgumentException('Split delimiter is empty.');
301 }
302 if (null !== $flags) {
303 return parent::split($delimiter, $limit, $flags);
304 }
305 $str = clone $this;
306 $chunks = $this->ignoreCase ? \preg_split('{' . \preg_quote($delimiter) . '}iD', $this->string, $limit) : \explode($delimiter, $this->string, $limit);
307 foreach ($chunks as &$chunk) {
308 $str->string = $chunk;
309 $chunk = clone $str;
310 }
311 return $chunks;
312 }
313 public function startsWith(string|iterable|AbstractString $prefix) : bool
314 {
315 if ($prefix instanceof AbstractString) {
316 $prefix = $prefix->string;
317 } elseif (!\is_string($prefix)) {
318 return parent::startsWith($prefix);
319 }
320 return '' !== $prefix && 0 === ($this->ignoreCase ? \strncasecmp($this->string, $prefix, \strlen($prefix)) : \strncmp($this->string, $prefix, \strlen($prefix)));
321 }
322 public function title(bool $allWords = \false) : static
323 {
324 $str = clone $this;
325 $str->string = $allWords ? \ucwords($str->string) : \ucfirst($str->string);
326 return $str;
327 }
328 public function toUnicodeString(string $fromEncoding = null) : UnicodeString
329 {
330 return new UnicodeString($this->toCodePointString($fromEncoding)->string);
331 }
332 public function toCodePointString(string $fromEncoding = null) : CodePointString
333 {
334 $u = new CodePointString();
335 if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], \true) && \preg_match('//u', $this->string)) {
336 $u->string = $this->string;
337 return $u;
338 }
339 \set_error_handler(static function ($t, $m) {
340 throw new InvalidArgumentException($m);
341 });
342 try {
343 try {
344 $validEncoding = \false !== \mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', \true);
345 } catch (InvalidArgumentException $e) {
346 if (!\function_exists('iconv')) {
347 throw $e;
348 }
349 $u->string = \iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string);
350 return $u;
351 }
352 } finally {
353 \restore_error_handler();
354 }
355 if (!$validEncoding) {
356 throw new InvalidArgumentException(\sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252'));
357 }
358 $u->string = \mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252');
359 return $u;
360 }
361 public function trim(string $chars = " \t\n\r\x00\v\f") : static
362 {
363 $str = clone $this;
364 $str->string = \trim($str->string, $chars);
365 return $str;
366 }
367 public function trimEnd(string $chars = " \t\n\r\x00\v\f") : static
368 {
369 $str = clone $this;
370 $str->string = \rtrim($str->string, $chars);
371 return $str;
372 }
373 public function trimStart(string $chars = " \t\n\r\x00\v\f") : static
374 {
375 $str = clone $this;
376 $str->string = \ltrim($str->string, $chars);
377 return $str;
378 }
379 public function upper() : static
380 {
381 $str = clone $this;
382 $str->string = \strtoupper($str->string);
383 return $str;
384 }
385 public function width(bool $ignoreAnsiDecoration = \true) : int
386 {
387 $string = \preg_match('//u', $this->string) ? $this->string : \preg_replace('/[\\x80-\\xFF]/', '?', $this->string);
388 return (new CodePointString($string))->width($ignoreAnsiDecoration);
389 }
390 }
391