1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/i18n/number_formatting.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include "base/format_macros.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/i18n/message_formatter.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/i18n/unicodestring.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/lazy_instance.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
19*635a8641SAndroid Build Coastguard Worker #include "third_party/icu/source/common/unicode/ustring.h"
20*635a8641SAndroid Build Coastguard Worker #include "third_party/icu/source/i18n/unicode/numfmt.h"
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Worker namespace base {
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker namespace {
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard Worker // A simple wrapper around icu::NumberFormat that allows for resetting it
27*635a8641SAndroid Build Coastguard Worker // (as LazyInstance does not).
28*635a8641SAndroid Build Coastguard Worker struct NumberFormatWrapper {
NumberFormatWrapperbase::__anon4141fcdb0111::NumberFormatWrapper29*635a8641SAndroid Build Coastguard Worker NumberFormatWrapper() {
30*635a8641SAndroid Build Coastguard Worker Reset();
31*635a8641SAndroid Build Coastguard Worker }
32*635a8641SAndroid Build Coastguard Worker
Resetbase::__anon4141fcdb0111::NumberFormatWrapper33*635a8641SAndroid Build Coastguard Worker void Reset() {
34*635a8641SAndroid Build Coastguard Worker // There's no ICU call to destroy a NumberFormat object other than
35*635a8641SAndroid Build Coastguard Worker // operator delete, so use the default Delete, which calls operator delete.
36*635a8641SAndroid Build Coastguard Worker // This can cause problems if a different allocator is used by this file
37*635a8641SAndroid Build Coastguard Worker // than by ICU.
38*635a8641SAndroid Build Coastguard Worker UErrorCode status = U_ZERO_ERROR;
39*635a8641SAndroid Build Coastguard Worker number_format.reset(icu::NumberFormat::createInstance(status));
40*635a8641SAndroid Build Coastguard Worker DCHECK(U_SUCCESS(status));
41*635a8641SAndroid Build Coastguard Worker }
42*635a8641SAndroid Build Coastguard Worker
43*635a8641SAndroid Build Coastguard Worker std::unique_ptr<icu::NumberFormat> number_format;
44*635a8641SAndroid Build Coastguard Worker };
45*635a8641SAndroid Build Coastguard Worker
46*635a8641SAndroid Build Coastguard Worker LazyInstance<NumberFormatWrapper>::DestructorAtExit g_number_format_int =
47*635a8641SAndroid Build Coastguard Worker LAZY_INSTANCE_INITIALIZER;
48*635a8641SAndroid Build Coastguard Worker LazyInstance<NumberFormatWrapper>::DestructorAtExit g_number_format_float =
49*635a8641SAndroid Build Coastguard Worker LAZY_INSTANCE_INITIALIZER;
50*635a8641SAndroid Build Coastguard Worker
51*635a8641SAndroid Build Coastguard Worker } // namespace
52*635a8641SAndroid Build Coastguard Worker
FormatNumber(int64_t number)53*635a8641SAndroid Build Coastguard Worker string16 FormatNumber(int64_t number) {
54*635a8641SAndroid Build Coastguard Worker icu::NumberFormat* number_format =
55*635a8641SAndroid Build Coastguard Worker g_number_format_int.Get().number_format.get();
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker if (!number_format) {
58*635a8641SAndroid Build Coastguard Worker // As a fallback, just return the raw number in a string.
59*635a8641SAndroid Build Coastguard Worker return ASCIIToUTF16(StringPrintf("%" PRId64, number));
60*635a8641SAndroid Build Coastguard Worker }
61*635a8641SAndroid Build Coastguard Worker icu::UnicodeString ustr;
62*635a8641SAndroid Build Coastguard Worker number_format->format(number, ustr);
63*635a8641SAndroid Build Coastguard Worker
64*635a8641SAndroid Build Coastguard Worker return i18n::UnicodeStringToString16(ustr);
65*635a8641SAndroid Build Coastguard Worker }
66*635a8641SAndroid Build Coastguard Worker
FormatDouble(double number,int fractional_digits)67*635a8641SAndroid Build Coastguard Worker string16 FormatDouble(double number, int fractional_digits) {
68*635a8641SAndroid Build Coastguard Worker icu::NumberFormat* number_format =
69*635a8641SAndroid Build Coastguard Worker g_number_format_float.Get().number_format.get();
70*635a8641SAndroid Build Coastguard Worker
71*635a8641SAndroid Build Coastguard Worker if (!number_format) {
72*635a8641SAndroid Build Coastguard Worker // As a fallback, just return the raw number in a string.
73*635a8641SAndroid Build Coastguard Worker return ASCIIToUTF16(StringPrintf("%f", number));
74*635a8641SAndroid Build Coastguard Worker }
75*635a8641SAndroid Build Coastguard Worker number_format->setMaximumFractionDigits(fractional_digits);
76*635a8641SAndroid Build Coastguard Worker number_format->setMinimumFractionDigits(fractional_digits);
77*635a8641SAndroid Build Coastguard Worker icu::UnicodeString ustr;
78*635a8641SAndroid Build Coastguard Worker number_format->format(number, ustr);
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker return i18n::UnicodeStringToString16(ustr);
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker
FormatPercent(int number)83*635a8641SAndroid Build Coastguard Worker string16 FormatPercent(int number) {
84*635a8641SAndroid Build Coastguard Worker return i18n::MessageFormatter::FormatWithNumberedArgs(
85*635a8641SAndroid Build Coastguard Worker ASCIIToUTF16("{0,number,percent}"), static_cast<double>(number) / 100.0);
86*635a8641SAndroid Build Coastguard Worker }
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard Worker namespace testing {
89*635a8641SAndroid Build Coastguard Worker
ResetFormatters()90*635a8641SAndroid Build Coastguard Worker void ResetFormatters() {
91*635a8641SAndroid Build Coastguard Worker g_number_format_int.Get().Reset();
92*635a8641SAndroid Build Coastguard Worker g_number_format_float.Get().Reset();
93*635a8641SAndroid Build Coastguard Worker }
94*635a8641SAndroid Build Coastguard Worker
95*635a8641SAndroid Build Coastguard Worker } // namespace testing
96*635a8641SAndroid Build Coastguard Worker
97*635a8641SAndroid Build Coastguard Worker } // namespace base
98