LCOV - code coverage report
Current view: directory - content/base/src - FileIOObject.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 122 87 71.3 %
Date: 2012-06-02 Functions: 21 17 81.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozila.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is the Mozilla Foundation
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Kyle Huey <me@kylehuey.com>
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #include "FileIOObject.h"
      39                 : #include "nsDOMFile.h"
      40                 : #include "nsDOMError.h"
      41                 : #include "nsIPrivateDOMEvent.h"
      42                 : #include "nsIDOMEvent.h"
      43                 : #include "nsIDOMProgressEvent.h"
      44                 : #include "nsComponentManagerUtils.h"
      45                 : #include "nsEventDispatcher.h"
      46                 : #include "xpcprivate.h"
      47                 : 
      48                 : #define ERROR_STR "error"
      49                 : #define ABORT_STR "abort"
      50                 : #define PROGRESS_STR "progress"
      51                 : 
      52                 : namespace mozilla {
      53                 : namespace dom {
      54                 : 
      55                 : const PRUint64 kUnknownSize = PRUint64(-1);
      56                 : 
      57             142 : NS_IMPL_ADDREF_INHERITED(FileIOObject, nsDOMEventTargetHelper)
      58             142 : NS_IMPL_RELEASE_INHERITED(FileIOObject, nsDOMEventTargetHelper)
      59                 : 
      60             128 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileIOObject)
      61             128 :   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
      62             128 :   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
      63             126 :   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
      64             126 : NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
      65                 : 
      66            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject)
      67                 : 
      68               4 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject,
      69                 :                                                   nsDOMEventTargetHelper)
      70               4 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressNotifier)
      71               4 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
      72               4 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
      73               4 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(progress)
      74               4 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      75                 : 
      76               2 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
      77                 :                                                 nsDOMEventTargetHelper)
      78               2 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressNotifier)
      79               2 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
      80               2 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
      81               2 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(progress)
      82               2 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      83                 : 
      84               2 : FileIOObject::FileIOObject()
      85                 :   : mProgressEventWasDelayed(false),
      86                 :     mTimerIsActive(false),
      87                 :     mReadyState(0),
      88               2 :     mTotal(0), mTransferred(0)
      89               2 : {}
      90                 : 
      91                 : void
      92               2 : FileIOObject::StartProgressEventTimer()
      93                 : {
      94               2 :   if (!mProgressNotifier) {
      95               2 :     mProgressNotifier = do_CreateInstance(NS_TIMER_CONTRACTID);
      96                 :   }
      97               2 :   if (mProgressNotifier) {
      98               2 :     mProgressEventWasDelayed = false;
      99               2 :     mTimerIsActive = true;
     100               2 :     mProgressNotifier->Cancel();
     101               2 :     mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL,
     102               2 :                                         nsITimer::TYPE_ONE_SHOT);
     103                 :   }
     104               2 : }
     105                 : 
     106                 : void
     107               2 : FileIOObject::ClearProgressEventTimer()
     108                 : {
     109               2 :   mProgressEventWasDelayed = false;
     110               2 :   mTimerIsActive = false;
     111               2 :   if (mProgressNotifier) {
     112               2 :     mProgressNotifier->Cancel();
     113                 :   }
     114               2 : }
     115                 : 
     116                 : void
     117               0 : FileIOObject::DispatchError(nsresult rv, nsAString& finalEvent)
     118                 : {
     119                 :   // Set the status attribute, and dispatch the error event
     120               0 :   switch (rv) {
     121                 :   case NS_ERROR_FILE_NOT_FOUND:
     122               0 :     mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotFoundError"));
     123               0 :     break;
     124                 :   case NS_ERROR_FILE_ACCESS_DENIED:
     125               0 :     mError = DOMError::CreateWithName(NS_LITERAL_STRING("SecurityError"));
     126               0 :     break;
     127                 :   default:
     128               0 :     mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotReadableError"));
     129               0 :     break;
     130                 :   }
     131                 : 
     132                 :   // Dispatch error event to signify load failure
     133               0 :   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
     134               0 :   DispatchProgressEvent(finalEvent);
     135               0 : }
     136                 : 
     137                 : nsresult
     138               8 : FileIOObject::DispatchProgressEvent(const nsAString& aType)
     139                 : {
     140              16 :   nsCOMPtr<nsIDOMEvent> event;
     141                 :   nsresult rv = nsEventDispatcher::CreateEvent(nsnull, nsnull,
     142               8 :                                                NS_LITERAL_STRING("ProgressEvent"),
     143              16 :                                                getter_AddRefs(event));
     144               8 :   NS_ENSURE_SUCCESS(rv, rv);
     145                 : 
     146              16 :   nsCOMPtr<nsIPrivateDOMEvent> privevent(do_QueryInterface(event));
     147               8 :   NS_ENSURE_TRUE(privevent, NS_ERROR_UNEXPECTED);
     148                 : 
     149               8 :   privevent->SetTrusted(true);
     150              16 :   nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
     151               8 :   NS_ENSURE_TRUE(progress, NS_ERROR_UNEXPECTED);
     152                 : 
     153                 :   bool known;
     154                 :   PRUint64 size;
     155               8 :   if (mTotal != kUnknownSize) {
     156               8 :     known = true;
     157               8 :     size = mTotal;
     158                 :   } else {
     159               0 :     known = false;
     160               0 :     size = 0;
     161                 :   }
     162               8 :   rv = progress->InitProgressEvent(aType, false, false, known,
     163               8 :                                    mTransferred, size);
     164               8 :   NS_ENSURE_SUCCESS(rv, rv);
     165                 : 
     166               8 :   return DispatchDOMEvent(nsnull, event, nsnull, nsnull);
     167                 : }
     168                 : 
     169                 : // nsITimerCallback
     170                 : NS_IMETHODIMP
     171               0 : FileIOObject::Notify(nsITimer* aTimer)
     172                 : {
     173                 :   nsresult rv;
     174               0 :   mTimerIsActive = false;
     175                 : 
     176               0 :   if (mProgressEventWasDelayed) {
     177               0 :     rv = DispatchProgressEvent(NS_LITERAL_STRING("progress"));
     178               0 :     NS_ENSURE_SUCCESS(rv, rv);
     179                 : 
     180               0 :     StartProgressEventTimer();
     181                 :   }
     182                 : 
     183               0 :   return NS_OK;
     184                 : }
     185                 : 
     186                 : // nsIStreamListener
     187                 : NS_IMETHODIMP
     188               2 : FileIOObject::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
     189                 : {
     190               2 :   return DoOnStartRequest(aRequest, aContext);
     191                 : }
     192                 : 
     193                 : NS_IMETHODIMP
     194               2 : FileIOObject::DoOnStartRequest(nsIRequest *request, nsISupports *ctxt)
     195                 : {
     196               2 :   return NS_OK;
     197                 : }
     198                 : 
     199                 : NS_IMETHODIMP
     200               2 : FileIOObject::OnDataAvailable(nsIRequest *aRequest,
     201                 :                               nsISupports *aContext,
     202                 :                               nsIInputStream *aInputStream,
     203                 :                               PRUint32 aOffset,
     204                 :                               PRUint32 aCount)
     205                 : {
     206                 :   nsresult rv;
     207               2 :   rv = DoOnDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
     208               2 :   NS_ENSURE_SUCCESS(rv, rv);
     209                 : 
     210               2 :   mTransferred += aCount;
     211                 : 
     212                 :   //Notify the timer is the appropriate timeframe has passed
     213               2 :   if (mTimerIsActive) {
     214               0 :     mProgressEventWasDelayed = true;
     215                 :   } else {
     216               2 :     rv = DispatchProgressEvent(NS_LITERAL_STRING(PROGRESS_STR));
     217               2 :     NS_ENSURE_SUCCESS(rv, rv);
     218                 : 
     219               2 :     StartProgressEventTimer();
     220                 :   }
     221                 : 
     222               2 :   return NS_OK;
     223                 : }
     224                 : 
     225                 : NS_IMETHODIMP
     226               2 : FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
     227                 :                             nsresult aStatus)
     228                 : {
     229                 :   // If we're here as a result of a call from Abort(),
     230                 :   // simply ignore the request.
     231               2 :   if (aRequest != mChannel)
     232               0 :     return NS_OK;
     233                 : 
     234                 :   // Cancel the progress event timer
     235               2 :   ClearProgressEventTimer();
     236                 : 
     237                 :   // FileIOObject must be in DONE stage after an operation
     238               2 :   mReadyState = 2;
     239                 : 
     240               4 :   nsString successEvent, termEvent;
     241                 :   nsresult rv = DoOnStopRequest(aRequest, aContext, aStatus,
     242               2 :                                 successEvent, termEvent);
     243               2 :   NS_ENSURE_SUCCESS(rv, rv);
     244                 : 
     245                 :   // Set the status field as appropriate
     246               2 :   if (NS_FAILED(aStatus)) {
     247               0 :     DispatchError(aStatus, termEvent);
     248               0 :     return NS_OK;
     249                 :   }
     250                 : 
     251                 :   // Dispatch event to signify end of a successful operation
     252               2 :   DispatchProgressEvent(successEvent);
     253               2 :   DispatchProgressEvent(termEvent);
     254                 : 
     255               2 :   return NS_OK;
     256                 : }
     257                 : 
     258                 : NS_IMETHODIMP
     259               2 : FileIOObject::Abort()
     260                 : {
     261               2 :   if (mReadyState != 1) {
     262                 :     // XXX The spec doesn't say this
     263               2 :     return NS_ERROR_DOM_FILE_ABORT_ERR;
     264                 :   }
     265                 : 
     266               0 :   ClearProgressEventTimer();
     267                 : 
     268               0 :   mReadyState = 2; // There are DONE constants on multiple interfaces,
     269                 :                    // but they all have value 2.
     270                 :   // XXX The spec doesn't say this
     271               0 :   mError = DOMError::CreateWithName(NS_LITERAL_STRING("AbortError"));
     272                 : 
     273               0 :   nsString finalEvent;
     274               0 :   nsresult rv = DoAbort(finalEvent);
     275                 : 
     276                 :   // Dispatch the events
     277               0 :   DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
     278               0 :   DispatchProgressEvent(finalEvent);
     279                 : 
     280               0 :   return rv;
     281                 : }
     282                 : 
     283                 : NS_IMETHODIMP
     284               2 : FileIOObject::GetReadyState(PRUint16 *aReadyState)
     285                 : {
     286               2 :   *aReadyState = mReadyState;
     287               2 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : NS_IMETHODIMP
     291               0 : FileIOObject::GetError(nsIDOMDOMError** aError)
     292                 : {
     293               0 :   NS_IF_ADDREF(*aError = mError);
     294               0 :   return NS_OK;
     295                 : }
     296                 : 
     297                 : } // namespace dom
     298            4392 : } // namespace mozilla

Generated by: LCOV version 1.7