2001-09-26 00:40:45 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-04-18 14:21:17 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
1999-01-21 01:28:27 +00:00
|
|
|
*
|
2004-04-18 14:21:17 +00:00
|
|
|
* 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/
|
1999-01-21 01:28:27 +00:00
|
|
|
*
|
2001-09-26 00:40:45 +00:00
|
|
|
* 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.
|
1999-01-21 01:28:27 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2004-04-18 14:21:17 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
2001-09-26 00:40:45 +00:00
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
1999-11-06 03:43:54 +00:00
|
|
|
*
|
2001-09-26 00:40:45 +00:00
|
|
|
* Contributor(s):
|
2000-02-02 22:24:56 +00:00
|
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
2001-09-26 00:40:45 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-04-18 14:21:17 +00:00
|
|
|
* 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"),
|
2001-09-26 00:40:45 +00:00
|
|
|
* 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
|
2004-04-18 14:21:17 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-09-26 00:40:45 +00:00
|
|
|
* 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
|
2004-04-18 14:21:17 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-09-26 00:40:45 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1999-01-21 01:28:27 +00:00
|
|
|
|
1999-08-27 21:10:18 +00:00
|
|
|
#include "nsIPlatformCharset.h"
|
|
|
|
#include "nsIServiceManager.h"
|
1999-03-09 09:44:27 +00:00
|
|
|
#include "nsIComponentManager.h"
|
1999-01-21 01:28:27 +00:00
|
|
|
#include "nsCollation.h"
|
|
|
|
#include "nsCollationCID.h"
|
|
|
|
#include "nsUnicharUtilCIID.h"
|
1999-02-04 23:17:37 +00:00
|
|
|
#include "prmem.h"
|
2001-10-24 08:15:57 +00:00
|
|
|
#include "nsReadableUtils.h"
|
1999-01-21 01:28:27 +00:00
|
|
|
|
1999-02-04 01:40:58 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
1999-01-21 01:28:27 +00:00
|
|
|
|
|
|
|
NS_DEFINE_CID(kCollationCID, NS_COLLATION_CID);
|
|
|
|
|
2003-09-07 22:24:21 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(nsCollationFactory, nsICollationFactory)
|
1999-01-21 01:28:27 +00:00
|
|
|
|
1999-02-03 01:35:11 +00:00
|
|
|
nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** instancePtr)
|
1999-01-21 01:28:27 +00:00
|
|
|
{
|
|
|
|
// Create a collation interface instance.
|
|
|
|
//
|
|
|
|
nsICollation *inst;
|
|
|
|
nsresult res;
|
|
|
|
|
2001-10-24 08:15:57 +00:00
|
|
|
res = CallCreateInstance(kCollationCID, &inst);
|
1999-01-21 01:28:27 +00:00
|
|
|
if (NS_FAILED(res)) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
inst->Initialize(locale);
|
|
|
|
*instancePtr = inst;
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
1999-02-04 01:40:58 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
1999-01-21 01:28:27 +00:00
|
|
|
|
|
|
|
nsCollation::nsCollation()
|
|
|
|
{
|
2001-11-27 06:19:36 +00:00
|
|
|
MOZ_COUNT_CTOR(nsCollation);
|
2001-10-24 08:15:57 +00:00
|
|
|
nsresult res;
|
2001-10-30 08:03:08 +00:00
|
|
|
mCaseConversion = do_GetService(NS_UNICHARUTIL_CONTRACTID, &res);
|
1999-02-04 01:40:58 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(res), "CreateInstance failed for kCaseConversionIID");
|
1999-01-21 01:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCollation::~nsCollation()
|
|
|
|
{
|
2001-11-27 06:19:36 +00:00
|
|
|
MOZ_COUNT_DTOR(nsCollation);
|
1999-01-21 01:28:27 +00:00
|
|
|
}
|
|
|
|
|
2001-10-24 08:15:57 +00:00
|
|
|
nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
|
1999-01-21 01:28:27 +00:00
|
|
|
{
|
2001-10-24 08:15:57 +00:00
|
|
|
if (!mCaseConversion) {
|
|
|
|
stringOut = stringIn;
|
1999-02-04 01:40:58 +00:00
|
|
|
}
|
|
|
|
else {
|
2001-10-24 08:15:57 +00:00
|
|
|
PRInt32 aLength = stringIn.Length();
|
1999-02-04 01:40:58 +00:00
|
|
|
|
2000-03-23 23:12:54 +00:00
|
|
|
if (aLength <= 64) {
|
2001-10-24 08:15:57 +00:00
|
|
|
PRUnichar conversionBuffer[64];
|
|
|
|
mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
|
|
|
|
stringOut.Assign(conversionBuffer, aLength);
|
2000-03-23 23:12:54 +00:00
|
|
|
}
|
|
|
|
else {
|
2001-10-24 08:15:57 +00:00
|
|
|
PRUnichar* conversionBuffer;
|
|
|
|
conversionBuffer = new PRUnichar[aLength];
|
|
|
|
if (!conversionBuffer) {
|
2000-03-23 23:12:54 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2001-10-24 08:15:57 +00:00
|
|
|
mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
|
|
|
|
stringOut.Assign(conversionBuffer, aLength);
|
|
|
|
delete [] conversionBuffer;
|
1999-02-04 01:40:58 +00:00
|
|
|
}
|
|
|
|
}
|
1999-01-21 01:28:27 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2003-06-11 18:16:03 +00:00
|
|
|
nsresult nsCollation::SetCharset(const char* aCharset)
|
2003-04-21 23:51:25 +00:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCharset);
|
|
|
|
|
|
|
|
nsresult rv;
|
2003-06-11 18:16:03 +00:00
|
|
|
nsCOMPtr <nsICharsetConverterManager> charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
2003-04-21 23:51:25 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2003-06-11 18:16:03 +00:00
|
|
|
rv = charsetConverterManager->GetUnicodeEncoder(aCharset,
|
|
|
|
getter_AddRefs(mEncoder));
|
2003-04-21 23:51:25 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst)
|
1999-02-04 23:17:37 +00:00
|
|
|
{
|
2001-02-14 00:02:45 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(dst);
|
1999-02-04 23:17:37 +00:00
|
|
|
|
2001-02-14 00:02:45 +00:00
|
|
|
nsresult res = NS_OK;
|
2003-04-21 23:51:25 +00:00
|
|
|
if (!mEncoder)
|
2003-06-18 14:31:45 +00:00
|
|
|
res = SetCharset("ISO-8859-1");
|
2001-02-14 00:02:45 +00:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(res)) {
|
2003-04-21 23:51:25 +00:00
|
|
|
const nsPromiseFlatString& src = PromiseFlatString(aSrc);
|
|
|
|
const PRUnichar *unichars = src.get();
|
|
|
|
PRInt32 unicharLength = src.Length();
|
|
|
|
PRInt32 dstLength;
|
|
|
|
res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength);
|
2001-02-14 00:02:45 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
2003-04-21 23:51:25 +00:00
|
|
|
PRInt32 bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call
|
|
|
|
*dst = (char *) PR_Malloc(bufLength);
|
|
|
|
if (*dst) {
|
|
|
|
**dst = '\0';
|
|
|
|
res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength);
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) {
|
|
|
|
// Finishes the conversion. The converter has the possibility to write some
|
|
|
|
// extra data and flush its final state.
|
|
|
|
PRInt32 finishLength = bufLength - dstLength; // remaining unused buffer length
|
|
|
|
if (finishLength > 0) {
|
|
|
|
res = mEncoder->Finish((*dst + dstLength), &finishLength);
|
|
|
|
if (NS_SUCCEEDED(res)) {
|
|
|
|
(*dst)[dstLength + finishLength] = '\0';
|
2001-02-14 00:02:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-04-21 23:51:25 +00:00
|
|
|
if (NS_FAILED(res)) {
|
|
|
|
PR_Free(*dst);
|
|
|
|
*dst = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
res = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2001-02-14 00:02:45 +00:00
|
|
|
}
|
1999-02-04 23:17:37 +00:00
|
|
|
}
|
2001-02-14 00:02:45 +00:00
|
|
|
|
1999-02-04 23:17:37 +00:00
|
|
|
return res;
|
|
|
|
}
|
1999-01-21 01:28:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
|