michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: #include "nsCollationWin.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsILocaleService.h" michael@0: #include "nsIPlatformCharset.h" michael@0: #include "nsWin32Locale.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "prmem.h" michael@0: #include "plstr.h" michael@0: #include michael@0: michael@0: #undef CompareString michael@0: michael@0: NS_IMPL_ISUPPORTS(nsCollationWin, nsICollation) michael@0: michael@0: michael@0: nsCollationWin::nsCollationWin() : mCollation(nullptr) michael@0: { michael@0: } michael@0: michael@0: nsCollationWin::~nsCollationWin() michael@0: { michael@0: if (mCollation) michael@0: delete mCollation; michael@0: } michael@0: michael@0: nsresult nsCollationWin::Initialize(nsILocale* locale) michael@0: { michael@0: NS_ASSERTION(!mCollation, "Should only be initialized once."); michael@0: michael@0: nsresult res; michael@0: michael@0: mCollation = new nsCollation; michael@0: michael@0: // default LCID (en-US) michael@0: mLCID = 1033; michael@0: michael@0: nsAutoString localeStr; michael@0: michael@0: // get locale string, use app default if no locale specified michael@0: if (!locale) { michael@0: nsCOMPtr localeService = michael@0: do_GetService(NS_LOCALESERVICE_CONTRACTID); michael@0: if (localeService) { michael@0: nsCOMPtr appLocale; michael@0: res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); michael@0: if (NS_SUCCEEDED(res)) { michael@0: res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), michael@0: localeStr); michael@0: } michael@0: } michael@0: } michael@0: else { michael@0: res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), michael@0: localeStr); michael@0: } michael@0: michael@0: // Get LCID and charset name from locale, if available michael@0: LCID lcid; michael@0: res = nsWin32Locale::GetPlatformLocale(localeStr, &lcid); michael@0: if (NS_SUCCEEDED(res)) { michael@0: mLCID = lcid; michael@0: } michael@0: michael@0: nsCOMPtr platformCharset = michael@0: do_GetService(NS_PLATFORMCHARSET_CONTRACTID); michael@0: if (platformCharset) { michael@0: nsAutoCString mappedCharset; michael@0: res = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset); michael@0: if (NS_SUCCEEDED(res)) { michael@0: mCollation->SetCharset(mappedCharset.get()); michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP nsCollationWin::CompareString(int32_t strength, michael@0: const nsAString & string1, michael@0: const nsAString & string2, michael@0: int32_t *result) michael@0: { michael@0: int retval; michael@0: nsresult res; michael@0: DWORD dwMapFlags = 0; michael@0: michael@0: if (strength == kCollationCaseInSensitive) michael@0: dwMapFlags |= NORM_IGNORECASE; michael@0: michael@0: retval = ::CompareStringW(mLCID, michael@0: dwMapFlags, michael@0: (LPCWSTR) PromiseFlatString(string1).get(), michael@0: -1, michael@0: (LPCWSTR) PromiseFlatString(string2).get(), michael@0: -1); michael@0: if (retval) { michael@0: res = NS_OK; michael@0: *result = retval - 2; michael@0: } else { michael@0: res = NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return res; michael@0: } michael@0: michael@0: michael@0: nsresult nsCollationWin::AllocateRawSortKey(int32_t strength, michael@0: const nsAString& stringIn, uint8_t** key, uint32_t* outLen) michael@0: { michael@0: int byteLen; michael@0: void *buffer; michael@0: nsresult res = NS_OK; michael@0: DWORD dwMapFlags = LCMAP_SORTKEY; michael@0: michael@0: if (strength == kCollationCaseInSensitive) michael@0: dwMapFlags |= NORM_IGNORECASE; michael@0: michael@0: byteLen = LCMapStringW(mLCID, dwMapFlags, michael@0: (LPCWSTR) PromiseFlatString(stringIn).get(), michael@0: -1, nullptr, 0); michael@0: buffer = PR_Malloc(byteLen); michael@0: if (!buffer) { michael@0: res = NS_ERROR_OUT_OF_MEMORY; michael@0: } else { michael@0: *key = (uint8_t *)buffer; michael@0: *outLen = LCMapStringW(mLCID, dwMapFlags, michael@0: (LPCWSTR) PromiseFlatString(stringIn).get(), michael@0: -1, (LPWSTR) buffer, byteLen); michael@0: } michael@0: return res; michael@0: } michael@0: michael@0: nsresult nsCollationWin::CompareRawSortKey(const uint8_t* key1, uint32_t len1, michael@0: const uint8_t* key2, uint32_t len2, michael@0: int32_t* result) michael@0: { michael@0: *result = PL_strcmp((const char *)key1, (const char *)key2); michael@0: return NS_OK; michael@0: }