Reenable test.
[wine-gecko.git] / intl / locale / src / nsCollation.cpp
blob6dd59eba8b62f21aaf1ae8d522492a14aa59b495
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Pierre Phaneuf <pp@ludusdesign.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsIPlatformCharset.h"
40 #include "nsIServiceManager.h"
41 #include "nsIComponentManager.h"
42 #include "nsCollation.h"
43 #include "nsCollationCID.h"
44 #include "nsUnicharUtilCIID.h"
45 #include "prmem.h"
46 #include "nsReadableUtils.h"
48 ////////////////////////////////////////////////////////////////////////////////
50 NS_DEFINE_CID(kCollationCID, NS_COLLATION_CID);
52 NS_IMPL_ISUPPORTS1(nsCollationFactory, nsICollationFactory)
54 nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** instancePtr)
56 // Create a collation interface instance.
58 nsICollation *inst;
59 nsresult res;
61 res = CallCreateInstance(kCollationCID, &inst);
62 if (NS_FAILED(res)) {
63 return res;
66 inst->Initialize(locale);
67 *instancePtr = inst;
69 return res;
72 ////////////////////////////////////////////////////////////////////////////////
74 nsCollation::nsCollation()
76 MOZ_COUNT_CTOR(nsCollation);
77 nsresult res;
78 mCaseConversion = do_GetService(NS_UNICHARUTIL_CONTRACTID, &res);
79 NS_ASSERTION(NS_SUCCEEDED(res), "CreateInstance failed for kCaseConversionIID");
82 nsCollation::~nsCollation()
84 MOZ_COUNT_DTOR(nsCollation);
87 nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
89 if (!mCaseConversion) {
90 stringOut = stringIn;
92 else {
93 PRInt32 aLength = stringIn.Length();
95 if (aLength <= 64) {
96 PRUnichar conversionBuffer[64];
97 mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
98 stringOut.Assign(conversionBuffer, aLength);
100 else {
101 PRUnichar* conversionBuffer;
102 conversionBuffer = new PRUnichar[aLength];
103 if (!conversionBuffer) {
104 return NS_ERROR_OUT_OF_MEMORY;
106 mCaseConversion->ToLower(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
107 stringOut.Assign(conversionBuffer, aLength);
108 delete [] conversionBuffer;
111 return NS_OK;
114 nsresult nsCollation::SetCharset(const char* aCharset)
116 NS_ENSURE_ARG_POINTER(aCharset);
118 nsresult rv;
119 nsCOMPtr <nsICharsetConverterManager> charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
120 if (NS_SUCCEEDED(rv)) {
121 rv = charsetConverterManager->GetUnicodeEncoder(aCharset,
122 getter_AddRefs(mEncoder));
124 return rv;
127 nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst)
129 NS_ENSURE_ARG_POINTER(dst);
131 nsresult res = NS_OK;
132 if (!mEncoder)
133 res = SetCharset("ISO-8859-1");
135 if (NS_SUCCEEDED(res)) {
136 const nsPromiseFlatString& src = PromiseFlatString(aSrc);
137 const PRUnichar *unichars = src.get();
138 PRInt32 unicharLength = src.Length();
139 PRInt32 dstLength;
140 res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength);
141 if (NS_SUCCEEDED(res)) {
142 PRInt32 bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call
143 *dst = (char *) PR_Malloc(bufLength);
144 if (*dst) {
145 **dst = '\0';
146 res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength);
148 if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) {
149 // Finishes the conversion. The converter has the possibility to write some
150 // extra data and flush its final state.
151 PRInt32 finishLength = bufLength - dstLength; // remaining unused buffer length
152 if (finishLength > 0) {
153 res = mEncoder->Finish((*dst + dstLength), &finishLength);
154 if (NS_SUCCEEDED(res)) {
155 (*dst)[dstLength + finishLength] = '\0';
159 if (NS_FAILED(res)) {
160 PR_Free(*dst);
161 *dst = nsnull;
164 else {
165 res = NS_ERROR_OUT_OF_MEMORY;
170 return res;