number_formatting.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/logging.h" 9#include "base/lazy_instance.h" 10#include "base/memory/scoped_ptr.h" 11#include "base/stringprintf.h" 12#include "base/string_util.h" 13#include "base/utf_string_conversions.h" 14#include "third_party/icu/public/common/unicode/ustring.h" 15#include "third_party/icu/public/i18n/unicode/numfmt.h" 16 17namespace base { 18 19namespace { 20 21// A simple wrapper around icu::NumberFormat that allows for resetting it 22// (as LazyInstance does not). 23struct 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 41LazyInstance<NumberFormatWrapper> g_number_format_int = 42 LAZY_INSTANCE_INITIALIZER; 43LazyInstance<NumberFormatWrapper> g_number_format_float = 44 LAZY_INSTANCE_INITIALIZER; 45 46} // namespace 47 48string16 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 62string16 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 78namespace testing { 79 80void 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