diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-22 20:40:22 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-22 20:40:22 +0000 |
commit | 7a3b263af6356885628add7a8843a40dbee5b8ab (patch) | |
tree | eff6140c44d29b6904b90366df65161364ea555f /ui/base/text | |
parent | efaba4815ff6786082583393ad06f8c22ef11fa0 (diff) | |
download | chromium_src-7a3b263af6356885628add7a8843a40dbee5b8ab.zip chromium_src-7a3b263af6356885628add7a8843a40dbee5b8ab.tar.gz chromium_src-7a3b263af6356885628add7a8843a40dbee5b8ab.tar.bz2 |
Localize strings, speeds.
BUG=86527
TEST=run in non-English. For European languages, during a download the decimal separators should be commas (e.g. "0,0 MB"). (The speeds are in strings files and might take a little time to run through the translation machinery.)
Review URL: http://codereview.chromium.org/7189076
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90092 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/text')
-rw-r--r-- | ui/base/text/bytes_formatting.cc | 110 | ||||
-rw-r--r-- | ui/base/text/bytes_formatting.h | 55 | ||||
-rw-r--r-- | ui/base/text/bytes_formatting_unittest.cc | 79 |
3 files changed, 244 insertions, 0 deletions
diff --git a/ui/base/text/bytes_formatting.cc b/ui/base/text/bytes_formatting.cc new file mode 100644 index 0000000..6399b3c --- /dev/null +++ b/ui/base/text/bytes_formatting.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/text/bytes_formatting.h" + +#include "base/i18n/number_formatting.h" +#include "base/logging.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "grit/app_strings.h" +#include "ui/base/l10n/l10n_util.h" + +namespace ui { + +namespace { + +// Byte suffix string constants. These both must match the DataUnits enum. +const int kByteStrings[] = { + IDS_APP_BYTES, + IDS_APP_KIBIBYTES, + IDS_APP_MEBIBYTES, + IDS_APP_GIBIBYTES, + IDS_APP_TEBIBYTES, + IDS_APP_PEBIBYTES +}; + +const int kSpeedStrings[] = { + IDS_APP_BYTES_PER_SECOND, + IDS_APP_KIBIBYTES_PER_SECOND, + IDS_APP_MEBIBYTES_PER_SECOND, + IDS_APP_GIBIBYTES_PER_SECOND, + IDS_APP_TEBIBYTES_PER_SECOND, + IDS_APP_PEBIBYTES_PER_SECOND +}; + +string16 FormatBytesInternal(int64 bytes, + DataUnits units, + bool show_units, + const int* const suffix) { + DCHECK(units >= DATA_UNITS_BYTE && units <= DATA_UNITS_PEBIBYTE); + if (bytes < 0) { + NOTREACHED() << "Negative bytes value"; + return string16(); + } + + // Put the quantity in the right units. + double unit_amount = static_cast<double>(bytes); + for (int i = 0; i < units; ++i) + unit_amount /= 1024.0; + + int fractional_digits = 0; + if (bytes != 0 && units != DATA_UNITS_BYTE && unit_amount < 100) + fractional_digits = 1; + + string16 result = base::FormatDouble(unit_amount, fractional_digits); + + if (show_units) + result = l10n_util::GetStringFUTF16(suffix[units], result); + + return result; +} + +} // namespace + +DataUnits GetByteDisplayUnits(int64 bytes) { + // The byte thresholds at which we display amounts. A byte count is displayed + // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1]. + // This must match the DataUnits enum. + static const int64 kUnitThresholds[] = { + 0, // DATA_UNITS_BYTE, + 3 * (1LL << 10), // DATA_UNITS_KIBIBYTE, + 2 * (1LL << 20), // DATA_UNITS_MEBIBYTE, + 1LL << 30, // DATA_UNITS_GIBIBYTE, + 1LL << 40, // DATA_UNITS_TEBIBYTE, + 1LL << 50 // DATA_UNITS_PEBIBYTE, + }; + + if (bytes < 0) { + NOTREACHED() << "Negative bytes value"; + return DATA_UNITS_BYTE; + } + + int unit_index = arraysize(kUnitThresholds); + while (--unit_index > 0) { + if (bytes >= kUnitThresholds[unit_index]) + break; + } + + DCHECK(unit_index >= DATA_UNITS_BYTE && unit_index <= DATA_UNITS_PEBIBYTE); + return DataUnits(unit_index); +} + +string16 FormatBytesWithUnits(int64 bytes, DataUnits units, bool show_units) { + return FormatBytesInternal(bytes, units, show_units, kByteStrings); +} + +string16 FormatSpeedWithUnits(int64 bytes, DataUnits units, bool show_units) { + return FormatBytesInternal(bytes, units, show_units, kSpeedStrings); +} + +string16 FormatBytes(int64 bytes) { + return FormatBytesWithUnits(bytes, GetByteDisplayUnits(bytes), true); +} + +string16 FormatSpeed(int64 bytes) { + return FormatSpeedWithUnits(bytes, GetByteDisplayUnits(bytes), true); +} + +} // namespace ui diff --git a/ui/base/text/bytes_formatting.h b/ui/base/text/bytes_formatting.h new file mode 100644 index 0000000..aef8f01 --- /dev/null +++ b/ui/base/text/bytes_formatting.h @@ -0,0 +1,55 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_TEXT_BYTES_FORMATTING_H_ +#define UI_BASE_TEXT_BYTES_FORMATTING_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/string16.h" + +namespace ui { + +// Simple API ------------------------------------------------------------------ + +// Simple call to return a byte quantity as a string in human-readable format. +// Ex: FormatBytes(512) => "512 B" +// Ex: FormatBytes(101479) => "99.1 kB" +string16 FormatBytes(int64 bytes); + +// Simple call to return a speed as a string in human-readable format. +// Ex: FormatSpeed(512) => "512 B/s" +// Ex: FormatSpeed(101479) => "99.1 kB/s" +string16 FormatSpeed(int64 bytes); + +// Less-Simple API ------------------------------------------------------------- + +enum DataUnits { + DATA_UNITS_BYTE = 0, + DATA_UNITS_KIBIBYTE, + DATA_UNITS_MEBIBYTE, + DATA_UNITS_GIBIBYTE, + DATA_UNITS_TEBIBYTE, + DATA_UNITS_PEBIBYTE +}; + +// Return the unit type that is appropriate for displaying the amount of bytes +// passed in. Most of the time, an explicit call to this isn't necessary; just +// use FormatBytes()/FormatSpeed() above. +DataUnits GetByteDisplayUnits(int64 bytes); + +// Return a byte quantity as a string in human-readable format with an optional +// unit suffix. Specify in the |units| argument the units to be used. +// Ex: FormatBytes(512, DATA_UNITS_KIBIBYTE, true) => "0.5 kB" +// Ex: FormatBytes(10*1024, DATA_UNITS_MEBIBYTE, false) => "0.1" +string16 FormatBytesWithUnits(int64 bytes, DataUnits units, bool show_units); + +// As above, but with "/s" units for speed values. +// Ex: FormatSpeed(512, DATA_UNITS_KIBIBYTE, true) => "0.5 kB/s" +// Ex: FormatSpeed(10*1024, DATA_UNITS_MEBIBYTE, false) => "0.1" +string16 FormatSpeedWithUnits(int64 bytes, DataUnits units, bool show_units); + +} // namespace ui + +#endif // UI_BASE_TEXT_BYTES_FORMATTING_H_ diff --git a/ui/base/text/bytes_formatting_unittest.cc b/ui/base/text/bytes_formatting_unittest.cc new file mode 100644 index 0000000..a214259 --- /dev/null +++ b/ui/base/text/bytes_formatting_unittest.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/text/bytes_formatting.h" + +namespace ui { + +TEST(BytesFormattingTest, GetByteDisplayUnits) { + static const struct { + int64 bytes; + DataUnits expected; + } cases[] = { + {0, DATA_UNITS_BYTE}, + {512, DATA_UNITS_BYTE}, + {10*1024, DATA_UNITS_KIBIBYTE}, + {10*1024*1024, DATA_UNITS_MEBIBYTE}, + {10LL*1024*1024*1024, DATA_UNITS_GIBIBYTE}, + {10LL*1024*1024*1024*1024, DATA_UNITS_TEBIBYTE}, + {~(1LL<<63), DATA_UNITS_PEBIBYTE}, +#ifdef NDEBUG + {-1, DATA_UNITS_BYTE}, +#endif + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) + EXPECT_EQ(cases[i].expected, GetByteDisplayUnits(cases[i].bytes)); +} + +TEST(BytesFormattingTest, FormatBytes) { + static const struct { + int64 bytes; + DataUnits units; + const char* expected; + const char* expected_with_units; + } cases[] = { + // Expected behavior: we show one post-decimal digit when we have + // under two pre-decimal digits, except in cases where it makes no + // sense (zero or bytes). + // Since we switch units once we cross the 1000 mark, this keeps + // the display of file sizes or bytes consistently around three + // digits. + {0, DATA_UNITS_BYTE, "0", "0 B"}, + {512, DATA_UNITS_BYTE, "512", "512 B"}, + {512, DATA_UNITS_KIBIBYTE, "0.5", "0.5 kB"}, + {1024*1024, DATA_UNITS_KIBIBYTE, "1,024", "1,024 kB"}, + {1024*1024, DATA_UNITS_MEBIBYTE, "1.0", "1.0 MB"}, + {1024*1024*1024, DATA_UNITS_GIBIBYTE, "1.0", "1.0 GB"}, + {10LL*1024*1024*1024, DATA_UNITS_GIBIBYTE, "10.0", "10.0 GB"}, + {99LL*1024*1024*1024, DATA_UNITS_GIBIBYTE, "99.0", "99.0 GB"}, + {105LL*1024*1024*1024, DATA_UNITS_GIBIBYTE, "105", "105 GB"}, + {105LL*1024*1024*1024 + 500LL*1024*1024, DATA_UNITS_GIBIBYTE, + "105", "105 GB"}, + {~(1LL<<63), DATA_UNITS_GIBIBYTE, "8,589,934,592", "8,589,934,592 GB"}, + {~(1LL<<63), DATA_UNITS_PEBIBYTE, "8,192", "8,192 PB"}, + + {99*1024 + 103, DATA_UNITS_KIBIBYTE, "99.1", "99.1 kB"}, + {1024*1024 + 103, DATA_UNITS_KIBIBYTE, "1,024", "1,024 kB"}, + {1024*1024 + 205 * 1024, DATA_UNITS_MEBIBYTE, "1.2", "1.2 MB"}, + {1024*1024*1024 + (927 * 1024*1024), DATA_UNITS_GIBIBYTE, + "1.9", "1.9 GB"}, + {10LL*1024*1024*1024, DATA_UNITS_GIBIBYTE, "10.0", "10.0 GB"}, + {100LL*1024*1024*1024, DATA_UNITS_GIBIBYTE, "100", "100 GB"}, +#ifdef NDEBUG + {-1, DATA_UNITS_BYTE, "", ""}, +#endif + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { + EXPECT_EQ(ASCIIToUTF16(cases[i].expected), + FormatBytesWithUnits(cases[i].bytes, cases[i].units, false)); + EXPECT_EQ(ASCIIToUTF16(cases[i].expected_with_units), + FormatBytesWithUnits(cases[i].bytes, cases[i].units, true)); + } +} + +} // namespace ui |