modules/libjar/zipwriter/src/nsDeflateConverter.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     4  */
     6 #include "StreamFunctions.h"
     7 #include "nsDeflateConverter.h"
     8 #include "nsIStringStream.h"
     9 #include "nsIInputStreamPump.h"
    10 #include "nsComponentManagerUtils.h"
    11 #include "nsMemory.h"
    12 #include "nsAutoPtr.h"
    13 #include "plstr.h"
    15 #define ZLIB_TYPE "deflate"
    16 #define GZIP_TYPE "gzip"
    17 #define X_GZIP_TYPE "x-gzip"
    19 /**
    20  * nsDeflateConverter is a stream converter applies the deflate compression
    21  * method to the data.
    22  */
    23 NS_IMPL_ISUPPORTS(nsDeflateConverter, nsIStreamConverter,
    24                   nsIStreamListener,
    25                   nsIRequestObserver)
    27 nsresult nsDeflateConverter::Init()
    28 {
    29     int zerr;
    31     mOffset = 0;
    33     mZstream.zalloc = Z_NULL;
    34     mZstream.zfree = Z_NULL;
    35     mZstream.opaque = Z_NULL;
    37     int32_t window = MAX_WBITS;
    38     switch (mWrapMode) {
    39         case WRAP_NONE:
    40             window = -window;
    41             break;
    42         case WRAP_GZIP:
    43             window += 16;
    44             break;
    45         default:
    46             break;
    47     }
    49     zerr = deflateInit2(&mZstream, mLevel, Z_DEFLATED, window, 8,
    50                         Z_DEFAULT_STRATEGY);
    51     if (zerr != Z_OK) return NS_ERROR_OUT_OF_MEMORY;
    53     mZstream.next_out = mWriteBuffer;
    54     mZstream.avail_out = sizeof(mWriteBuffer);
    56     // mark the input buffer as empty.
    57     mZstream.avail_in = 0;
    58     mZstream.next_in = Z_NULL;
    60     return NS_OK;
    61 }
    63 /* nsIInputStream convert (in nsIInputStream aFromStream, in string aFromType
    64  *                         in string aToType, in nsISupports aCtxt); */
    65 NS_IMETHODIMP nsDeflateConverter::Convert(nsIInputStream *aFromStream,
    66                                           const char *aFromType,
    67                                           const char *aToType,
    68                                           nsISupports *aCtxt,
    69                                           nsIInputStream **_retval)
    70 {
    71     return NS_ERROR_NOT_IMPLEMENTED;
    72 }
    74 /* void asyncConvertData (in string aFromType, in string aToType,
    75  *                        in nsIStreamListener aListener,
    76  *                        in nsISupports aCtxt); */
    77 NS_IMETHODIMP nsDeflateConverter::AsyncConvertData(const char *aFromType,
    78                                                    const char *aToType,
    79                                                    nsIStreamListener *aListener,
    80                                                    nsISupports *aCtxt)
    81 {
    82     if (mListener)
    83         return NS_ERROR_ALREADY_INITIALIZED;
    85     NS_ENSURE_ARG_POINTER(aListener);
    87     if (!PL_strncasecmp(aToType, ZLIB_TYPE, sizeof(ZLIB_TYPE)-1))
    88         mWrapMode = WRAP_ZLIB;
    89     else if (!PL_strcasecmp(aToType, GZIP_TYPE) ||
    90              !PL_strcasecmp(aToType, X_GZIP_TYPE))
    91         mWrapMode = WRAP_GZIP;
    92     else
    93         mWrapMode = WRAP_NONE;
    95     nsresult rv = Init();
    96     NS_ENSURE_SUCCESS(rv, rv);
    98     mListener = aListener;
    99     mContext = aCtxt;
   100     return rv;
   101 }
   103 /* void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext,
   104  *                       in nsIInputStream aInputStream,
   105  *                       in unsigned long long aOffset,
   106  *                       in unsigned long aCount); */
   107 NS_IMETHODIMP nsDeflateConverter::OnDataAvailable(nsIRequest *aRequest,
   108                                                   nsISupports *aContext,
   109                                                   nsIInputStream *aInputStream,
   110                                                   uint64_t aOffset,
   111                                                   uint32_t aCount)
   112 {
   113     if (!mListener)
   114         return NS_ERROR_NOT_INITIALIZED;
   116     nsAutoArrayPtr<char> buffer(new char[aCount]);
   117     NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
   119     nsresult rv = ZW_ReadData(aInputStream, buffer.get(), aCount);
   120     NS_ENSURE_SUCCESS(rv, rv);
   122     // make sure we aren't reading too much
   123     mZstream.avail_in = aCount;
   124     mZstream.next_in = (unsigned char*)buffer.get();
   126     int zerr = Z_OK;
   127     // deflate loop
   128     while (mZstream.avail_in > 0 && zerr == Z_OK) {
   129         zerr = deflate(&mZstream, Z_NO_FLUSH);
   131         while (mZstream.avail_out == 0) {
   132             // buffer is full, push the data out to the listener
   133             rv = PushAvailableData(aRequest, aContext);
   134             NS_ENSURE_SUCCESS(rv, rv);
   135             zerr = deflate(&mZstream, Z_NO_FLUSH);
   136         }
   137     }
   139     return NS_OK;
   140 }
   142 /* void onStartRequest (in nsIRequest aRequest, in nsISupports aContext); */
   143 NS_IMETHODIMP nsDeflateConverter::OnStartRequest(nsIRequest *aRequest,
   144                                                  nsISupports *aContext)
   145 {
   146     if (!mListener)
   147         return NS_ERROR_NOT_INITIALIZED;
   149     return mListener->OnStartRequest(aRequest, mContext);
   150 }
   152 /* void onStopRequest (in nsIRequest aRequest, in nsISupports aContext,
   153  *                     in nsresult aStatusCode); */
   154 NS_IMETHODIMP nsDeflateConverter::OnStopRequest(nsIRequest *aRequest,
   155                                                 nsISupports *aContext,
   156                                                 nsresult aStatusCode)
   157 {
   158     if (!mListener)
   159         return NS_ERROR_NOT_INITIALIZED;
   161     nsresult rv;
   163     int zerr;
   164     do {
   165         zerr = deflate(&mZstream, Z_FINISH);
   166         rv = PushAvailableData(aRequest, aContext);
   167         NS_ENSURE_SUCCESS(rv, rv);
   168     } while (zerr == Z_OK);
   170     deflateEnd(&mZstream);
   172     return mListener->OnStopRequest(aRequest, mContext, aStatusCode);
   173 }
   175 nsresult nsDeflateConverter::PushAvailableData(nsIRequest *aRequest,
   176                                                nsISupports *aContext)
   177 {
   178     uint32_t bytesToWrite = sizeof(mWriteBuffer) - mZstream.avail_out;
   179     // We don't need to do anything if there isn't any data
   180     if (bytesToWrite == 0)
   181         return NS_OK;
   183     nsresult rv;
   184     nsCOMPtr<nsIStringInputStream> stream =
   185              do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
   186     NS_ENSURE_SUCCESS(rv, rv);
   188     stream->ShareData((char*)mWriteBuffer, bytesToWrite);
   189     rv = mListener->OnDataAvailable(aRequest, mContext, stream, mOffset,
   190                                     bytesToWrite);
   192     // now set the state for 'deflate'
   193     mZstream.next_out = mWriteBuffer;
   194     mZstream.avail_out = sizeof(mWriteBuffer);
   196     mOffset += bytesToWrite;
   197     return rv;
   198 }

mercurial