Bumping gaia.json for 4 gaia revision(s) a=gaia-bump
[gecko.git] / intl / locale / nsCollation.cpp
blobf6fa544715fcdd27c25b8ffc3f8ac1f3078486ec
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsCollation.h"
7 #include "nsCollationCID.h"
8 #include "nsUnicharUtils.h"
9 #include "prmem.h"
10 #include "nsIUnicodeEncoder.h"
11 #include "nsServiceManagerUtils.h"
12 #include "mozilla/dom/EncodingUtils.h"
14 using mozilla::dom::EncodingUtils;
16 ////////////////////////////////////////////////////////////////////////////////
18 NS_DEFINE_CID(kCollationCID, NS_COLLATION_CID);
20 NS_IMPL_ISUPPORTS(nsCollationFactory, nsICollationFactory)
22 nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** instancePtr)
24 // Create a collation interface instance.
26 nsICollation *inst;
27 nsresult res;
29 res = CallCreateInstance(kCollationCID, &inst);
30 if (NS_FAILED(res)) {
31 return res;
34 inst->Initialize(locale);
35 *instancePtr = inst;
37 return res;
40 ////////////////////////////////////////////////////////////////////////////////
42 nsCollation::nsCollation()
44 MOZ_COUNT_CTOR(nsCollation);
47 nsCollation::~nsCollation()
49 MOZ_COUNT_DTOR(nsCollation);
52 nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
54 int32_t aLength = stringIn.Length();
56 if (aLength <= 64) {
57 char16_t conversionBuffer[64];
58 ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
59 stringOut.Assign(conversionBuffer, aLength);
61 else {
62 char16_t* conversionBuffer;
63 conversionBuffer = new char16_t[aLength];
64 if (!conversionBuffer) {
65 return NS_ERROR_OUT_OF_MEMORY;
67 ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
68 stringOut.Assign(conversionBuffer, aLength);
69 delete [] conversionBuffer;
71 return NS_OK;
74 nsresult nsCollation::SetCharset(const char* aCharset)
76 NS_ENSURE_ARG_POINTER(aCharset);
78 nsDependentCString label(aCharset);
79 nsAutoCString encoding;
80 if (!EncodingUtils::FindEncodingForLabelNoReplacement(label, encoding)) {
81 return NS_ERROR_UCONV_NOCONV;
83 mEncoder = EncodingUtils::EncoderForEncoding(encoding);
84 return NS_OK;
87 nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst)
89 NS_ENSURE_ARG_POINTER(dst);
91 nsresult res = NS_OK;
92 if (!mEncoder)
93 res = SetCharset("ISO-8859-1");
95 if (NS_SUCCEEDED(res)) {
96 const nsPromiseFlatString& src = PromiseFlatString(aSrc);
97 const char16_t *unichars = src.get();
98 int32_t unicharLength = src.Length();
99 int32_t dstLength;
100 res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength);
101 if (NS_SUCCEEDED(res)) {
102 int32_t bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call
103 *dst = (char *) PR_Malloc(bufLength);
104 if (*dst) {
105 **dst = '\0';
106 res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength);
108 if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) {
109 // Finishes the conversion. The converter has the possibility to write some
110 // extra data and flush its final state.
111 int32_t finishLength = bufLength - dstLength; // remaining unused buffer length
112 if (finishLength > 0) {
113 res = mEncoder->Finish((*dst + dstLength), &finishLength);
114 if (NS_SUCCEEDED(res)) {
115 (*dst)[dstLength + finishLength] = '\0';
119 if (NS_FAILED(res)) {
120 PR_Free(*dst);
121 *dst = nullptr;
124 else {
125 res = NS_ERROR_OUT_OF_MEMORY;
130 return res;