Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | |
michael@0 | 7 | #include "nsCollationWin.h" |
michael@0 | 8 | #include "nsIServiceManager.h" |
michael@0 | 9 | #include "nsIComponentManager.h" |
michael@0 | 10 | #include "nsILocaleService.h" |
michael@0 | 11 | #include "nsIPlatformCharset.h" |
michael@0 | 12 | #include "nsWin32Locale.h" |
michael@0 | 13 | #include "nsCOMPtr.h" |
michael@0 | 14 | #include "prmem.h" |
michael@0 | 15 | #include "plstr.h" |
michael@0 | 16 | #include <windows.h> |
michael@0 | 17 | |
michael@0 | 18 | #undef CompareString |
michael@0 | 19 | |
michael@0 | 20 | NS_IMPL_ISUPPORTS(nsCollationWin, nsICollation) |
michael@0 | 21 | |
michael@0 | 22 | |
michael@0 | 23 | nsCollationWin::nsCollationWin() : mCollation(nullptr) |
michael@0 | 24 | { |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | nsCollationWin::~nsCollationWin() |
michael@0 | 28 | { |
michael@0 | 29 | if (mCollation) |
michael@0 | 30 | delete mCollation; |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | nsresult nsCollationWin::Initialize(nsILocale* locale) |
michael@0 | 34 | { |
michael@0 | 35 | NS_ASSERTION(!mCollation, "Should only be initialized once."); |
michael@0 | 36 | |
michael@0 | 37 | nsresult res; |
michael@0 | 38 | |
michael@0 | 39 | mCollation = new nsCollation; |
michael@0 | 40 | |
michael@0 | 41 | // default LCID (en-US) |
michael@0 | 42 | mLCID = 1033; |
michael@0 | 43 | |
michael@0 | 44 | nsAutoString localeStr; |
michael@0 | 45 | |
michael@0 | 46 | // get locale string, use app default if no locale specified |
michael@0 | 47 | if (!locale) { |
michael@0 | 48 | nsCOMPtr<nsILocaleService> localeService = |
michael@0 | 49 | do_GetService(NS_LOCALESERVICE_CONTRACTID); |
michael@0 | 50 | if (localeService) { |
michael@0 | 51 | nsCOMPtr<nsILocale> appLocale; |
michael@0 | 52 | res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); |
michael@0 | 53 | if (NS_SUCCEEDED(res)) { |
michael@0 | 54 | res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), |
michael@0 | 55 | localeStr); |
michael@0 | 56 | } |
michael@0 | 57 | } |
michael@0 | 58 | } |
michael@0 | 59 | else { |
michael@0 | 60 | res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), |
michael@0 | 61 | localeStr); |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | // Get LCID and charset name from locale, if available |
michael@0 | 65 | LCID lcid; |
michael@0 | 66 | res = nsWin32Locale::GetPlatformLocale(localeStr, &lcid); |
michael@0 | 67 | if (NS_SUCCEEDED(res)) { |
michael@0 | 68 | mLCID = lcid; |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | nsCOMPtr <nsIPlatformCharset> platformCharset = |
michael@0 | 72 | do_GetService(NS_PLATFORMCHARSET_CONTRACTID); |
michael@0 | 73 | if (platformCharset) { |
michael@0 | 74 | nsAutoCString mappedCharset; |
michael@0 | 75 | res = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset); |
michael@0 | 76 | if (NS_SUCCEEDED(res)) { |
michael@0 | 77 | mCollation->SetCharset(mappedCharset.get()); |
michael@0 | 78 | } |
michael@0 | 79 | } |
michael@0 | 80 | |
michael@0 | 81 | return NS_OK; |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | |
michael@0 | 85 | NS_IMETHODIMP nsCollationWin::CompareString(int32_t strength, |
michael@0 | 86 | const nsAString & string1, |
michael@0 | 87 | const nsAString & string2, |
michael@0 | 88 | int32_t *result) |
michael@0 | 89 | { |
michael@0 | 90 | int retval; |
michael@0 | 91 | nsresult res; |
michael@0 | 92 | DWORD dwMapFlags = 0; |
michael@0 | 93 | |
michael@0 | 94 | if (strength == kCollationCaseInSensitive) |
michael@0 | 95 | dwMapFlags |= NORM_IGNORECASE; |
michael@0 | 96 | |
michael@0 | 97 | retval = ::CompareStringW(mLCID, |
michael@0 | 98 | dwMapFlags, |
michael@0 | 99 | (LPCWSTR) PromiseFlatString(string1).get(), |
michael@0 | 100 | -1, |
michael@0 | 101 | (LPCWSTR) PromiseFlatString(string2).get(), |
michael@0 | 102 | -1); |
michael@0 | 103 | if (retval) { |
michael@0 | 104 | res = NS_OK; |
michael@0 | 105 | *result = retval - 2; |
michael@0 | 106 | } else { |
michael@0 | 107 | res = NS_ERROR_FAILURE; |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | return res; |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | |
michael@0 | 114 | nsresult nsCollationWin::AllocateRawSortKey(int32_t strength, |
michael@0 | 115 | const nsAString& stringIn, uint8_t** key, uint32_t* outLen) |
michael@0 | 116 | { |
michael@0 | 117 | int byteLen; |
michael@0 | 118 | void *buffer; |
michael@0 | 119 | nsresult res = NS_OK; |
michael@0 | 120 | DWORD dwMapFlags = LCMAP_SORTKEY; |
michael@0 | 121 | |
michael@0 | 122 | if (strength == kCollationCaseInSensitive) |
michael@0 | 123 | dwMapFlags |= NORM_IGNORECASE; |
michael@0 | 124 | |
michael@0 | 125 | byteLen = LCMapStringW(mLCID, dwMapFlags, |
michael@0 | 126 | (LPCWSTR) PromiseFlatString(stringIn).get(), |
michael@0 | 127 | -1, nullptr, 0); |
michael@0 | 128 | buffer = PR_Malloc(byteLen); |
michael@0 | 129 | if (!buffer) { |
michael@0 | 130 | res = NS_ERROR_OUT_OF_MEMORY; |
michael@0 | 131 | } else { |
michael@0 | 132 | *key = (uint8_t *)buffer; |
michael@0 | 133 | *outLen = LCMapStringW(mLCID, dwMapFlags, |
michael@0 | 134 | (LPCWSTR) PromiseFlatString(stringIn).get(), |
michael@0 | 135 | -1, (LPWSTR) buffer, byteLen); |
michael@0 | 136 | } |
michael@0 | 137 | return res; |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | nsresult nsCollationWin::CompareRawSortKey(const uint8_t* key1, uint32_t len1, |
michael@0 | 141 | const uint8_t* key2, uint32_t len2, |
michael@0 | 142 | int32_t* result) |
michael@0 | 143 | { |
michael@0 | 144 | *result = PL_strcmp((const char *)key1, (const char *)key2); |
michael@0 | 145 | return NS_OK; |
michael@0 | 146 | } |