intl/uconv/src/nsConverterOutputStream.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 /* vim:set expandtab ts=4 sw=4 sts=4 cin: */
     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 "nsCOMPtr.h"
     8 #include "nsIOutputStream.h"
     9 #include "nsICharsetConverterManager.h"
    11 #include "nsConverterOutputStream.h"
    12 #include "nsServiceManagerUtils.h"
    14 NS_IMPL_ISUPPORTS(nsConverterOutputStream,
    15                   nsIUnicharOutputStream,
    16                   nsIConverterOutputStream)
    18 nsConverterOutputStream::~nsConverterOutputStream()
    19 {
    20     Close();
    21 }
    23 NS_IMETHODIMP
    24 nsConverterOutputStream::Init(nsIOutputStream* aOutStream,
    25                               const char*      aCharset,
    26                               uint32_t         aBufferSize /* ignored */,
    27                               char16_t        aReplacementChar)
    28 {
    29     NS_PRECONDITION(aOutStream, "Null output stream!");
    31     if (!aCharset)
    32         aCharset = "UTF-8";
    34     nsresult rv;
    35     nsCOMPtr<nsICharsetConverterManager> ccm =
    36         do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
    37     if (NS_FAILED(rv)) return rv;
    39     rv = ccm->GetUnicodeEncoder(aCharset, getter_AddRefs(mConverter));
    40     if (NS_FAILED(rv))
    41         return rv;
    43     mOutStream = aOutStream;
    45     int32_t behaviour = aReplacementChar ? nsIUnicodeEncoder::kOnError_Replace
    46                                          : nsIUnicodeEncoder::kOnError_Signal;
    47     return mConverter->
    48         SetOutputErrorBehavior(behaviour,
    49                                nullptr,
    50                                aReplacementChar);
    51 }
    53 NS_IMETHODIMP
    54 nsConverterOutputStream::Write(uint32_t aCount, const char16_t* aChars,
    55                                bool* aSuccess)
    56 {
    57     if (!mOutStream) {
    58         NS_ASSERTION(!mConverter, "Closed streams shouldn't have converters");
    59         return NS_BASE_STREAM_CLOSED;
    60     }
    61     NS_ASSERTION(mConverter, "Must have a converter when not closed");
    63     int32_t inLen = aCount;
    65     int32_t maxLen;
    66     nsresult rv = mConverter->GetMaxLength(aChars, inLen, &maxLen);
    67     NS_ENSURE_SUCCESS(rv, rv);
    69     nsAutoCString buf;
    70     buf.SetLength(maxLen);
    71     if (buf.Length() != (uint32_t) maxLen)
    72         return NS_ERROR_OUT_OF_MEMORY;
    74     int32_t outLen = maxLen;
    75     rv = mConverter->Convert(aChars, &inLen, buf.BeginWriting(), &outLen);
    76     if (NS_FAILED(rv))
    77         return rv;
    78     if (rv == NS_ERROR_UENC_NOMAPPING) {
    79         // Yes, NS_ERROR_UENC_NOMAPPING is a success code
    80         return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
    81     }
    82     NS_ASSERTION((uint32_t) inLen == aCount,
    83                  "Converter didn't consume all the data!");
    85     uint32_t written;
    86     rv = mOutStream->Write(buf.get(), outLen, &written);
    87     *aSuccess = NS_SUCCEEDED(rv) && written == uint32_t(outLen);
    88     return rv;
    90 }
    92 NS_IMETHODIMP
    93 nsConverterOutputStream::WriteString(const nsAString& aString, bool* aSuccess)
    94 {
    95     int32_t inLen = aString.Length();
    96     nsAString::const_iterator i;
    97     aString.BeginReading(i);
    98     return Write(inLen, i.get(), aSuccess);
    99 }
   101 NS_IMETHODIMP
   102 nsConverterOutputStream::Flush()
   103 {
   104     if (!mOutStream)
   105         return NS_OK; // Already closed.
   107     char buf[1024];
   108     int32_t size = sizeof(buf);
   109     nsresult rv = mConverter->Finish(buf, &size);
   110     NS_ASSERTION(rv != NS_OK_UENC_MOREOUTPUT,
   111                  "1024 bytes ought to be enough for everyone");
   112     if (NS_FAILED(rv))
   113         return rv;
   114     if (size == 0)
   115         return NS_OK;
   117     uint32_t written;
   118     rv = mOutStream->Write(buf, size, &written);
   119     if (NS_FAILED(rv)) {
   120         NS_WARNING("Flush() lost data!");
   121         return rv;
   122     }
   123     if (written != uint32_t(size)) {
   124         NS_WARNING("Flush() lost data!");
   125         return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
   126     }
   127     return rv;
   128 }
   130 NS_IMETHODIMP
   131 nsConverterOutputStream::Close()
   132 {
   133     if (!mOutStream)
   134         return NS_OK; // Already closed.
   136     nsresult rv1 = Flush();
   138     nsresult rv2 = mOutStream->Close();
   139     mOutStream = nullptr;
   140     mConverter = nullptr;
   141     return NS_FAILED(rv1) ? rv1 : rv2;
   142 }

mercurial