intl/uconv/src/nsScriptableUConv.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     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 "nsString.h"
     7 #include "nsICharsetConverterManager.h"
     8 #include "nsIScriptableUConv.h"
     9 #include "nsScriptableUConv.h"
    10 #include "nsIStringStream.h"
    11 #include "nsComponentManagerUtils.h"
    12 #include "nsCharsetAlias.h"
    13 #include "nsServiceManagerUtils.h"
    15 /* Implementation file */
    16 NS_IMPL_ISUPPORTS(nsScriptableUnicodeConverter, nsIScriptableUnicodeConverter)
    18 nsScriptableUnicodeConverter::nsScriptableUnicodeConverter()
    19 : mIsInternal(false)
    20 {
    21 }
    23 nsScriptableUnicodeConverter::~nsScriptableUnicodeConverter()
    24 {
    25 }
    27 nsresult
    28 nsScriptableUnicodeConverter::ConvertFromUnicodeWithLength(const nsAString& aSrc,
    29                                                            int32_t* aOutLen,
    30                                                            char **_retval)
    31 {
    32   if (!mEncoder)
    33     return NS_ERROR_FAILURE;
    35   nsresult rv = NS_OK;
    36   int32_t inLength = aSrc.Length();
    37   const nsAFlatString& flatSrc = PromiseFlatString(aSrc);
    38   rv = mEncoder->GetMaxLength(flatSrc.get(), inLength, aOutLen);
    39   if (NS_SUCCEEDED(rv)) {
    40     *_retval = (char*)moz_malloc(*aOutLen+1);
    41     if (!*_retval)
    42       return NS_ERROR_OUT_OF_MEMORY;
    44     rv = mEncoder->Convert(flatSrc.get(), &inLength, *_retval, aOutLen);
    45     if (NS_SUCCEEDED(rv))
    46     {
    47       (*_retval)[*aOutLen] = '\0';
    48       return NS_OK;
    49     }
    50     moz_free(*_retval);
    51   }
    52   *_retval = nullptr;
    53   return NS_ERROR_FAILURE;
    54 }
    56 /* ACString ConvertFromUnicode (in AString src); */
    57 NS_IMETHODIMP
    58 nsScriptableUnicodeConverter::ConvertFromUnicode(const nsAString& aSrc,
    59                                                  nsACString& _retval)
    60 {
    61   int32_t len;
    62   char* str;
    63   nsresult rv = ConvertFromUnicodeWithLength(aSrc, &len, &str);
    64   if (NS_SUCCEEDED(rv)) {
    65     // No Adopt on nsACString :(
    66     if (!_retval.Assign(str, len, mozilla::fallible_t())) {
    67       rv = NS_ERROR_OUT_OF_MEMORY;
    68     }
    69     moz_free(str);
    70   }
    71   return rv;
    72 }
    74 nsresult
    75 nsScriptableUnicodeConverter::FinishWithLength(char **_retval, int32_t* aLength)
    76 {
    77   if (!mEncoder)
    78     return NS_ERROR_FAILURE;
    80   int32_t finLength = 32;
    82   *_retval = (char *)moz_malloc(finLength);
    83   if (!*_retval)
    84     return NS_ERROR_OUT_OF_MEMORY;
    86   nsresult rv = mEncoder->Finish(*_retval, &finLength);
    87   if (NS_SUCCEEDED(rv))
    88     *aLength = finLength;
    89   else
    90     moz_free(*_retval);
    92   return rv;
    94 }
    96 /* ACString Finish(); */
    97 NS_IMETHODIMP
    98 nsScriptableUnicodeConverter::Finish(nsACString& _retval)
    99 {
   100   int32_t len;
   101   char* str;
   102   nsresult rv = FinishWithLength(&str, &len);
   103   if (NS_SUCCEEDED(rv)) {
   104     // No Adopt on nsACString :(
   105     if (!_retval.Assign(str, len, mozilla::fallible_t())) {
   106       rv = NS_ERROR_OUT_OF_MEMORY;
   107     }
   108     moz_free(str);
   109   }
   110   return rv;
   111 }
   113 /* AString ConvertToUnicode (in ACString src); */
   114 NS_IMETHODIMP
   115 nsScriptableUnicodeConverter::ConvertToUnicode(const nsACString& aSrc, nsAString& _retval)
   116 {
   117   nsACString::const_iterator i;
   118   aSrc.BeginReading(i);
   119   return ConvertFromByteArray(reinterpret_cast<const uint8_t*>(i.get()),
   120                               aSrc.Length(),
   121                               _retval);
   122 }
   124 /* AString convertFromByteArray([const,array,size_is(aCount)] in octet aData,
   125                                 in unsigned long aCount);
   126  */
   127 NS_IMETHODIMP
   128 nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData,
   129                                                    uint32_t aCount,
   130                                                    nsAString& _retval)
   131 {
   132   if (!mDecoder)
   133     return NS_ERROR_FAILURE;
   135   nsresult rv = NS_OK;
   136   int32_t inLength = aCount;
   137   int32_t outLength;
   138   rv = mDecoder->GetMaxLength(reinterpret_cast<const char*>(aData),
   139                               inLength, &outLength);
   140   if (NS_SUCCEEDED(rv))
   141   {
   142     char16_t* buf = (char16_t*)moz_malloc((outLength+1)*sizeof(char16_t));
   143     if (!buf)
   144       return NS_ERROR_OUT_OF_MEMORY;
   146     rv = mDecoder->Convert(reinterpret_cast<const char*>(aData),
   147                            &inLength, buf, &outLength);
   148     if (NS_SUCCEEDED(rv))
   149     {
   150       buf[outLength] = 0;
   151       if (!_retval.Assign(buf, outLength, mozilla::fallible_t())) {
   152         rv = NS_ERROR_OUT_OF_MEMORY;
   153       }
   154     }
   155     moz_free(buf);
   156     return rv;
   157   }
   158   return NS_ERROR_FAILURE;
   160 }
   162 /* void convertToByteArray(in AString aString,
   163                           [optional] out unsigned long aLen,
   164                           [array, size_is(aLen),retval] out octet aData);
   165  */
   166 NS_IMETHODIMP
   167 nsScriptableUnicodeConverter::ConvertToByteArray(const nsAString& aString,
   168                                                  uint32_t* aLen,
   169                                                  uint8_t** _aData)
   170 {
   171   char* data;
   172   int32_t len;
   173   nsresult rv = ConvertFromUnicodeWithLength(aString, &len, &data);
   174   if (NS_FAILED(rv))
   175     return rv;
   176   nsXPIDLCString str;
   177   str.Adopt(data, len); // NOTE: This uses the XPIDLCString as a byte array
   179   rv = FinishWithLength(&data, &len);
   180   if (NS_FAILED(rv))
   181     return rv;
   183   str.Append(data, len);
   184   moz_free(data);
   185   // NOTE: this being a byte array, it needs no null termination
   186   *_aData = reinterpret_cast<uint8_t*>(moz_malloc(str.Length()));
   187   if (!*_aData)
   188     return NS_ERROR_OUT_OF_MEMORY;
   189   memcpy(*_aData, str.get(), str.Length());
   190   *aLen = str.Length();
   191   return NS_OK;
   192 }
   194 /* nsIInputStream convertToInputStream(in AString aString); */
   195 NS_IMETHODIMP
   196 nsScriptableUnicodeConverter::ConvertToInputStream(const nsAString& aString,
   197                                                    nsIInputStream** _retval)
   198 {
   199   nsresult rv;
   200   nsCOMPtr<nsIStringInputStream> inputStream =
   201     do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
   202   if (NS_FAILED(rv))
   203     return rv;
   205   uint8_t* data;
   206   uint32_t dataLen;
   207   rv = ConvertToByteArray(aString, &dataLen, &data);
   208   if (NS_FAILED(rv))
   209     return rv;
   211   rv = inputStream->AdoptData(reinterpret_cast<char*>(data), dataLen);
   212   if (NS_FAILED(rv)) {
   213     moz_free(data);
   214     return rv;
   215   }
   217   NS_ADDREF(*_retval = inputStream);
   218   return rv;
   219 }
   221 /* attribute string charset; */
   222 NS_IMETHODIMP
   223 nsScriptableUnicodeConverter::GetCharset(char * *aCharset)
   224 {
   225   *aCharset = ToNewCString(mCharset);
   226   if (!*aCharset)
   227     return NS_ERROR_OUT_OF_MEMORY;
   229   return NS_OK;
   230 }
   232 NS_IMETHODIMP
   233 nsScriptableUnicodeConverter::SetCharset(const char * aCharset)
   234 {
   235   mCharset.Assign(aCharset);
   236   return InitConverter();
   237 }
   239 NS_IMETHODIMP
   240 nsScriptableUnicodeConverter::GetIsInternal(bool *aIsInternal)
   241 {
   242   *aIsInternal = mIsInternal;
   243   return NS_OK;
   244 }
   246 NS_IMETHODIMP
   247 nsScriptableUnicodeConverter::SetIsInternal(const bool aIsInternal)
   248 {
   249   mIsInternal = aIsInternal;
   250   return NS_OK;
   251 }
   253 nsresult
   254 nsScriptableUnicodeConverter::InitConverter()
   255 {
   256   nsresult rv = NS_OK;
   257   mEncoder = nullptr;
   259   nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   260   if (NS_FAILED(rv) || !ccm) {
   261     return rv;
   262   }
   264   // get an unicode converter
   265   rv = ccm->GetUnicodeEncoder(mCharset.get(), getter_AddRefs(mEncoder));
   266   if (NS_FAILED(rv)) {
   267     return rv;
   268   }
   270   rv = mEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nullptr, (char16_t)'?');
   271   if (NS_FAILED(rv)) {
   272     return rv;
   273   }
   275   nsAutoCString charset;
   276   rv = mIsInternal ? nsCharsetAlias::GetPreferredInternal(mCharset, charset)
   277                    : nsCharsetAlias::GetPreferred(mCharset, charset);
   278   if (NS_FAILED(rv)) {
   279     return rv;
   280   }
   282   rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(mDecoder));
   283   if (NS_FAILED(rv)) {
   284     return rv;
   285   }
   287   // The UTF-8 decoder used to throw regardless of the error behavior.
   288   // Simulating the old behavior for compatibility with legacy callers
   289   // (including addons). If callers want a control over the behavior,
   290   // they should switch to TextDecoder.
   291   if (charset.EqualsLiteral("UTF-8")) {
   292     mDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal);
   293   }
   295   return rv ;
   296 }

mercurial