Back to index

lightning-sunbird  0.9+nobinonly
nsStreamObserverProxy.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Darin Fisher <darin@netscape.com> (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsStreamObserverProxy.h"
00040 #include "nsIGenericFactory.h"
00041 #include "nsIServiceManager.h"
00042 #include "nsIEventQueueService.h"
00043 #include "nsString.h"
00044 
00045 #if defined(PR_LOGGING)
00046 PRLogModuleInfo *gStreamProxyLog;
00047 #endif
00048 #define LOG(args) PR_LOG(gStreamProxyLog, PR_LOG_DEBUG, args)
00049 
00050 static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
00051 
00052 //
00053 //----------------------------------------------------------------------------
00054 // nsStreamObserverEvent implementation...
00055 //----------------------------------------------------------------------------
00056 //
00057 nsStreamObserverEvent::nsStreamObserverEvent(nsStreamProxyBase *aProxy,
00058                                              nsIRequest *aRequest,
00059                                              nsISupports *aContext)
00060     : mProxy(aProxy)
00061     , mRequest(aRequest)
00062     , mContext(aContext)
00063 {
00064     NS_IF_ADDREF(mProxy);
00065 } 
00066 
00067 nsStreamObserverEvent::~nsStreamObserverEvent()
00068 {
00069     NS_IF_RELEASE(mProxy);
00070 }
00071 
00072 nsresult
00073 nsStreamObserverEvent::FireEvent(nsIEventQueue *aEventQ)
00074 {
00075     NS_PRECONDITION(aEventQ, "null event queue");
00076 
00077     PL_InitEvent(&mEvent, nsnull,
00078         (PLHandleEventProc) nsStreamObserverEvent::HandlePLEvent,
00079         (PLDestroyEventProc) nsStreamObserverEvent::DestroyPLEvent);
00080 
00081     PRStatus status = aEventQ->PostEvent(&mEvent);
00082     return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
00083 }
00084 
00085 void PR_CALLBACK
00086 nsStreamObserverEvent::HandlePLEvent(PLEvent *aEvent)
00087 {
00088     nsStreamObserverEvent *ev = GET_STREAM_OBSERVER_EVENT(aEvent);
00089     NS_ASSERTION(ev, "null event");
00090 
00091     // Pass control the real event handler
00092     if (ev)
00093         ev->HandleEvent();
00094 }
00095 
00096 void PR_CALLBACK
00097 nsStreamObserverEvent::DestroyPLEvent(PLEvent *aEvent)
00098 {
00099     nsStreamObserverEvent *ev = GET_STREAM_OBSERVER_EVENT(aEvent);
00100     NS_ASSERTION(ev, "null event");
00101     delete ev;
00102 }
00103 
00104 //
00105 //----------------------------------------------------------------------------
00106 // nsOnStartRequestEvent internal class...
00107 //----------------------------------------------------------------------------
00108 //
00109 class nsOnStartRequestEvent : public nsStreamObserverEvent
00110 {
00111 public:
00112     nsOnStartRequestEvent(nsStreamProxyBase *aProxy,
00113                           nsIRequest *aRequest,
00114                           nsISupports *aContext)
00115         : nsStreamObserverEvent(aProxy, aRequest, aContext)
00116     {
00117         MOZ_COUNT_CTOR(nsOnStartRequestEvent);
00118     }
00119 
00120    ~nsOnStartRequestEvent()
00121     {
00122         MOZ_COUNT_DTOR(nsOnStartRequestEvent);
00123     }
00124 
00125     NS_IMETHOD HandleEvent();
00126 };
00127 
00128 NS_IMETHODIMP
00129 nsOnStartRequestEvent::HandleEvent()
00130 {
00131     LOG(("nsOnStartRequestEvent: HandleEvent [event=%x req=%x]\n",
00132         this, mRequest.get()));
00133 
00134     nsCOMPtr<nsIStreamObserver> observer = mProxy->GetReceiver();
00135     if (!observer) {
00136         LOG(("nsOnStartRequestEvent: Already called OnStopRequest (observer is NULL)\n"));
00137         return NS_ERROR_FAILURE;
00138     }
00139 
00140     nsresult rv = observer->OnStartRequest(mRequest, mContext);
00141     if (NS_FAILED(rv)) {
00142         LOG(("OnStartRequest failed [rv=%x] canceling request!\n", rv));
00143         mRequest->Cancel(rv);
00144     }
00145     return rv;
00146 }
00147 
00148 //
00149 //----------------------------------------------------------------------------
00150 // nsOnStopRequestEvent internal class...
00151 //----------------------------------------------------------------------------
00152 //
00153 class nsOnStopRequestEvent : public nsStreamObserverEvent
00154 {
00155 public:
00156     nsOnStopRequestEvent(nsStreamProxyBase *aProxy,
00157                          nsIRequest *aRequest, nsISupports *aContext,
00158                          nsresult aStatus, const PRUnichar *aStatusText)
00159         : nsStreamObserverEvent(aProxy, aRequest, aContext)
00160         , mStatus(aStatus)
00161         , mStatusText(aStatusText)
00162     {
00163         MOZ_COUNT_CTOR(nsOnStopRequestEvent);
00164     }
00165 
00166    ~nsOnStopRequestEvent()
00167     {
00168         MOZ_COUNT_DTOR(nsOnStopRequestEvent);
00169     }
00170     
00171     NS_IMETHOD HandleEvent();
00172 
00173 protected:
00174     nsresult mStatus;
00175     nsString mStatusText;
00176 };
00177 
00178 NS_IMETHODIMP
00179 nsOnStopRequestEvent::HandleEvent()
00180 {
00181     LOG(("nsOnStopRequestEvent: HandleEvent [event=%x req=%x]\n",
00182         this, mRequest.get()));
00183 
00184     nsCOMPtr<nsIStreamObserver> observer = mProxy->GetReceiver();
00185     if (!observer) {
00186         LOG(("nsOnStopRequestEvent: Already called OnStopRequest (observer is NULL)\n"));
00187         return NS_ERROR_FAILURE;
00188     }
00189 
00190     //
00191     // Do not allow any more events to be handled after OnStopRequest
00192     //
00193     mProxy->SetReceiver(nsnull);
00194 
00195     return observer->OnStopRequest(mRequest,
00196                                    mContext,
00197                                    mStatus,
00198                                    mStatusText.get());
00199 }
00200 
00201 //
00202 //----------------------------------------------------------------------------
00203 // nsStreamProxyBase: nsISupports implementation...
00204 //----------------------------------------------------------------------------
00205 //
00206 NS_IMPL_THREADSAFE_ISUPPORTS1(nsStreamProxyBase,
00207                               nsIStreamObserver)
00208 
00209 //
00210 //----------------------------------------------------------------------------
00211 // nsStreamProxyBase: nsIStreamObserver implementation...
00212 //----------------------------------------------------------------------------
00213 //
00214 NS_IMETHODIMP 
00215 nsStreamProxyBase::OnStartRequest(nsIRequest *aRequest,
00216                                   nsISupports *aContext)
00217 {
00218     LOG(("nsStreamProxyBase: OnStartRequest [this=%x req=%x]\n", this, aRequest));
00219     nsOnStartRequestEvent *ev = 
00220         new nsOnStartRequestEvent(this, aRequest, aContext);
00221     if (!ev)
00222         return NS_ERROR_OUT_OF_MEMORY;
00223 
00224     nsresult rv = ev->FireEvent(GetEventQueue());
00225     if (NS_FAILED(rv))
00226         delete ev;
00227     return rv;
00228 }
00229 
00230 NS_IMETHODIMP 
00231 nsStreamProxyBase::OnStopRequest(nsIRequest *aRequest,
00232                                  nsISupports *aContext,
00233                                  nsresult aStatus,
00234                                  const PRUnichar *aStatusText)
00235 {
00236     LOG(("nsStreamProxyBase: OnStopRequest [this=%x req=%x status=%x]\n",
00237         this, aRequest, aStatus));
00238     nsOnStopRequestEvent *ev = 
00239         new nsOnStopRequestEvent(this, aRequest, aContext, aStatus, aStatusText);
00240     if (!ev)
00241         return NS_ERROR_OUT_OF_MEMORY;
00242 
00243     nsresult rv = ev->FireEvent(GetEventQueue());
00244     if (NS_FAILED(rv))
00245         delete ev;
00246     return rv;
00247 }
00248 
00249 //
00250 //----------------------------------------------------------------------------
00251 // nsStreamProxyBase: implementation...
00252 //----------------------------------------------------------------------------
00253 //
00254 nsresult
00255 nsStreamProxyBase::SetEventQueue(nsIEventQueue *aEventQ)
00256 {
00257 #if defined(PR_LOGGING)
00258     if (!gStreamProxyLog)
00259         gStreamProxyLog = PR_NewLogModule("nsStreamProxy");
00260 #endif
00261     nsresult rv = NS_OK;
00262     if ((aEventQ == NS_CURRENT_EVENTQ) || (aEventQ == NS_UI_THREAD_EVENTQ)) {
00263         nsCOMPtr<nsIEventQueueService> serv =
00264                 do_GetService(kEventQueueService, &rv);
00265         if (NS_FAILED(rv)) 
00266             return rv;
00267         rv = serv->GetSpecialEventQueue((PRInt32) aEventQ,
00268                 getter_AddRefs(mEventQ));
00269     } else
00270         mEventQ = aEventQ;
00271     return rv;
00272 }
00273 
00274 //
00275 //----------------------------------------------------------------------------
00276 // nsStreamObserverProxy: nsISupports implementation...
00277 //----------------------------------------------------------------------------
00278 //
00279 NS_IMPL_ISUPPORTS_INHERITED1(nsStreamObserverProxy,
00280                              nsStreamProxyBase,
00281                              nsIStreamObserverProxy)
00282 
00283 //
00284 //----------------------------------------------------------------------------
00285 // nsStreamObserverProxy: nsIStreamObserverProxy implementation...
00286 //----------------------------------------------------------------------------
00287 //
00288 NS_IMETHODIMP
00289 nsStreamObserverProxy::Init(nsIStreamObserver *aObserver,
00290                             nsIEventQueue *aEventQ)
00291 {
00292     NS_PRECONDITION(aObserver, "null observer");
00293     SetReceiver(aObserver);
00294     return SetEventQueue(aEventQ);
00295 }