Commit 5fbdca02 authored by Dries's avatar Dries

- Patch #267883 by MadHarold, boombatower: parse_size() and format_size() do...

- Patch #267883 by MadHarold, boombatower: parse_size() and format_size() do not use the same kilo standard.
parent daf5005c
......@@ -161,6 +161,14 @@
*/
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;
......
<?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 . ')'
);
}
}
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment