LCOV - code coverage report
Current view: top level - netwerk/base - nsStreamListenerTee.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 30 63 47.6 %
Date: 2017-07-14 16:53:18 Functions: 6 9 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
       5             : #include "nsStreamListenerTee.h"
       6             : #include "nsProxyRelease.h"
       7             : 
       8             : namespace mozilla {
       9             : namespace net {
      10             : 
      11          26 : NS_IMPL_ISUPPORTS(nsStreamListenerTee,
      12             :                   nsIStreamListener,
      13             :                   nsIRequestObserver,
      14             :                   nsIStreamListenerTee,
      15             :                   nsIThreadRetargetableStreamListener)
      16             : 
      17             : NS_IMETHODIMP
      18           0 : nsStreamListenerTee::OnStartRequest(nsIRequest *request,
      19             :                                     nsISupports *context)
      20             : {
      21           0 :     NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
      22           0 :     nsresult rv1 = mListener->OnStartRequest(request, context);
      23           0 :     nsresult rv2 = NS_OK;
      24           0 :     if (mObserver)
      25           0 :         rv2 = mObserver->OnStartRequest(request, context);
      26             : 
      27             :     // Preserve NS_SUCCESS_XXX in rv1 in case mObserver didn't throw
      28           0 :     return (NS_FAILED(rv2) && NS_SUCCEEDED(rv1)) ? rv2 : rv1;
      29             : }
      30             : 
      31             : NS_IMETHODIMP
      32           2 : nsStreamListenerTee::OnStopRequest(nsIRequest *request,
      33             :                                    nsISupports *context,
      34             :                                    nsresult status)
      35             : {
      36           2 :     NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
      37             :     // it is critical that we close out the input stream tee
      38           2 :     if (mInputTee) {
      39           2 :         mInputTee->SetSink(nullptr);
      40           2 :         mInputTee = nullptr;
      41             :     }
      42             : 
      43             :     // release sink on the same thread where the data was written (bug 716293)
      44           2 :     if (mEventTarget) {
      45           0 :       NS_ProxyRelease(
      46           0 :         "nsStreamListenerTee::mSink", mEventTarget, mSink.forget());
      47             :     }
      48             :     else {
      49           2 :         mSink = nullptr;
      50             :     }
      51             : 
      52           2 :     nsresult rv = mListener->OnStopRequest(request, context, status);
      53           2 :     if (mObserver)
      54           0 :         mObserver->OnStopRequest(request, context, status);
      55           2 :     mObserver = nullptr;
      56           2 :     return rv;
      57             : }
      58             : 
      59             : NS_IMETHODIMP
      60           2 : nsStreamListenerTee::OnDataAvailable(nsIRequest *request,
      61             :                                      nsISupports *context,
      62             :                                      nsIInputStream *input,
      63             :                                      uint64_t offset,
      64             :                                      uint32_t count)
      65             : {
      66           2 :     NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
      67           2 :     NS_ENSURE_TRUE(mSink, NS_ERROR_NOT_INITIALIZED);
      68             : 
      69           4 :     nsCOMPtr<nsIInputStream> tee;
      70             :     nsresult rv;
      71             : 
      72           2 :     if (!mInputTee) {
      73           2 :         if (mEventTarget)
      74           0 :             rv = NS_NewInputStreamTeeAsync(getter_AddRefs(tee), input,
      75             :                                            mSink, mEventTarget);
      76             :         else
      77           2 :             rv = NS_NewInputStreamTee(getter_AddRefs(tee), input, mSink);
      78           2 :         if (NS_FAILED(rv)) return rv;
      79             : 
      80           2 :         mInputTee = do_QueryInterface(tee, &rv);
      81           2 :         if (NS_FAILED(rv)) return rv;
      82             :     }
      83             :     else {
      84             :         // re-initialize the input tee since the input stream may have changed.
      85           0 :         rv = mInputTee->SetSource(input);
      86           0 :         if (NS_FAILED(rv)) return rv;
      87             : 
      88           0 :         tee = do_QueryInterface(mInputTee, &rv);
      89           0 :         if (NS_FAILED(rv)) return rv;
      90             :     }
      91             : 
      92           2 :     return mListener->OnDataAvailable(request, context, tee, offset, count);
      93             : }
      94             : 
      95             : NS_IMETHODIMP
      96           0 : nsStreamListenerTee::CheckListenerChain()
      97             : {
      98           0 :     NS_ASSERTION(NS_IsMainThread(), "Should be on main thread!");
      99           0 :     nsresult rv = NS_OK;
     100             :     nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
     101           0 :         do_QueryInterface(mListener, &rv);
     102           0 :     if (retargetableListener) {
     103           0 :         rv = retargetableListener->CheckListenerChain();
     104             :     }
     105           0 :     if (NS_FAILED(rv)) {
     106           0 :       return rv;
     107             :     }
     108           0 :     if (!mObserver) {
     109           0 :       return rv;
     110             :     }
     111           0 :     retargetableListener = do_QueryInterface(mObserver, &rv);
     112           0 :     if (retargetableListener) {
     113           0 :         rv = retargetableListener->CheckListenerChain();
     114             :     }
     115           0 :     return rv;
     116             : }
     117             : 
     118             : NS_IMETHODIMP
     119           2 : nsStreamListenerTee::Init(nsIStreamListener *listener,
     120             :                           nsIOutputStream *sink,
     121             :                           nsIRequestObserver *requestObserver)
     122             : {
     123           2 :     NS_ENSURE_ARG_POINTER(listener);
     124           2 :     NS_ENSURE_ARG_POINTER(sink);
     125           2 :     mListener = listener;
     126           2 :     mSink = sink;
     127           2 :     mObserver = requestObserver;
     128           2 :     return NS_OK;
     129             : }
     130             : 
     131             : NS_IMETHODIMP
     132           0 : nsStreamListenerTee::InitAsync(nsIStreamListener *listener,
     133             :                                nsIEventTarget *eventTarget,
     134             :                                nsIOutputStream *sink,
     135             :                                nsIRequestObserver *requestObserver)
     136             : {
     137           0 :     NS_ENSURE_ARG_POINTER(eventTarget);
     138           0 :     mEventTarget = eventTarget;
     139           0 :     return Init(listener, sink, requestObserver);
     140             : }
     141             : 
     142             : } // namespace net
     143             : } // namespace mozilla

Generated by: LCOV version 1.13