netwerk/base/src/nsStreamLoader.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 /* -*- 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 "nsStreamLoader.h"
     7 #include "nsIInputStream.h"
     8 #include "nsIChannel.h"
     9 #include "nsError.h"
    10 #include "GeckoProfiler.h"
    12 nsStreamLoader::nsStreamLoader()
    13   : mData(nullptr),
    14     mAllocated(0),
    15     mLength(0)
    16 {
    17 }
    19 nsStreamLoader::~nsStreamLoader()
    20 {
    21   ReleaseData();
    22 }
    24 NS_IMETHODIMP
    25 nsStreamLoader::Init(nsIStreamLoaderObserver* observer)
    26 {
    27   NS_ENSURE_ARG_POINTER(observer);
    28   mObserver = observer;
    29   return NS_OK;
    30 }
    32 nsresult
    33 nsStreamLoader::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
    34 {
    35   if (aOuter) return NS_ERROR_NO_AGGREGATION;
    37   nsStreamLoader* it = new nsStreamLoader();
    38   if (it == nullptr)
    39     return NS_ERROR_OUT_OF_MEMORY;
    40   NS_ADDREF(it);
    41   nsresult rv = it->QueryInterface(aIID, aResult);
    42   NS_RELEASE(it);
    43   return rv;
    44 }
    46 NS_IMPL_ISUPPORTS(nsStreamLoader, nsIStreamLoader,
    47                   nsIRequestObserver, nsIStreamListener)
    49 NS_IMETHODIMP 
    50 nsStreamLoader::GetNumBytesRead(uint32_t* aNumBytes)
    51 {
    52   *aNumBytes = mLength;
    53   return NS_OK;
    54 }
    56 /* readonly attribute nsIRequest request; */
    57 NS_IMETHODIMP 
    58 nsStreamLoader::GetRequest(nsIRequest **aRequest)
    59 {
    60   NS_IF_ADDREF(*aRequest = mRequest);
    61   return NS_OK;
    62 }
    64 NS_IMETHODIMP 
    65 nsStreamLoader::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
    66 {
    67   nsCOMPtr<nsIChannel> chan( do_QueryInterface(request) );
    68   if (chan) {
    69     int64_t contentLength = -1;
    70     chan->GetContentLength(&contentLength);
    71     if (contentLength >= 0) {
    72       if (contentLength > UINT32_MAX) {
    73         // Too big to fit into uint32, so let's bail.
    74         // XXX we should really make mAllocated and mLength 64-bit instead.
    75         return NS_ERROR_OUT_OF_MEMORY;
    76       }
    77       uint32_t contentLength32 = uint32_t(contentLength);
    78       // preallocate buffer
    79       mData = static_cast<uint8_t*>(moz_malloc(contentLength32));
    80       if (!mData) {
    81         return NS_ERROR_OUT_OF_MEMORY;
    82       }
    83       mAllocated = contentLength32;
    84     }
    85   }
    86   mContext = ctxt;
    87   return NS_OK;
    88 }
    90 NS_IMETHODIMP 
    91 nsStreamLoader::OnStopRequest(nsIRequest* request, nsISupports *ctxt,
    92                               nsresult aStatus)
    93 {
    94   PROFILER_LABEL("network", "nsStreamLoader::OnStopRequest");
    95   if (mObserver) {
    96     // provide nsIStreamLoader::request during call to OnStreamComplete
    97     mRequest = request;
    98     nsresult rv = mObserver->OnStreamComplete(this, mContext, aStatus,
    99                                               mLength, mData);
   100     if (rv == NS_SUCCESS_ADOPTED_DATA) {
   101       // the observer now owns the data buffer, and the loader must
   102       // not deallocate it
   103       mData = nullptr;
   104     }
   105     // done.. cleanup
   106     ReleaseData();
   107     mRequest = 0;
   108     mObserver = 0;
   109     mContext = 0;
   110   }
   111   return NS_OK;
   112 }
   114 NS_METHOD
   115 nsStreamLoader::WriteSegmentFun(nsIInputStream *inStr,
   116                                 void *closure,
   117                                 const char *fromSegment,
   118                                 uint32_t toOffset,
   119                                 uint32_t count,
   120                                 uint32_t *writeCount)
   121 {
   122   nsStreamLoader *self = (nsStreamLoader *) closure;
   124   if (count > UINT32_MAX - self->mLength) {
   125     return NS_ERROR_ILLEGAL_VALUE; // is there a better error to use here?
   126   }
   128   if (self->mLength + count > self->mAllocated) {
   129     self->mData = static_cast<uint8_t*>(NS_Realloc(self->mData,
   130                                                    self->mLength + count));
   131     if (!self->mData) {
   132       self->ReleaseData();
   133       return NS_ERROR_OUT_OF_MEMORY;
   134     }
   135     self->mAllocated = self->mLength + count;
   136   }
   138   ::memcpy(self->mData + self->mLength, fromSegment, count);
   139   self->mLength += count;
   141   *writeCount = count;
   143   return NS_OK;
   144 }
   146 NS_IMETHODIMP 
   147 nsStreamLoader::OnDataAvailable(nsIRequest* request, nsISupports *ctxt, 
   148                                 nsIInputStream *inStr, 
   149                                 uint64_t sourceOffset, uint32_t count)
   150 {
   151   uint32_t countRead;
   152   return inStr->ReadSegments(WriteSegmentFun, this, count, &countRead);
   153 }
   155 void
   156 nsStreamLoader::ReleaseData()
   157 {
   158   if (mData) {
   159     NS_Free(mData);
   160     mData = nullptr;
   161   }
   162   mLength = 0;
   163   mAllocated = 0;
   164 }

mercurial