-
Notifications
You must be signed in to change notification settings - Fork 1
/
Bytes.php
140 lines (127 loc) · 3.44 KB
/
Bytes.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
namespace Drupal\Component\Utility;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Provides helper methods for byte conversions.
*/
class Bytes {
/**
* The number of bytes in a kilobyte.
*
* @see http://wikipedia.org/wiki/Kilobyte
*/
const KILOBYTE = 1024;
/**
* The allowed suffixes of a bytes string in lowercase.
*
* @see http://wikipedia.org/wiki/Kilobyte
*/
const ALLOWED_SUFFIXES = [
'',
'b',
'byte',
'bytes',
'k',
'kb',
'kilobyte',
'kilobytes',
'm',
'mb',
'megabyte',
'megabytes',
'g',
'gb',
'gigabyte',
'gigabytes',
't',
'tb',
'terabyte',
'terabytes',
'p',
'pb',
'petabyte',
'petabytes',
'e',
'eb',
'exabyte',
'exabytes',
'z',
'zb',
'zettabyte',
'zettabytes',
'y',
'yb',
'yottabyte',
'yottabytes',
];
/**
* Parses a given byte size.
*
* @param int|float|string $size
* An integer, float, or string size expressed as a number of bytes with
* optional SI or IEC binary unit prefix (e.g. 2, 2.4, 3K, 5MB, 10G, 6GiB,
* 8 bytes, 9mbytes).
*
* @return float
* The floating point value of the size in bytes.
*/
public static function toNumber($size): float {
// Remove the non-unit characters from the size.
$unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
// Remove the non-numeric characters from the size.
$size = preg_replace('/[^0-9\.]/', '', $size);
if ($unit) {
// Find the position of the unit in the ordered string which is the power
// of magnitude to multiply a kilobyte by.
return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
}
else {
// Ensure size is a proper number type.
return round((float) $size);
}
}
/**
* Validate that a string is a representation of a number of bytes.
*
* @param string $string
* The string to validate.
*
* @return bool
* TRUE if the string is valid, FALSE otherwise.
*/
public static function validate($string): bool {
// Ensure that the string starts with a numeric character.
if (!preg_match('/^[0-9]/', $string)) {
return FALSE;
}
// Remove the numeric characters from the beginning of the value.
$string = preg_replace('/^[0-9\.]+/', '', $string);
// Remove remaining spaces from the value.
$string = trim($string);
return in_array(strtolower($string), self::ALLOWED_SUFFIXES);
}
/**
* Validates a string is a representation of a number of bytes.
*
* To be used with the `Callback` constraint.
*
* @param string|int|float|null $value
* The string, integer or float to validate.
* @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
* The validation execution context.
*
* @see \Symfony\Component\Validator\Constraints\CallbackValidator
* @see core/config/schema/core.data_types.schema.yml
*/
public static function validateConstraint(string|int|float|null $value, ExecutionContextInterface $context): void {
// Ignore NULL values (i.e. support `nullable: true`).
if ($value === NULL) {
return;
}
if (!self::validate((string) $value)) {
$context->addViolation('This value must be a number of bytes, optionally with a unit such as "MB" or "megabytes". %value does not represent a number of bytes.', [
'%value' => $value,
]);
}
}
}