1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @author: Viskov Sergey |
4
|
|
|
* @date : 3/24/16 |
5
|
|
|
* @time : 6:23 PM |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace LTDBeget\structures\informationUnits\base; |
9
|
|
|
|
10
|
|
|
use LTDBeget\structures\informationUnits\Bytes; |
11
|
|
|
use LTDBeget\structures\informationUnits\KiloBytes; |
12
|
|
|
use LTDBeget\structures\informationUnits\MegaBytes; |
13
|
|
|
use LTDBeget\structures\informationUnits\GigaBytes; |
14
|
|
|
use LTDBeget\structures\informationUnits\TeraBytes; |
15
|
|
|
use LTDBeget\structures\informationUnits\PetaBytes; |
16
|
|
|
|
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class InformationUnit |
20
|
|
|
* |
21
|
|
|
* @package LTDBeget\structures\informationUnits\base |
22
|
|
|
*/ |
23
|
|
|
abstract class InformationUnit |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* InformationUnit constructor. |
27
|
|
|
* |
28
|
|
|
* @param float $amount |
29
|
|
|
* |
30
|
|
|
* @throws \OutOfBoundsException |
31
|
|
|
*/ |
32
|
|
|
public function __construct(float $amount) |
33
|
|
|
{ |
34
|
|
|
if($amount < 0) { |
35
|
|
|
throw new \OutOfBoundsException('Only positive ammount more then zero allowed'); |
36
|
|
|
} |
37
|
|
|
$this->amount = $amount; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @return float |
42
|
|
|
*/ |
43
|
|
|
public function getAmount() : float |
44
|
|
|
{ |
45
|
|
|
return $this->amount; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @return string |
50
|
|
|
*/ |
51
|
|
|
public function getDimension() : string |
52
|
|
|
{ |
53
|
|
|
return self::$dimensionName[$this->dimension]; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @param InformationUnit $unit |
58
|
|
|
* |
59
|
|
|
* @return InformationUnit |
60
|
|
|
*/ |
61
|
|
|
public function add(InformationUnit $unit) : self |
62
|
|
|
{ |
63
|
|
|
$value = self::convert($unit->getAmount(), $unit->getDimensionCode(), $this->getDimensionCode()); |
64
|
|
|
$this->amount += $value; |
65
|
|
|
|
66
|
|
|
return $this; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param InformationUnit $unit |
71
|
|
|
* |
72
|
|
|
* @return InformationUnit |
73
|
|
|
* @throws \OutOfBoundsException |
74
|
|
|
*/ |
75
|
|
|
public function subtract(InformationUnit $unit) : self |
76
|
|
|
{ |
77
|
|
|
$value = self::convert($unit->getAmount(), $unit->getDimensionCode(), $this->getDimensionCode()); |
78
|
|
|
$result = $this->getAmount() - $value; |
79
|
|
|
|
80
|
|
|
if($result < 0) { |
81
|
|
|
throw new \OutOfBoundsException('Cannot subtract, less or equal zero result'); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$this->amount = $result; |
85
|
|
|
|
86
|
|
|
return $this; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @param float $number |
91
|
|
|
* |
92
|
|
|
* @return InformationUnit |
93
|
|
|
*/ |
94
|
|
|
public function multiply(float $number) : self |
95
|
|
|
{ |
96
|
|
|
$this->amount *= $number; |
97
|
|
|
|
98
|
|
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @param float $number |
103
|
|
|
* |
104
|
|
|
* @return InformationUnit |
105
|
|
|
* @throws \OutOfBoundsException |
106
|
|
|
*/ |
107
|
|
|
public function divide(float $number) : self |
108
|
|
|
{ |
109
|
|
|
/** @noinspection TypeUnsafeComparisonInspection */ |
110
|
|
|
if($number == 0) { |
111
|
|
|
throw new \OutOfBoundsException('Cannot divide on zero'); |
112
|
|
|
} |
113
|
|
|
$this->amount /= $number; |
114
|
|
|
|
115
|
|
|
return $this; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @return Bytes |
120
|
|
|
* @throws \OutOfBoundsException |
121
|
|
|
*/ |
122
|
|
|
public function toB() : Bytes |
123
|
|
|
{ |
124
|
|
|
return new Bytes(self::convert($this->getAmount(), $this->getDimensionCode(), self::$byte)); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* @return KiloBytes |
129
|
|
|
* @throws \OutOfBoundsException |
130
|
|
|
*/ |
131
|
|
|
public function toKB() : KiloBytes |
132
|
|
|
{ |
133
|
|
|
return new KiloBytes(self::convert($this->getAmount(), $this->getDimensionCode(), self::$kiloByte)); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* @return MegaBytes |
138
|
|
|
* @throws \OutOfBoundsException |
139
|
|
|
*/ |
140
|
|
|
public function toMB() : MegaBytes |
141
|
|
|
{ |
142
|
|
|
return new MegaBytes(self::convert($this->getAmount(), $this->getDimensionCode(), self::$megaByte)); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* @return GigaBytes |
147
|
|
|
* @throws \OutOfBoundsException |
148
|
|
|
*/ |
149
|
|
|
public function toGB() : GigaBytes |
150
|
|
|
{ |
151
|
|
|
return new GigaBytes(self::convert($this->getAmount(), $this->getDimensionCode(), self::$gigaByte)); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* @return TeraBytes |
156
|
|
|
* @throws \OutOfBoundsException |
157
|
|
|
*/ |
158
|
|
|
public function toTB() : TeraBytes |
159
|
|
|
{ |
160
|
|
|
return new TeraBytes(self::convert($this->getAmount(), $this->getDimensionCode(), self::$teraByte)); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* @return PetaBytes |
165
|
|
|
* @throws \OutOfBoundsException |
166
|
|
|
*/ |
167
|
|
|
public function toPB() : PetaBytes |
168
|
|
|
{ |
169
|
|
|
return new PetaBytes(self::convert($this->getAmount(), $this->getDimensionCode(), self::$petaByte)); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* @return string |
174
|
|
|
*/ |
175
|
|
|
public function __toString() : string |
176
|
|
|
{ |
177
|
|
|
return $this->getAmount(); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* @return string |
182
|
|
|
*/ |
183
|
|
|
public function asHumanReadableString() : string |
184
|
|
|
{ |
185
|
|
|
return $this->getAmount() . ' ' . $this->getDimension(); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* @param float $value |
190
|
|
|
* @param int $fromDimension |
191
|
|
|
* @param int $toDimension |
192
|
|
|
* |
193
|
|
|
* @return float |
194
|
|
|
* |
195
|
|
|
*/ |
196
|
|
|
protected static function convert(float $value, int $fromDimension, int $toDimension) : float |
197
|
|
|
{ |
198
|
|
View Code Duplication |
if($fromDimension > $toDimension) { |
|
|
|
|
199
|
|
|
$numberOfMultiplies = $fromDimension - $toDimension; |
200
|
|
|
for($i = 0; $i < $numberOfMultiplies; $i++) { |
201
|
|
|
$value *= self::$multiplier; |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
205
|
|
View Code Duplication |
if($fromDimension < $toDimension) { |
|
|
|
|
206
|
|
|
$numberOfDivides = $toDimension - $fromDimension; |
207
|
|
|
for($i = 0; $i < $numberOfDivides; $i++) { |
208
|
|
|
$value /= self::$multiplier; |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
return $value; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* @return int |
217
|
|
|
*/ |
218
|
|
|
protected function getDimensionCode() : int |
219
|
|
|
{ |
220
|
|
|
return $this->dimension; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* @var int |
225
|
|
|
*/ |
226
|
|
|
protected static $multiplier = 1024; |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* Dimension codes |
230
|
|
|
*/ |
231
|
|
|
protected static $byte = 1; |
232
|
|
|
protected static $kiloByte = 2; |
233
|
|
|
protected static $megaByte = 3; |
234
|
|
|
protected static $gigaByte = 4; |
235
|
|
|
protected static $teraByte = 5; |
236
|
|
|
protected static $petaByte = 6; |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* @var array |
240
|
|
|
*/ |
241
|
|
|
protected static $dimensionName = [ |
242
|
|
|
1 => 'B', |
243
|
|
|
2 => 'kB', |
244
|
|
|
3 => 'MB', |
245
|
|
|
4 => 'GB', |
246
|
|
|
5 => 'TB', |
247
|
|
|
6 => 'PB' |
248
|
|
|
]; |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @var int |
252
|
|
|
*/ |
253
|
|
|
protected $dimension; |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* @var float |
257
|
|
|
*/ |
258
|
|
|
private $amount; |
259
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.