diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-24 05:14:04 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-24 05:14:04 +0000 |
commit | 07ae2c333da12779c87eefcd65f4272e389766f3 (patch) | |
tree | d13dc876544bd5b65e00f1e4db8573c4551dcf8d | |
parent | a53ef0492a5c34542d5b1d607f848fb7b45002ba (diff) | |
download | chromium_src-07ae2c333da12779c87eefcd65f4272e389766f3.zip chromium_src-07ae2c333da12779c87eefcd65f4272e389766f3.tar.gz chromium_src-07ae2c333da12779c87eefcd65f4272e389766f3.tar.bz2 |
Adds a method to sort the elements of a vector by invoking a method on
each that returns a string. The strings are then compared using a
collator, or operator < if no collator is found.
I'm going to use this for sorting bookmarks.
BUG=1750
TEST=none yet
Review URL: http://codereview.chromium.org/20484
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10252 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/common/l10n_util.cc | 60 | ||||
-rw-r--r-- | chrome/common/l10n_util.h | 70 | ||||
-rw-r--r-- | chrome/common/l10n_util_unittest.cc | 32 |
3 files changed, 127 insertions, 35 deletions
diff --git a/chrome/common/l10n_util.cc b/chrome/common/l10n_util.cc index 6fb5286..c576a4b 100644 --- a/chrome/common/l10n_util.cc +++ b/chrome/common/l10n_util.cc @@ -25,8 +25,6 @@ #if defined(OS_WIN) #include "chrome/views/view.h" #endif // defined(OS_WIN) -#include "unicode/rbbi.h" -#include "unicode/uchar.h" // TODO(playmobil): remove this undef once SkPostConfig.h is fixed. // skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use @@ -210,35 +208,6 @@ std::wstring GetSystemLocale() { return ASCIIToWide(ret); } -// Compares the character data stored in two different strings by specified -// Collator instance. -UCollationResult CompareStringWithCollator(const Collator* collator, - const std::wstring& lhs, - const std::wstring& rhs) { - DCHECK(collator); - UErrorCode error = U_ZERO_ERROR; -#if defined(WCHAR_T_IS_UTF32) - // Need to convert to UTF-16 to be compatible with UnicodeString's - // constructor. - string16 lhs_utf16 = WideToUTF16(lhs); - string16 rhs_utf16 = WideToUTF16(rhs); - - UCollationResult result = collator->compare( - static_cast<const UChar*>(lhs_utf16.c_str()), - static_cast<int>(lhs_utf16.length()), - static_cast<const UChar*>(rhs_utf16.c_str()), - static_cast<int>(rhs_utf16.length()), - error); -#else - UCollationResult result = collator->compare( - static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()), - static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()), - error); -#endif - DCHECK(U_SUCCESS(error)); - return result; -} - } // namespace namespace l10n_util { @@ -671,6 +640,35 @@ void HWNDSetRTLLayout(HWND hwnd) { } #endif // defined(OS_WIN) +// Compares the character data stored in two different strings by specified +// Collator instance. +UCollationResult CompareStringWithCollator(const Collator* collator, + const std::wstring& lhs, + const std::wstring& rhs) { + DCHECK(collator); + UErrorCode error = U_ZERO_ERROR; +#if defined(WCHAR_T_IS_UTF32) + // Need to convert to UTF-16 to be compatible with UnicodeString's + // constructor. + string16 lhs_utf16 = WideToUTF16(lhs); + string16 rhs_utf16 = WideToUTF16(rhs); + + UCollationResult result = collator->compare( + static_cast<const UChar*>(lhs_utf16.c_str()), + static_cast<int>(lhs_utf16.length()), + static_cast<const UChar*>(rhs_utf16.c_str()), + static_cast<int>(rhs_utf16.length()), + error); +#else + UCollationResult result = collator->compare( + static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()), + static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()), + error); +#endif + DCHECK(U_SUCCESS(error)); + return result; +} + // Specialization of operator() method for std::wstring version. template <> bool StringComparator<std::wstring>::operator()(const std::wstring& lhs, diff --git a/chrome/common/l10n_util.h b/chrome/common/l10n_util.h index c0a5d0d..51160cd 100644 --- a/chrome/common/l10n_util.h +++ b/chrome/common/l10n_util.h @@ -23,9 +23,11 @@ #include "base/scoped_ptr.h" #include "base/string16.h" #include "base/string_util.h" -#include "third_party/icu38/public/common/unicode/ubidi.h" #include "unicode/coll.h" #include "unicode/locid.h" +#include "unicode/rbbi.h" +#include "unicode/ubidi.h" +#include "unicode/uchar.h" class FilePath; class PrefService; @@ -198,6 +200,72 @@ int DefaultCanvasTextAlignment(); void HWNDSetRTLLayout(HWND hwnd); #endif +// Compares the two strings using the specified collator. +UCollationResult CompareStringWithCollator(const Collator* collator, + const std::wstring& lhs, + const std::wstring& rhs); + +// Used by SortStringsUsingMethod. Invokes a method on the objects passed to +// operator (), comparing the string results using a collator. +template <class T, class Method> +class StringMethodComparatorWithCollator : + public std::binary_function<const std::wstring&, + const std::wstring&, + bool> { + public: + StringMethodComparatorWithCollator(Collator* collator, Method method) + : collator_(collator), + method_(method) { } + + // Returns true if lhs preceeds rhs. + bool operator() (T* lhs_t, T* rhs_t) { + return CompareStringWithCollator(collator_, (lhs_t->*method_)(), + (rhs_t->*method_)()) == UCOL_LESS; + } + + private: + Collator* collator_; + Method method_; +}; + +// Used by SortStringsUsingMethod. Invokes a method on the objects passed to +// operator (), comparing the string results using <. +template <class T, class Method> +class StringMethodComparator : public std::binary_function<const std::wstring&, + const std::wstring&, + bool> { + public: + explicit StringMethodComparator(Method method) : method_(method) { } + + // Returns true if lhs preceeds rhs. + bool operator() (T* lhs_t, T* rhs_t) { + return (lhs_t->*method_)() < (rhs_t->*method_)(); + } + + private: + Method method_; +}; + +// Sorts the objects in |elements| using the method |method|, which must return +// a string. Sorting is done using a collator, unless a collator can not be +// found in which case the strings are sorted using the operator <. +template <class T, class Method> +void SortStringsUsingMethod(const std::wstring& locale, + std::vector<T*>* elements, + Method method) { + UErrorCode error = U_ZERO_ERROR; + Locale loc(WideToUTF8(locale).c_str()); + scoped_ptr<Collator> collator(Collator::createInstance(loc, error)); + if (U_FAILURE(error)) { + sort(elements->begin(), elements->end(), + StringMethodComparator<T,Method>(method)); + return; + } + + std::sort(elements->begin(), elements->end(), + StringMethodComparatorWithCollator<T,Method>(collator.get(), method)); +} + // Compares two elements' string keys and returns true if the first element's // string key is less than the second element's string key. The Element must // have a method like the follow format to return the string key. diff --git a/chrome/common/l10n_util_unittest.cc b/chrome/common/l10n_util_unittest.cc index 88c1cad..b308ffa4 100644 --- a/chrome/common/l10n_util_unittest.cc +++ b/chrome/common/l10n_util_unittest.cc @@ -10,6 +10,7 @@ #include "base/string_util.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/l10n_util.h" +#include "chrome/common/stl_util-inl.h" #if !defined(OS_MACOSX) #include "chrome/test/data/resource.h" #endif @@ -19,7 +20,20 @@ namespace { -class L10nUtilTest: public PlatformTest { +class StringWrapper { + public: + explicit StringWrapper(const std::wstring& string) : string_(string) {} + const std::wstring& string() const { return string_; } + + private: + std::wstring string_; + + DISALLOW_COPY_AND_ASSIGN(StringWrapper); +}; + +} // namespace + +class L10nUtilTest : public PlatformTest { }; #if defined(OS_WIN) @@ -160,6 +174,20 @@ TEST_F(L10nUtilTest, GetAppLocale) { Locale::setDefault(locale, error_code); } +TEST_F(L10nUtilTest, SortStringsUsingFunction) { + std::vector<StringWrapper*> strings; + strings.push_back(new StringWrapper(L"C")); + strings.push_back(new StringWrapper(L"d")); + strings.push_back(new StringWrapper(L"b")); + strings.push_back(new StringWrapper(L"a")); + l10n_util::SortStringsUsingMethod(L"en-US", &strings, &StringWrapper::string); + ASSERT_TRUE(L"a" == strings[0]->string()); + ASSERT_TRUE(L"b" == strings[1]->string()); + ASSERT_TRUE(L"C" == strings[2]->string()); + ASSERT_TRUE(L"d" == strings[3]->string()); + STLDeleteElements(&strings); +} + TEST_F(L10nUtilTest, GetFirstStrongCharacterDirection) { // Test pure LTR string. std::wstring string(L"foo bar"); @@ -334,5 +362,3 @@ TEST_F(L10nUtilTest, WrapPathWithLTRFormatting) { EXPECT_EQ(wrapped_path, test_data[i].wrapped_path); } } -} - |