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 { 24 NumberFormatWrapper() { 25 Reset(); 26 } 27 28 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 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 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 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