- Patch #267883 by MadHarold, boombatower: parse_size() and format_size() do not use the same kilo standard.
parent
daf5005c23
commit
5fbdca023f
|
@ -161,6 +161,14 @@ define('DRUPAL_ANONYMOUS_RID', 1);
|
|||
*/
|
||||
define('DRUPAL_AUTHENTICATED_RID', 2);
|
||||
|
||||
/**
|
||||
* The number of bytes in a kilobyte. The scientific standard for kilo is 1000,
|
||||
* but used commonly in the field of computers to represent 1024 bits. For more
|
||||
* information on the different standards please visit:
|
||||
* http://en.wikipedia.org/wiki/Kilobyte.
|
||||
*/
|
||||
define('DRUPAL_KILOBYTE', 1024);
|
||||
|
||||
/**
|
||||
* No language negotiation. The default language is used.
|
||||
*/
|
||||
|
|
|
@ -1210,20 +1210,20 @@ function format_plural($count, $singular, $plural, $args = array(), $langcode =
|
|||
* Parse a given byte count.
|
||||
*
|
||||
* @param $size
|
||||
* A size expressed as a number of bytes with optional SI size and unit
|
||||
* suffix (e.g. 2, 3K, 5MB, 10G).
|
||||
* A size expressed as a number of bytes with optional SI or IEC binary unit
|
||||
* prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes).
|
||||
* @return
|
||||
* An integer representation of the size.
|
||||
* An integer representation of the size in bytes.
|
||||
*/
|
||||
function parse_size($size) {
|
||||
$suffixes = array(
|
||||
'' => 1,
|
||||
'k' => 1024,
|
||||
'm' => 1048576, // 1024 * 1024
|
||||
'g' => 1073741824, // 1024 * 1024 * 1024
|
||||
);
|
||||
if (preg_match('/([0-9]+)\s*(k|m|g)?(b?(ytes?)?)/i', $size, $match)) {
|
||||
return $match[1] * $suffixes[drupal_strtolower($match[2])];
|
||||
$unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size.
|
||||
$size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the 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(DRUPAL_KILOBYTE, stripos('bkmgtpezy', $unit[0])));
|
||||
}
|
||||
else {
|
||||
return round($size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1239,11 +1239,11 @@ function parse_size($size) {
|
|||
* A translated string representation of the size.
|
||||
*/
|
||||
function format_size($size, $langcode = NULL) {
|
||||
if ($size < 1000) {
|
||||
if ($size < DRUPAL_KILOBYTE) {
|
||||
return format_plural($size, '1 byte', '@count bytes', array(), $langcode);
|
||||
}
|
||||
else {
|
||||
$size = $size / 1000; // convert bytes to kilobytes (1000 bytes)
|
||||
$size = $size / DRUPAL_KILOBYTE; // Convert bytes to kilobytes.
|
||||
$units = array(
|
||||
t('@size KB', array(), $langcode),
|
||||
t('@size MB', array(), $langcode),
|
||||
|
@ -1255,8 +1255,8 @@ function format_size($size, $langcode = NULL) {
|
|||
t('@size YB', array(), $langcode),
|
||||
);
|
||||
foreach ($units as $unit) {
|
||||
if (round($size, 2) >= 1000) {
|
||||
$size = $size / 1000;
|
||||
if (round($size, 2) >= DRUPAL_KILOBYTE) {
|
||||
$size = $size / DRUPAL_KILOBYTE;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<?php
|
||||
// $Id$
|
||||
|
||||
class CommonFormatSizeTestCase extends DrupalWebTestCase {
|
||||
class CommonSizeTestCase extends DrupalWebTestCase {
|
||||
protected $exact_test_cases;
|
||||
protected $rounded_test_cases;
|
||||
|
||||
/**
|
||||
* Implementation of getInfo().
|
||||
*/
|
||||
function getInfo() {
|
||||
return array(
|
||||
'name' => t('Format size test'),
|
||||
'name' => t('Size parsing test'),
|
||||
'description' => t('Parse a predefined amount of bytes and compare the output with the expected value.'),
|
||||
'group' => t('System')
|
||||
);
|
||||
|
@ -18,40 +20,88 @@ class CommonFormatSizeTestCase extends DrupalWebTestCase {
|
|||
* Implementation of setUp().
|
||||
*/
|
||||
function setUp() {
|
||||
$kb = DRUPAL_KILOBYTE;
|
||||
$this->exact_test_cases = array(
|
||||
'1 byte' => 1, // byte
|
||||
'1 KB' => 1000, // kilobyte
|
||||
'1 MB' => 1000000, // megabyte
|
||||
'1 GB' => 1000000000, // gigabyte
|
||||
'1 TB' => 1000000000000, // terabyte
|
||||
'1 PB' => 1000000000000000, // petabyte
|
||||
'1 EB' => 1000000000000000000, // exabyte
|
||||
'1 ZB' => 1000000000000000000000, // zettabyte
|
||||
'1 YB' => 1000000000000000000000000, // yottabyte
|
||||
'1 byte' => 1,
|
||||
'1 KB' => $kb,
|
||||
'1 MB' => $kb * $kb,
|
||||
'1 GB' => $kb * $kb * $kb,
|
||||
'1 TB' => $kb * $kb * $kb * $kb,
|
||||
'1 PB' => $kb * $kb * $kb * $kb * $kb,
|
||||
'1 EB' => $kb * $kb * $kb * $kb * $kb * $kb,
|
||||
'1 ZB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb,
|
||||
'1 YB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb * $kb,
|
||||
);
|
||||
$this->rounded_test_cases = array(
|
||||
'2 bytes' => 2, // bytes
|
||||
'1 MB' => 999999, // 1 MB (not 1000 kilobyte!)
|
||||
'3.62 MB' => 3623651, // megabytes
|
||||
'67.23 PB' => 67234178751368124, // petabytes
|
||||
'235.35 YB' => 235346823821125814962843827, // yottabytes
|
||||
'2 bytes' => 2,
|
||||
'1 MB' => ($kb * $kb) - 1, // rounded to 1 MB (not 1000 or 1024 kilobyte!)
|
||||
round(3623651 / ($this->exact_test_cases['1 MB']), 2) . ' MB' => 3623651, // megabytes
|
||||
round(67234178751368124 / ($this->exact_test_cases['1 PB']), 2) . ' PB' => 67234178751368124, // petabytes
|
||||
round(235346823821125814962843827 / ($this->exact_test_cases['1 YB']), 2) . ' YB' => 235346823821125814962843827, // yottabytes
|
||||
);
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* testCommonFormatSize
|
||||
* Check that format_size() returns the expected string.
|
||||
*/
|
||||
function testCommonFormatSize() {
|
||||
foreach (array($this->exact_test_cases, $this->rounded_test_cases) as $test_cases) {
|
||||
foreach ($test_cases as $expected => $size) {
|
||||
$this->assertTrue(
|
||||
($result = format_size($size, NULL)) == $expected,
|
||||
$expected . " == " . $result . " (" . $size . " bytes) %s"
|
||||
foreach ($test_cases as $expected => $input) {
|
||||
$this->assertEqual(
|
||||
($result = format_size($input, NULL)),
|
||||
$expected,
|
||||
$expected . ' == ' . $result . ' (' . $input . ' bytes)'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that parse_size() returns the proper byte sizes.
|
||||
*/
|
||||
function testCommonParseSize() {
|
||||
foreach ($this->exact_test_cases as $string => $size) {
|
||||
$this->assertEqual(
|
||||
$parsed_size = parse_size($string),
|
||||
$size,
|
||||
$size . ' == ' . $parsed_size . ' (' . $string . ')'
|
||||
);
|
||||
}
|
||||
|
||||
// Some custom parsing tests
|
||||
$string = '23476892 bytes';
|
||||
$this->assertEqual(
|
||||
($parsed_size = parse_size($string)),
|
||||
$size = 23476892,
|
||||
$string . ' == ' . $parsed_size . ' bytes'
|
||||
);
|
||||
$string = '76MRandomStringThatShouldBeIgnoredByParseSize.'; // 76 MB
|
||||
$this->assertEqual(
|
||||
$parsed_size = parse_size($string),
|
||||
$size = 79691776,
|
||||
$string . ' == ' . $parsed_size . ' bytes'
|
||||
);
|
||||
$string = '76.24 Giggabyte'; // Misspeld text -> 76.24 GB
|
||||
$this->assertEqual(
|
||||
$parsed_size = parse_size($string),
|
||||
$size = 81862076662,
|
||||
$string . ' == ' . $parsed_size . ' bytes'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross-test parse_size() and format_size().
|
||||
*/
|
||||
function testCommonParseSizeFormatSize() {
|
||||
foreach ($this->exact_test_cases as $size) {
|
||||
$this->assertEqual(
|
||||
$size,
|
||||
($parsed_size = parse_size($string = format_size($size, NULL))),
|
||||
$size . ' == ' . $parsed_size . ' (' . $string . ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue