Back to index

lightning-sunbird  0.9+nobinonly
TestCallbacks.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "TestCommon.h"
00039 #include <stdio.h>
00040 #ifdef WIN32 
00041 #include <windows.h>
00042 #endif
00043 #include "nspr.h"
00044 #include "nscore.h"
00045 #include "nsCOMPtr.h"
00046 #include "nsIEventQueueService.h"
00047 #include "nsIIOService.h"
00048 #include "nsIServiceManager.h"
00049 #include "nsIStreamListener.h"
00050 #include "nsIInputStream.h"
00051 #include "nsCRT.h"
00052 #include "nsIChannel.h"
00053 #include "nsIURL.h"
00054 #include "nsIInterfaceRequestor.h" 
00055 #include "nsIInterfaceRequestorUtils.h"
00056 #include "nsIDNSService.h" 
00057 
00058 #include "nsISimpleEnumerator.h"
00059 #include "nsXPIDLString.h"
00060 #include "nsNetUtil.h"
00061 
00062 static NS_DEFINE_CID(kEventQueueServiceCID,      NS_EVENTQUEUESERVICE_CID);
00063 static NS_DEFINE_CID(kIOServiceCID,              NS_IOSERVICE_CID);
00064 
00065 static int gKeepRunning = 0;
00066 static nsIEventQueue* gEventQ = nsnull;
00067 static PRBool gError = PR_FALSE;
00068 
00069 #define NS_IEQUALS_IID \
00070     { 0x11c5c8ee, 0x1dd2, 0x11b2, \
00071       { 0xa8, 0x93, 0xbb, 0x23, 0xa1, 0xb6, 0x27, 0x76 }}
00072 
00073 class nsIEquals : public nsISupports {
00074 public:
00075     NS_DEFINE_STATIC_IID_ACCESSOR(NS_IEQUALS_IID)
00076     NS_IMETHOD Equals(void *aPtr, PRBool *_retval) = 0;
00077 };
00078 
00079 class ConsumerContext : public nsIEquals {
00080 public:
00081     NS_DECL_ISUPPORTS
00082 
00083     ConsumerContext() { }
00084 
00085     NS_IMETHOD Equals(void *aPtr, PRBool *_retval) {
00086         *_retval = PR_TRUE;
00087         if (aPtr != this) *_retval = PR_FALSE;
00088         return NS_OK;
00089     };
00090 };
00091 
00092 NS_IMPL_THREADSAFE_ISUPPORTS1(ConsumerContext, nsIEquals)
00093 
00094 class Consumer : public nsIStreamListener {
00095 public:
00096     NS_DECL_ISUPPORTS
00097     NS_DECL_NSIREQUESTOBSERVER
00098     NS_DECL_NSISTREAMLISTENER
00099 
00100     Consumer();
00101     virtual ~Consumer();
00102     nsresult Init(nsIURI *aURI, nsIChannel *aChannel, nsISupports *aContext);
00103     nsresult Validate(nsIRequest *request, nsISupports *aContext);
00104 
00105     // member data
00106     PRBool  mOnStart; // have we received an OnStart?
00107     PRBool  mOnStop;  // have we received an onStop?
00108     PRInt32 mOnDataCount; // number of times OnData was called.
00109     nsCOMPtr<nsIURI>     mURI;
00110     nsCOMPtr<nsIChannel> mChannel;
00111     nsCOMPtr<nsIEquals>  mContext;
00112 };
00113 
00114 // nsISupports implementation
00115 NS_IMPL_THREADSAFE_ISUPPORTS2(Consumer, nsIStreamListener, nsIRequestObserver)
00116 
00117 
00118 // nsIRequestObserver implementation
00119 NS_IMETHODIMP
00120 Consumer::OnStartRequest(nsIRequest *request, nsISupports* aContext) {
00121     fprintf(stderr, "Consumer::OnStart() -> in\n\n");
00122 
00123     if (mOnStart) {
00124         fprintf(stderr, "INFO: multiple OnStarts received\n");
00125     }
00126     mOnStart = PR_TRUE;
00127 
00128     nsresult rv = Validate(request, aContext);
00129     if (NS_FAILED(rv)) return rv;
00130 
00131     fprintf(stderr, "Consumer::OnStart() -> out\n\n");
00132     return rv;
00133 }
00134 
00135 NS_IMETHODIMP
00136 Consumer::OnStopRequest(nsIRequest *request, nsISupports *aContext,
00137                         nsresult aStatus) {
00138     fprintf(stderr, "Consumer::OnStop() -> in\n\n");
00139 
00140     if (!mOnStart) {
00141         gError = PR_TRUE;
00142         fprintf(stderr, "ERROR: No OnStart received\n");
00143     }
00144 
00145     if (mOnStop) {
00146         fprintf(stderr, "INFO: multiple OnStops received\n");
00147     }
00148 
00149     fprintf(stderr, "INFO: received %d OnData()s\n", mOnDataCount);
00150 
00151     mOnStop = PR_TRUE;
00152 
00153     nsresult rv = Validate(request, aContext);
00154     if (NS_FAILED(rv)) return rv;
00155 
00156     fprintf(stderr, "Consumer::OnStop() -> out\n\n");
00157     return rv;
00158 }
00159 
00160 
00161 // nsIStreamListener implementation
00162 NS_IMETHODIMP
00163 Consumer::OnDataAvailable(nsIRequest *request, nsISupports *aContext,
00164                           nsIInputStream *aIStream,
00165                           PRUint32 aOffset, PRUint32 aLength) {
00166     fprintf(stderr, "Consumer::OnData() -> in\n\n");
00167 
00168     if (!mOnStart) {
00169         gError = PR_TRUE;
00170         fprintf(stderr, "ERROR: No OnStart received\n");
00171     }
00172 
00173     mOnDataCount += 1;
00174 
00175     nsresult rv = Validate(request, aContext);
00176     if (NS_FAILED(rv)) return rv;
00177 
00178     fprintf(stderr, "Consumer::OnData() -> out\n\n");
00179     return rv;
00180 }
00181 
00182 // Consumer implementation
00183 Consumer::Consumer() {
00184     mOnStart = mOnStop = PR_FALSE;
00185     mOnDataCount = 0;
00186     gKeepRunning++;
00187 }
00188 
00189 Consumer::~Consumer() {
00190     fprintf(stderr, "Consumer::~Consumer -> in\n\n");
00191 
00192     if (!mOnStart) {
00193         gError = PR_TRUE;
00194         fprintf(stderr, "ERROR: Never got an OnStart\n");
00195     }
00196 
00197     if (!mOnStop) {
00198         gError = PR_TRUE;
00199         fprintf(stderr, "ERROR: Never got an OnStop \n");
00200     }
00201 
00202     fprintf(stderr, "Consumer::~Consumer -> out\n\n");
00203     gKeepRunning--;
00204 }
00205 
00206 nsresult
00207 Consumer::Init(nsIURI *aURI, nsIChannel* aChannel, nsISupports *aContext) {
00208     mURI     = aURI;
00209     mChannel = aChannel;
00210     mContext = do_QueryInterface(aContext);
00211     return NS_OK;
00212 }
00213 
00214 nsresult
00215 Consumer::Validate(nsIRequest* request, nsISupports *aContext) {
00216     nsresult rv = NS_OK;
00217     nsCOMPtr<nsIURI> uri;
00218     nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
00219 
00220     rv = aChannel->GetURI(getter_AddRefs(uri));
00221     if (NS_FAILED(rv)) return rv;
00222 
00223     PRBool same = PR_FALSE;
00224 
00225     rv = mURI->Equals(uri, &same);
00226     if (NS_FAILED(rv)) return rv;
00227 
00228     if (!same)
00229         fprintf(stderr, "INFO: URIs do not match\n");
00230 
00231     rv = mContext->Equals((void*)aContext, &same);
00232     if (NS_FAILED(rv)) return rv;
00233 
00234     if (!same) {
00235         gError = PR_TRUE;
00236         fprintf(stderr, "ERROR: Contexts do not match\n");
00237     }
00238     return rv;
00239 }
00240 
00241 nsresult StartLoad(const char *);
00242 
00243 int main(int argc, char *argv[]) {
00244     if (test_common_init(&argc, &argv) != 0)
00245         return -1;
00246 
00247     nsresult rv = NS_OK;
00248     PRBool cmdLineURL = PR_FALSE;
00249 
00250     if (argc > 1) {
00251         // run in signle url mode
00252         cmdLineURL = PR_TRUE;
00253     }
00254 
00255     rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
00256     if (NS_FAILED(rv)) return rv;
00257 
00258     // Create the Event Queue for this thread...
00259     nsCOMPtr<nsIEventQueueService> eventQService = 
00260              do_GetService(kEventQueueServiceCID, &rv);
00261     if (NS_FAILED(rv)) return rv;
00262 
00263     rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
00264     if (NS_FAILED(rv)) return rv;
00265 
00266     if (cmdLineURL) {
00267         rv = StartLoad(argv[1]);
00268     } else {
00269         rv = StartLoad("http://badhostnamexyz/test.txt");
00270     }
00271     if (NS_FAILED(rv)) return rv;
00272 
00273     // Enter the message pump to allow the URL load to proceed.
00274     while ( gKeepRunning ) {
00275         PLEvent *gEvent;
00276         gEventQ->WaitForEvent(&gEvent);
00277         gEventQ->HandleEvent(gEvent);
00278     }
00279 
00280     NS_ShutdownXPCOM(nsnull);
00281     if (gError) {
00282         fprintf(stderr, "\n\n-------ERROR-------\n\n");
00283     }
00284     return rv;
00285 }
00286 
00287 nsresult StartLoad(const char *aURISpec) {
00288     nsresult rv = NS_OK;
00289 
00290     // create a context
00291     ConsumerContext *context = new ConsumerContext;
00292     nsCOMPtr<nsISupports> contextSup = do_QueryInterface(context, &rv);
00293     if (NS_FAILED(rv)) return rv;
00294 
00295 
00296     nsCOMPtr<nsIIOService> serv = do_GetService(kIOServiceCID, &rv);
00297     if (NS_FAILED(rv)) return rv;
00298 
00299     // create a uri
00300     nsCOMPtr<nsIURI> uri;
00301     rv = NS_NewURI(getter_AddRefs(uri), aURISpec);
00302     if (NS_FAILED(rv)) return rv;
00303 
00304     // create a channel
00305     nsCOMPtr<nsIChannel> channel;
00306     rv = serv->NewChannelFromURI(uri, getter_AddRefs(channel));
00307     if (NS_FAILED(rv)) return rv;
00308 
00309     Consumer *consumer = new Consumer;
00310     rv = consumer->Init(uri, channel, contextSup);
00311     if (NS_FAILED(rv)) return rv;
00312 
00313     // kick off the load
00314     nsCOMPtr<nsIRequest> request;
00315     return channel->AsyncOpen(NS_STATIC_CAST(nsIStreamListener*, consumer), contextSup);
00316 }