Back to index

lightning-sunbird  0.9+nobinonly
TestPageLoad.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; 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 Communicator client 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 "nsNetUtil.h"
00040 #include "nsIEventQueueService.h"
00041 #include "nsIServiceManager.h"
00042 #include "nsIInterfaceRequestor.h"
00043 #include "nsIInterfaceRequestorUtils.h"
00044 #include "nsIProgressEventSink.h"
00045 #include "nsIComponentManager.h"
00046 #include "prprf.h"
00047 #include "nsXPCOM.h"
00048 #include "nsISupportsPrimitives.h"
00049 #include "nsTimer.h"
00050 #include "prlong.h"
00051 #include "plstr.h"
00052 #include "nsSupportsArray.h"
00053 #include "nsReadableUtils.h"
00054 #include "nsIComponentRegistrar.h"
00055 int getStrLine(const char *src, char *str, int ind, int max);
00056 nsresult auxLoad(char *uriBuf);
00057 //----------------------------------------------------------------------
00058 
00059 
00060 #define RETURN_IF_FAILED(rv, step) \
00061     PR_BEGIN_MACRO \
00062     if (NS_FAILED(rv)) { \
00063         printf(">>> %s failed: rv=%x\n", step, rv); \
00064         return rv;\
00065     } \
00066     PR_END_MACRO
00067 
00068 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
00069 static nsIEventQueue* gEventQ = nsnull;
00070 static PRBool gKeepRunning = PR_FALSE;
00071 static nsCString globalStream;
00072 //static char urlBuf[256];
00073 static nsCOMPtr<nsIURI> baseURI;
00074 static nsCOMPtr<nsISupportsArray> uriList;
00075 
00076 //Temp, should remove:
00077 static int numStart=0;
00078 static int numFound=0;
00079 
00080 
00081 //--------writer fun----------------------
00082 
00083 static NS_METHOD streamParse (nsIInputStream* in,
00084                               void* closure,
00085                               const char* fromRawSegment,
00086                               PRUint32 toOffset,
00087                               PRUint32 count,
00088                               PRUint32 *writeCount) {
00089 
00090   char parseBuf[2048], loc[2048], lineBuf[2048];
00091   char *loc_t, *loc_t2;
00092   int i = 0;
00093   char *tmp;
00094 
00095   if(!globalStream.IsEmpty()) {
00096     globalStream.Append(fromRawSegment);
00097     tmp = ToNewCString(globalStream);
00098     //printf("\n>>NOW:\n^^^^^\n%s\n^^^^^^^^^^^^^^", tmp);
00099   } else {
00100     tmp = (char *)fromRawSegment;
00101   }
00102 
00103   while(i < (int)count) {
00104     i = getStrLine(tmp, lineBuf, i, count);
00105     if(i < 0) {
00106       *writeCount = count;
00107       return NS_OK;
00108     }
00109     parseBuf[0]='\0';
00110     if((loc_t=PL_strcasestr(lineBuf, "img"))!= NULL 
00111        || (loc_t=PL_strcasestr(lineBuf, "script"))!=NULL) {
00112       loc_t2=PL_strcasestr(loc_t, "src");
00113       if(loc_t2!=NULL) {
00114         loc_t2+=3;
00115         strcpy(loc, loc_t2);
00116         sscanf(loc, "=\"%[^\"]", parseBuf);
00117         if(parseBuf[0]=='\0')
00118           sscanf(loc, "=%s", parseBuf);         
00119         if(parseBuf[0]!='\0'){
00120           numFound++;
00121           auxLoad(parseBuf);
00122         }     
00123       }
00124     }
00125 
00126     /***NEED BETTER CHECK FOR STYLESHEETS
00127     if((loc_t=PL_strcasestr(lineBuf, "link"))!= NULL) { 
00128        loc_t2=PL_strcasestr(loc_t, "href");
00129       if(loc_t2!=NULL) {
00130         loc_t2+=4;
00131         strcpy(loc, loc_t2);
00132         //printf("%s\n", loc);
00133         sscanf(loc, "=\"%[^\"]", parseBuf);
00134         if(parseBuf[0]!='\0'){
00135           //printf("%s\n", parseBuf);
00136           numFound++;
00137           auxLoad(parseBuf);
00138         }     
00139       }
00140     }
00141     */
00142     if((loc_t=PL_strcasestr(lineBuf, "background"))!=NULL) {
00143       loc_t+=10;
00144       strcpy(loc, loc_t);
00145       sscanf(loc, "=\"%[^\"]", parseBuf);
00146       if(parseBuf[0]!='\0') {
00147         numFound++;
00148         auxLoad(parseBuf);
00149       }
00150     }
00151     i++;
00152 
00153   }
00154   *writeCount = count;
00155   return NS_OK;
00156 }
00157 
00158 //-----------------------------------------------------------------------------
00159 // nsIStreamListener implementation
00160 //-----------------------------------------------------------------------------
00161 
00162 class MyListener : public nsIStreamListener
00163 {
00164 public:
00165     NS_DECL_ISUPPORTS
00166     NS_DECL_NSIREQUESTOBSERVER
00167     NS_DECL_NSISTREAMLISTENER
00168 
00169     MyListener() { }
00170     virtual ~MyListener() {}
00171 };
00172 
00173 NS_IMPL_ISUPPORTS2(MyListener,
00174                    nsIRequestObserver,
00175                    nsIStreamListener)
00176 
00177 NS_IMETHODIMP
00178 MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt)
00179 {
00180   //printf(">>> OnStartRequest\n");
00181     numStart++;
00182     return NS_OK;
00183 }
00184 
00185 NS_IMETHODIMP
00186 MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status)
00187 {
00188     //printf(">>> OnStopRequest status=%x\n", status);
00189     gKeepRunning--;
00190     return NS_OK;
00191 }
00192 
00193 NS_IMETHODIMP
00194 MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt,
00195                             nsIInputStream *stream,
00196                             PRUint32 offset, PRUint32 count)
00197 {
00198     //printf(">>> OnDataAvailable [count=%u]\n", count);
00199     nsresult rv = NS_ERROR_FAILURE;
00200     PRUint32 bytesRead=0;
00201     char buf[1024];
00202 
00203     if(ctxt == nsnull) {
00204       bytesRead=0;
00205       rv = stream->ReadSegments(streamParse, &offset, count, &bytesRead);
00206     } else {
00207       while (count) {
00208         PRUint32 amount = PR_MIN(count, sizeof(buf));
00209         rv = stream->Read(buf, amount, &bytesRead);  
00210         count -= bytesRead;
00211       }
00212     }
00213 
00214     if (NS_FAILED(rv)) {
00215       printf(">>> stream->Read failed with rv=%x\n", rv);
00216       return rv;
00217     }
00218 
00219     return NS_OK;
00220 }
00221 
00222 //-----------------------------------------------------------------------------
00223 // NotificationCallbacks implementation
00224 //-----------------------------------------------------------------------------
00225 
00226 class MyNotifications : public nsIInterfaceRequestor
00227                       , public nsIProgressEventSink
00228 {
00229 public:
00230     NS_DECL_ISUPPORTS
00231     NS_DECL_NSIINTERFACEREQUESTOR
00232     NS_DECL_NSIPROGRESSEVENTSINK
00233 
00234     MyNotifications() { }
00235     virtual ~MyNotifications() {}
00236 };
00237 
00238 NS_IMPL_THREADSAFE_ISUPPORTS2(MyNotifications,
00239                               nsIInterfaceRequestor,
00240                               nsIProgressEventSink)
00241 
00242 NS_IMETHODIMP
00243 MyNotifications::GetInterface(const nsIID &iid, void **result)
00244 {
00245     return QueryInterface(iid, result);
00246 }
00247 
00248 NS_IMETHODIMP
00249 MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx,
00250                           nsresult status, const PRUnichar *statusText)
00251 {
00252     //printf("status: %x\n", status);
00253     return NS_OK;
00254 }
00255 
00256 NS_IMETHODIMP
00257 MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx,
00258                             PRUint64 progress, PRUint64 progressMax)
00259 {
00260     // char buf[100];
00261     // PR_snprintf(buf, sizeof(buf), "%llu/%llu\n", progress, progressMax);
00262     // printf("%s", buf);
00263     return NS_OK;
00264 }
00265 
00266 //-----------------------------------------------------------------------------
00267 // main, etc..
00268 //-----------------------------------------------------------------------------
00269 
00270 //---------getStrLine Helper function---------------
00271 //Finds a newline in src starting at ind. Puts the
00272 //line in str (must be big enough). Returns the index
00273 //of the newline, or -1 if at end of string. If reaches 
00274 //end of string ('\0'), then will copy contents to 
00275 //globalStream. 
00276 int getStrLine(const char *src, char *str, int ind, int max) {
00277   char c = src[ind];
00278   int i=0;
00279   globalStream.AssignLiteral("\0");
00280   while(c!='\n' && c!='\0' && i<max) {
00281     str[i] = src[ind];
00282     i++; ind++;
00283     c = src[ind];
00284   }
00285   str[i]='\0';
00286   if(i==max || c=='\0') {
00287     globalStream.Assign(str);
00288     //printf("\nCarryover (%d|%d):\n------------\n%s\n-------\n",i,max,str);
00289     return -1;
00290   }
00291   return ind;
00292 }
00293 
00294 //----------AUX LOAD-----------
00295 nsresult auxLoad(char *uriBuf)
00296 {
00297     nsresult rv;
00298 
00299     nsCOMPtr<nsISupportsPRBool> myBool = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
00300 
00301     nsCOMPtr<nsIURI> uri;
00302     nsCOMPtr<nsIChannel> chan;
00303     nsCOMPtr<nsIStreamListener> listener = new MyListener();
00304     nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
00305 
00306     printf("Getting: %s", uriBuf);
00307 
00308     //If relative link
00309     if(strncmp(uriBuf, "http:", 5)) {
00310       //Relative link
00311       rv = NS_NewURI(getter_AddRefs(uri), uriBuf, baseURI);
00312       if (NS_FAILED(rv)) return(rv);
00313     } else {
00314       //Absolute link, no base needed
00315       rv = NS_NewURI(getter_AddRefs(uri), uriBuf);
00316       if (NS_FAILED(rv)) return(rv);
00317     }
00318 
00319     //Compare to see if exists
00320     PRUint32 num;
00321     uriList->Count(&num);
00322     PRBool equal;
00323     nsCOMPtr<nsIURI> uriTmp;
00324     for(PRUint32 i = 0; i < num; i++) {
00325       uriList->GetElementAt(i, getter_AddRefs(uriTmp));
00326       uri->Equals(uriTmp, &equal);
00327       if(equal) {
00328         printf("(duplicate, canceling) %s\n",uriBuf); 
00329         return NS_OK;
00330       }
00331     }
00332     printf("\n");
00333     uriList->AppendElement(uri);
00334     rv = NS_NewChannel(getter_AddRefs(chan), uri, nsnull, nsnull, callbacks);
00335     RETURN_IF_FAILED(rv, "NS_NewChannel");
00336 
00337     gKeepRunning++;
00338     rv = chan->AsyncOpen(listener, myBool);
00339     RETURN_IF_FAILED(rv, "AsyncOpen");
00340 
00341     return NS_OK;
00342 
00343 }
00344 
00345 //---------Buffer writer fun---------
00346 
00347 
00348 //---------MAIN-----------
00349 
00350 int main(int argc, char **argv)
00351 { 
00352     if (test_common_init(&argc, &argv) != 0)
00353         return -1;
00354 
00355     nsresult rv;
00356 
00357     if (argc == 1) {
00358         printf("usage: TestPageLoad <url>\n");
00359         return -1;
00360     }
00361     {
00362         nsCOMPtr<nsIServiceManager> servMan;
00363         NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
00364         nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
00365         NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
00366         if (registrar)
00367             registrar->AutoRegister(nsnull);
00368 
00369         PRTime start, finish;
00370 
00371         rv = NS_NewISupportsArray(getter_AddRefs(uriList));
00372         RETURN_IF_FAILED(rv, "NS_NewISupportsArray");
00373 
00374         // Create the Event Queue for this thread...
00375         nsCOMPtr<nsIEventQueueService> eqs =
00376                  do_GetService(kEventQueueServiceCID, &rv);
00377         RETURN_IF_FAILED(rv, "do_GetService(EventQueueService)");
00378 
00379         rv = eqs->CreateMonitoredThreadEventQueue();
00380         RETURN_IF_FAILED(rv, "CreateMonitoredThreadEventQueue");
00381 
00382         rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
00383         RETURN_IF_FAILED(rv, "GetThreadEventQueue");
00384 
00385         printf("Loading necko ... \n");
00386         nsCOMPtr<nsIChannel> chan;
00387         nsCOMPtr<nsIStreamListener> listener = new MyListener();
00388         nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
00389 
00390         rv = NS_NewURI(getter_AddRefs(baseURI), argv[1]);
00391         RETURN_IF_FAILED(rv, "NS_NewURI");
00392 
00393         rv = NS_NewChannel(getter_AddRefs(chan), baseURI, nsnull, nsnull, callbacks);
00394         RETURN_IF_FAILED(rv, "NS_OpenURI");
00395         gKeepRunning++;
00396 
00397         //TIMER STARTED-----------------------
00398         printf("Starting clock ... \n");
00399         start = PR_Now();
00400         rv = chan->AsyncOpen(listener, nsnull);
00401         RETURN_IF_FAILED(rv, "AsyncOpen");
00402 
00403         while (gKeepRunning) {
00404             gEventQ->ProcessPendingEvents();
00405         }
00406 
00407         finish = PR_Now();
00408         PRUint32 totalTime32;
00409         PRUint64 totalTime64;
00410         LL_SUB(totalTime64, finish, start);
00411         LL_L2UI(totalTime32, totalTime64);
00412 
00413         printf("\n\n--------------------\nAll done:\nnum found:%d\nnum start:%d\n", numFound, numStart);
00414 
00415         printf("\n\n>>PageLoadTime>>%u>>\n\n", totalTime32);
00416     } // this scopes the nsCOMPtrs
00417     // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
00418     rv = NS_ShutdownXPCOM(nsnull);
00419     NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
00420     return 0;
00421 }