Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 "nsICharsetConverterManager.h"
12 #include "nsServiceManagerUtils.h"
14 ////////////////////////////////////////////////////////////////////////////////
16 NS_DEFINE_CID(kCollationCID, NS_COLLATION_CID);
18 NS_IMPL_ISUPPORTS(nsCollationFactory, nsICollationFactory)
20 nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** instancePtr)
21 {
22 // Create a collation interface instance.
23 //
24 nsICollation *inst;
25 nsresult res;
27 res = CallCreateInstance(kCollationCID, &inst);
28 if (NS_FAILED(res)) {
29 return res;
30 }
32 inst->Initialize(locale);
33 *instancePtr = inst;
35 return res;
36 }
38 ////////////////////////////////////////////////////////////////////////////////
40 nsCollation::nsCollation()
41 {
42 MOZ_COUNT_CTOR(nsCollation);
43 }
45 nsCollation::~nsCollation()
46 {
47 MOZ_COUNT_DTOR(nsCollation);
48 }
50 nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
51 {
52 int32_t aLength = stringIn.Length();
54 if (aLength <= 64) {
55 char16_t conversionBuffer[64];
56 ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
57 stringOut.Assign(conversionBuffer, aLength);
58 }
59 else {
60 char16_t* conversionBuffer;
61 conversionBuffer = new char16_t[aLength];
62 if (!conversionBuffer) {
63 return NS_ERROR_OUT_OF_MEMORY;
64 }
65 ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength);
66 stringOut.Assign(conversionBuffer, aLength);
67 delete [] conversionBuffer;
68 }
69 return NS_OK;
70 }
72 nsresult nsCollation::SetCharset(const char* aCharset)
73 {
74 NS_ENSURE_ARG_POINTER(aCharset);
76 nsresult rv;
77 nsCOMPtr <nsICharsetConverterManager> charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
78 if (NS_SUCCEEDED(rv)) {
79 rv = charsetConverterManager->GetUnicodeEncoder(aCharset,
80 getter_AddRefs(mEncoder));
81 }
82 return rv;
83 }
85 nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst)
86 {
87 NS_ENSURE_ARG_POINTER(dst);
89 nsresult res = NS_OK;
90 if (!mEncoder)
91 res = SetCharset("ISO-8859-1");
93 if (NS_SUCCEEDED(res)) {
94 const nsPromiseFlatString& src = PromiseFlatString(aSrc);
95 const char16_t *unichars = src.get();
96 int32_t unicharLength = src.Length();
97 int32_t dstLength;
98 res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength);
99 if (NS_SUCCEEDED(res)) {
100 int32_t bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call
101 *dst = (char *) PR_Malloc(bufLength);
102 if (*dst) {
103 **dst = '\0';
104 res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength);
106 if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) {
107 // Finishes the conversion. The converter has the possibility to write some
108 // extra data and flush its final state.
109 int32_t finishLength = bufLength - dstLength; // remaining unused buffer length
110 if (finishLength > 0) {
111 res = mEncoder->Finish((*dst + dstLength), &finishLength);
112 if (NS_SUCCEEDED(res)) {
113 (*dst)[dstLength + finishLength] = '\0';
114 }
115 }
116 }
117 if (NS_FAILED(res)) {
118 PR_Free(*dst);
119 *dst = nullptr;
120 }
121 }
122 else {
123 res = NS_ERROR_OUT_OF_MEMORY;
124 }
125 }
126 }
128 return res;
129 }