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