1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/locale/src/nsCollation.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,132 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsCollation.h" 1.10 +#include "nsCollationCID.h" 1.11 +#include "nsUnicharUtils.h" 1.12 +#include "prmem.h" 1.13 +#include "nsIUnicodeEncoder.h" 1.14 +#include "nsICharsetConverterManager.h" 1.15 +#include "nsServiceManagerUtils.h" 1.16 + 1.17 +//////////////////////////////////////////////////////////////////////////////// 1.18 + 1.19 +NS_DEFINE_CID(kCollationCID, NS_COLLATION_CID); 1.20 + 1.21 +NS_IMPL_ISUPPORTS(nsCollationFactory, nsICollationFactory) 1.22 + 1.23 +nsresult nsCollationFactory::CreateCollation(nsILocale* locale, nsICollation** instancePtr) 1.24 +{ 1.25 + // Create a collation interface instance. 1.26 + // 1.27 + nsICollation *inst; 1.28 + nsresult res; 1.29 + 1.30 + res = CallCreateInstance(kCollationCID, &inst); 1.31 + if (NS_FAILED(res)) { 1.32 + return res; 1.33 + } 1.34 + 1.35 + inst->Initialize(locale); 1.36 + *instancePtr = inst; 1.37 + 1.38 + return res; 1.39 +} 1.40 + 1.41 +//////////////////////////////////////////////////////////////////////////////// 1.42 + 1.43 +nsCollation::nsCollation() 1.44 +{ 1.45 + MOZ_COUNT_CTOR(nsCollation); 1.46 +} 1.47 + 1.48 +nsCollation::~nsCollation() 1.49 +{ 1.50 + MOZ_COUNT_DTOR(nsCollation); 1.51 +} 1.52 + 1.53 +nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut) 1.54 +{ 1.55 + int32_t aLength = stringIn.Length(); 1.56 + 1.57 + if (aLength <= 64) { 1.58 + char16_t conversionBuffer[64]; 1.59 + ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength); 1.60 + stringOut.Assign(conversionBuffer, aLength); 1.61 + } 1.62 + else { 1.63 + char16_t* conversionBuffer; 1.64 + conversionBuffer = new char16_t[aLength]; 1.65 + if (!conversionBuffer) { 1.66 + return NS_ERROR_OUT_OF_MEMORY; 1.67 + } 1.68 + ToLowerCase(PromiseFlatString(stringIn).get(), conversionBuffer, aLength); 1.69 + stringOut.Assign(conversionBuffer, aLength); 1.70 + delete [] conversionBuffer; 1.71 + } 1.72 + return NS_OK; 1.73 +} 1.74 + 1.75 +nsresult nsCollation::SetCharset(const char* aCharset) 1.76 +{ 1.77 + NS_ENSURE_ARG_POINTER(aCharset); 1.78 + 1.79 + nsresult rv; 1.80 + nsCOMPtr <nsICharsetConverterManager> charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); 1.81 + if (NS_SUCCEEDED(rv)) { 1.82 + rv = charsetConverterManager->GetUnicodeEncoder(aCharset, 1.83 + getter_AddRefs(mEncoder)); 1.84 + } 1.85 + return rv; 1.86 +} 1.87 + 1.88 +nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst) 1.89 +{ 1.90 + NS_ENSURE_ARG_POINTER(dst); 1.91 + 1.92 + nsresult res = NS_OK; 1.93 + if (!mEncoder) 1.94 + res = SetCharset("ISO-8859-1"); 1.95 + 1.96 + if (NS_SUCCEEDED(res)) { 1.97 + const nsPromiseFlatString& src = PromiseFlatString(aSrc); 1.98 + const char16_t *unichars = src.get(); 1.99 + int32_t unicharLength = src.Length(); 1.100 + int32_t dstLength; 1.101 + res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength); 1.102 + if (NS_SUCCEEDED(res)) { 1.103 + int32_t bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call 1.104 + *dst = (char *) PR_Malloc(bufLength); 1.105 + if (*dst) { 1.106 + **dst = '\0'; 1.107 + res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength); 1.108 + 1.109 + if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) { 1.110 + // Finishes the conversion. The converter has the possibility to write some 1.111 + // extra data and flush its final state. 1.112 + int32_t finishLength = bufLength - dstLength; // remaining unused buffer length 1.113 + if (finishLength > 0) { 1.114 + res = mEncoder->Finish((*dst + dstLength), &finishLength); 1.115 + if (NS_SUCCEEDED(res)) { 1.116 + (*dst)[dstLength + finishLength] = '\0'; 1.117 + } 1.118 + } 1.119 + } 1.120 + if (NS_FAILED(res)) { 1.121 + PR_Free(*dst); 1.122 + *dst = nullptr; 1.123 + } 1.124 + } 1.125 + else { 1.126 + res = NS_ERROR_OUT_OF_MEMORY; 1.127 + } 1.128 + } 1.129 + } 1.130 + 1.131 + return res; 1.132 +} 1.133 + 1.134 + 1.135 +