/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Pierre Phaneuf * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsCollationWin.h" #include "nsIServiceManager.h" #include "nsIComponentManager.h" #include "nsLocaleCID.h" #include "nsILocaleService.h" #include "nsIPlatformCharset.h" #include "nsIWin32Locale.h" #include "nsCOMPtr.h" #include "prmem.h" #include "plstr.h" #include #ifdef WINCE #include #else #undef CompareString #endif NS_IMPL_ISUPPORTS1(nsCollationWin, nsICollation) nsCollationWin::nsCollationWin() { mCollation = NULL; } nsCollationWin::~nsCollationWin() { if (mCollation != NULL) delete mCollation; } nsresult nsCollationWin::Initialize(nsILocale* locale) { NS_ASSERTION(mCollation == NULL, "Should only be initialized once."); nsresult res; mCollation = new nsCollation; if (!mCollation) { return NS_ERROR_OUT_OF_MEMORY; } // default LCID (en-US) mLCID = 1033; nsAutoString localeStr; // get locale string, use app default if no locale specified if (!locale) { nsCOMPtr localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID); if (localeService) { nsCOMPtr appLocale; res = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); if (NS_SUCCEEDED(res)) { res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeStr); } } } else { res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeStr); } // Get LCID and charset name from locale, if available nsCOMPtr win32Locale = do_GetService(NS_WIN32LOCALE_CONTRACTID); if (win32Locale) { LCID lcid; res = win32Locale->GetPlatformLocale(localeStr, &lcid); if (NS_SUCCEEDED(res)) { mLCID = lcid; } } nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID); if (platformCharset) { nsCAutoString mappedCharset; res = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset); if (NS_SUCCEEDED(res)) { mCollation->SetCharset(mappedCharset.get()); } } return NS_OK; } NS_IMETHODIMP nsCollationWin::CompareString(PRInt32 strength, const nsAString & string1, const nsAString & string2, PRInt32 *result) { int retval; nsresult res; DWORD dwMapFlags = 0; #ifndef WINCE // NORM_IGNORECASE is not supported on WINCE if (strength == kCollationCaseInSensitive) dwMapFlags |= NORM_IGNORECASE; #endif retval = ::CompareStringW(mLCID, dwMapFlags, (LPCWSTR) PromiseFlatString(string1).get(), -1, (LPCWSTR) PromiseFlatString(string2).get(), -1); if (retval) { res = NS_OK; *result = retval - 2; } else { res = NS_ERROR_FAILURE; } return res; } nsresult nsCollationWin::AllocateRawSortKey(PRInt32 strength, const nsAString& stringIn, PRUint8** key, PRUint32* outLen) { int byteLen; void *buffer; nsresult res = NS_OK; DWORD dwMapFlags = LCMAP_SORTKEY; if (strength == kCollationCaseInSensitive) dwMapFlags |= NORM_IGNORECASE; byteLen = LCMapStringW(mLCID, dwMapFlags, (LPCWSTR) PromiseFlatString(stringIn).get(), -1, NULL, 0); buffer = PR_Malloc(byteLen); if (!buffer) { res = NS_ERROR_OUT_OF_MEMORY; } else { *key = (PRUint8 *)buffer; *outLen = LCMapStringW(mLCID, dwMapFlags, (LPCWSTR) PromiseFlatString(stringIn).get(), -1, (LPWSTR) buffer, byteLen); } return res; } nsresult nsCollationWin::CompareRawSortKey(const PRUint8* key1, PRUint32 len1, const PRUint8* key2, PRUint32 len2, PRInt32* result) { *result = PL_strcmp((const char *)key1, (const char *)key2); return NS_OK; }