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"
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.
29 res
= CallCreateInstance(kCollationCID
, &inst
);
34 inst
->Initialize(locale
);
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();
57 char16_t conversionBuffer
[64];
58 ToLowerCase(PromiseFlatString(stringIn
).get(), conversionBuffer
, aLength
);
59 stringOut
.Assign(conversionBuffer
, aLength
);
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
;
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
);
87 nsresult
nsCollation::UnicodeToChar(const nsAString
& aSrc
, char** dst
)
89 NS_ENSURE_ARG_POINTER(dst
);
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();
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
);
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
)) {
125 res
= NS_ERROR_OUT_OF_MEMORY
;