intl/locale/src/nsCollation.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     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 }

mercurial