Added byte formatting methods.
This commit is contained in:
parent
8f908d7f68
commit
1cd1695429
4 changed files with 190 additions and 2 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.2307.50127
|
0.2307.52303
|
||||||
|
|
85
src/ByteFormat.php
Normal file
85
src/ByteFormat.php
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
// ByteFormat.php
|
||||||
|
// Created: 2023-07-05
|
||||||
|
// Updated: 2023-07-05
|
||||||
|
|
||||||
|
namespace Index;
|
||||||
|
|
||||||
|
final class ByteFormat {
|
||||||
|
/**
|
||||||
|
* Whether the default behaviour for the format function is decimal (power of 10) or not (power of 2).
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public const DECIMAL_DEFAULT = true;
|
||||||
|
|
||||||
|
private const SYMBOLS = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q'];
|
||||||
|
private const DIV_DECIMAL = 1000;
|
||||||
|
private const DIV_BINARY = 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a raw amount of bytes as a human readable string.
|
||||||
|
*
|
||||||
|
* @param int $bytes Number of bytes.
|
||||||
|
* @param bool $decimal Whether format as a power of 10 (e.g. MB) or a power of 2 (e.g. MiB).
|
||||||
|
* @return string Formatted byte string.
|
||||||
|
*/
|
||||||
|
public static function format(int $bytes, bool $decimal = self::DECIMAL_DEFAULT): string {
|
||||||
|
// this whole thing will be fun if i ever decide to do localisation
|
||||||
|
if($bytes === 0)
|
||||||
|
return 'Zero Bytes';
|
||||||
|
|
||||||
|
$negative = $bytes < 0;
|
||||||
|
$bytes = abs($bytes);
|
||||||
|
|
||||||
|
$power = $decimal ? self::DIV_DECIMAL : self::DIV_BINARY;
|
||||||
|
$exp = floor(log($bytes) / log($power));
|
||||||
|
|
||||||
|
$number = $bytes / pow($power, $exp);
|
||||||
|
$symbol = self::SYMBOLS[$exp];
|
||||||
|
|
||||||
|
$string = '';
|
||||||
|
if($negative)
|
||||||
|
$string .= '-';
|
||||||
|
|
||||||
|
if($bytes < $power)
|
||||||
|
$string .= $number;
|
||||||
|
else if($number < 10)
|
||||||
|
$string .= sprintf('%.2f', $number);
|
||||||
|
else
|
||||||
|
$string .= sprintf('%.1f', $number);
|
||||||
|
|
||||||
|
$string .= ' ' . $symbol;
|
||||||
|
if($symbol === '') {
|
||||||
|
$string .= 'Byte';
|
||||||
|
if($number > 1)
|
||||||
|
$string .= 's';
|
||||||
|
} else {
|
||||||
|
if(!$decimal)
|
||||||
|
$string .= 'i';
|
||||||
|
$string .= 'B';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a raw amount of bytes as a human readable string in the power of 10 (e.g. MB).
|
||||||
|
*
|
||||||
|
* @param int $bytes Number of bytes.
|
||||||
|
* @return string Formatted byte string.
|
||||||
|
*/
|
||||||
|
public static function formatDecimal(int $bytes): string {
|
||||||
|
return self::format($bytes, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a raw amount of bytes as a human readable string in the power of 2 (e.g. MiB).
|
||||||
|
*
|
||||||
|
* @param int $bytes Number of bytes.
|
||||||
|
* @return string Formatted byte string.
|
||||||
|
*/
|
||||||
|
public static function formatBinary(int $bytes): string {
|
||||||
|
return self::format($bytes, false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ final class XString {
|
||||||
/**
|
/**
|
||||||
* Counts unique characters in a string.
|
* Counts unique characters in a string.
|
||||||
*
|
*
|
||||||
* @param string String to count unique characters of.
|
* @param string $string String to count unique characters of.
|
||||||
* @return int Unique character count.
|
* @return int Unique character count.
|
||||||
*/
|
*/
|
||||||
public static function countUnique(string $string): int {
|
public static function countUnique(string $string): int {
|
||||||
|
|
103
tests/ByteFormatTest.php
Normal file
103
tests/ByteFormatTest.php
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<?php
|
||||||
|
// ByteFormatTest.php
|
||||||
|
// Created: 2023-07-05
|
||||||
|
// Updated: 2023-07-05
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Index\ByteFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ByteFormat
|
||||||
|
*/
|
||||||
|
final class ByteFormatTest extends TestCase {
|
||||||
|
public function testFormat(): void {
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(0), 'Zero Bytes');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(0), 'Zero Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(64), '64 Bytes');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(64), '64 Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-64), '-64 Bytes');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-64), '-64 Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(512), '512 Bytes');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(512), '512 Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-512), '-512 Bytes');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-512), '-512 Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1000), '1.00 KB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1000), '1000 Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1000), '-1.00 KB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1000), '-1000 Bytes');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1024), '1.02 KB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1024), '1.00 KiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1024), '-1.02 KB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1024), '-1.00 KiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1000000), '1.00 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1000000), '976.6 KiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1000000), '-1.00 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1000000), '-976.6 KiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1048576), '1.05 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1048576), '1.00 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1048576), '-1.05 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1048576), '-1.00 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(25252525), '25.3 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(25252525), '24.1 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-25252525), '-25.3 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-25252525), '-24.1 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(26476544), '26.5 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(26476544), '25.2 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-26476544), '-26.5 MB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-26476544), '-25.2 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1000000000), '1.00 GB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1000000000), '953.7 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1000000000), '-1.00 GB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1000000000), '-953.7 MiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1073741824), '1.07 GB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1073741824), '1.00 GiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1073741824), '-1.07 GB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1073741824), '-1.00 GiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1000000000000), '1.00 TB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1000000000000), '931.3 GiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1000000000000), '-1.00 TB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1000000000000), '-931.3 GiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1099511627776), '1.10 TB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1099511627776), '1.00 TiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1099511627776), '-1.10 TB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1099511627776), '-1.00 TiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1000000000000000), '1.00 PB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1000000000000000), '909.5 TiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1000000000000000), '-1.00 PB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1000000000000000), '-909.5 TiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(1125899906842624), '1.13 PB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(1125899906842624), '1.00 PiB');
|
||||||
|
|
||||||
|
$this->assertEquals(ByteFormat::formatDecimal(-1125899906842624), '-1.13 PB');
|
||||||
|
$this->assertEquals(ByteFormat::formatBinary(-1125899906842624), '-1.00 PiB');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue