On x86 compilers without fastcall, simulate it when invoking traces and un-simulate...
[wine-gecko.git] / netwerk / test / TestPageLoad.cpp
blobeb89a5cde4e048805cad23a5f32e70989e498573
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
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.
36 * ***** END LICENSE BLOCK ***** */
38 #include "TestCommon.h"
39 #include "nsNetUtil.h"
40 #include "nsIServiceManager.h"
41 #include "nsIInterfaceRequestor.h"
42 #include "nsIInterfaceRequestorUtils.h"
43 #include "nsIProgressEventSink.h"
44 #include "nsIComponentManager.h"
45 #include "prprf.h"
46 #include "nsXPCOM.h"
47 #include "nsISupportsPrimitives.h"
48 #include "prlong.h"
49 #include "plstr.h"
50 #include "nsSupportsArray.h"
51 #include "nsIComponentRegistrar.h"
53 namespace TestPageLoad {
55 int getStrLine(const char *src, char *str, int ind, int max);
56 nsresult auxLoad(char *uriBuf);
57 //----------------------------------------------------------------------
60 #define RETURN_IF_FAILED(rv, step) \
61 PR_BEGIN_MACRO \
62 if (NS_FAILED(rv)) { \
63 printf(">>> %s failed: rv=%x\n", step, rv); \
64 return rv;\
65 } \
66 PR_END_MACRO
68 static nsCString globalStream;
69 //static char urlBuf[256];
70 static nsCOMPtr<nsIURI> baseURI;
71 static nsCOMPtr<nsISupportsArray> uriList;
73 //Temp, should remove:
74 static int numStart=0;
75 static int numFound=0;
77 static PRInt32 gKeepRunning = 0;
80 //--------writer fun----------------------
82 static NS_METHOD streamParse (nsIInputStream* in,
83 void* closure,
84 const char* fromRawSegment,
85 PRUint32 toOffset,
86 PRUint32 count,
87 PRUint32 *writeCount) {
89 char parseBuf[2048], loc[2048], lineBuf[2048];
90 char *loc_t, *loc_t2;
91 int i = 0;
92 char *tmp;
94 if(!globalStream.IsEmpty()) {
95 globalStream.Append(fromRawSegment);
96 tmp = ToNewCString(globalStream);
97 //printf("\n>>NOW:\n^^^^^\n%s\n^^^^^^^^^^^^^^", tmp);
98 } else {
99 tmp = (char *)fromRawSegment;
102 while(i < (int)count) {
103 i = getStrLine(tmp, lineBuf, i, count);
104 if(i < 0) {
105 *writeCount = count;
106 return NS_OK;
108 parseBuf[0]='\0';
109 if((loc_t=PL_strcasestr(lineBuf, "img"))!= NULL
110 || (loc_t=PL_strcasestr(lineBuf, "script"))!=NULL) {
111 loc_t2=PL_strcasestr(loc_t, "src");
112 if(loc_t2!=NULL) {
113 loc_t2+=3;
114 strcpy(loc, loc_t2);
115 sscanf(loc, "=\"%[^\"]", parseBuf);
116 if(parseBuf[0]=='\0')
117 sscanf(loc, "=%s", parseBuf);
118 if(parseBuf[0]!='\0'){
119 numFound++;
120 auxLoad(parseBuf);
125 /***NEED BETTER CHECK FOR STYLESHEETS
126 if((loc_t=PL_strcasestr(lineBuf, "link"))!= NULL) {
127 loc_t2=PL_strcasestr(loc_t, "href");
128 if(loc_t2!=NULL) {
129 loc_t2+=4;
130 strcpy(loc, loc_t2);
131 //printf("%s\n", loc);
132 sscanf(loc, "=\"%[^\"]", parseBuf);
133 if(parseBuf[0]!='\0'){
134 //printf("%s\n", parseBuf);
135 numFound++;
136 auxLoad(parseBuf);
141 if((loc_t=PL_strcasestr(lineBuf, "background"))!=NULL) {
142 loc_t+=10;
143 strcpy(loc, loc_t);
144 sscanf(loc, "=\"%[^\"]", parseBuf);
145 if(parseBuf[0]!='\0') {
146 numFound++;
147 auxLoad(parseBuf);
150 i++;
153 *writeCount = count;
154 return NS_OK;
157 //-----------------------------------------------------------------------------
158 // nsIStreamListener implementation
159 //-----------------------------------------------------------------------------
161 class MyListener : public nsIStreamListener
163 public:
164 NS_DECL_ISUPPORTS
165 NS_DECL_NSIREQUESTOBSERVER
166 NS_DECL_NSISTREAMLISTENER
168 MyListener() { }
169 virtual ~MyListener() {}
172 NS_IMPL_ISUPPORTS2(MyListener,
173 nsIRequestObserver,
174 nsIStreamListener)
176 NS_IMETHODIMP
177 MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt)
179 //printf(">>> OnStartRequest\n");
180 numStart++;
181 return NS_OK;
184 NS_IMETHODIMP
185 MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status)
187 //printf(">>> OnStopRequest status=%x\n", status);
188 if (--gKeepRunning == 0)
189 QuitPumpingEvents();
190 return NS_OK;
193 NS_IMETHODIMP
194 MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt,
195 nsIInputStream *stream,
196 PRUint32 offset, PRUint32 count)
198 //printf(">>> OnDataAvailable [count=%u]\n", count);
199 nsresult rv = NS_ERROR_FAILURE;
200 PRUint32 bytesRead=0;
201 char buf[1024];
203 if(ctxt == nsnull) {
204 bytesRead=0;
205 rv = stream->ReadSegments(streamParse, &offset, count, &bytesRead);
206 } else {
207 while (count) {
208 PRUint32 amount = PR_MIN(count, sizeof(buf));
209 rv = stream->Read(buf, amount, &bytesRead);
210 count -= bytesRead;
214 if (NS_FAILED(rv)) {
215 printf(">>> stream->Read failed with rv=%x\n", rv);
216 return rv;
219 return NS_OK;
222 //-----------------------------------------------------------------------------
223 // NotificationCallbacks implementation
224 //-----------------------------------------------------------------------------
226 class MyNotifications : public nsIInterfaceRequestor
227 , public nsIProgressEventSink
229 public:
230 NS_DECL_ISUPPORTS
231 NS_DECL_NSIINTERFACEREQUESTOR
232 NS_DECL_NSIPROGRESSEVENTSINK
234 MyNotifications() { }
235 virtual ~MyNotifications() {}
238 NS_IMPL_THREADSAFE_ISUPPORTS2(MyNotifications,
239 nsIInterfaceRequestor,
240 nsIProgressEventSink)
242 NS_IMETHODIMP
243 MyNotifications::GetInterface(const nsIID &iid, void **result)
245 return QueryInterface(iid, result);
248 NS_IMETHODIMP
249 MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx,
250 nsresult status, const PRUnichar *statusText)
252 //printf("status: %x\n", status);
253 return NS_OK;
256 NS_IMETHODIMP
257 MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx,
258 PRUint64 progress, PRUint64 progressMax)
260 // char buf[100];
261 // PR_snprintf(buf, sizeof(buf), "%llu/%llu\n", progress, progressMax);
262 // printf("%s", buf);
263 return NS_OK;
266 //-----------------------------------------------------------------------------
267 // main, etc..
268 //-----------------------------------------------------------------------------
270 //---------getStrLine Helper function---------------
271 //Finds a newline in src starting at ind. Puts the
272 //line in str (must be big enough). Returns the index
273 //of the newline, or -1 if at end of string. If reaches
274 //end of string ('\0'), then will copy contents to
275 //globalStream.
276 int getStrLine(const char *src, char *str, int ind, int max) {
277 char c = src[ind];
278 int i=0;
279 globalStream.Assign('\0');
280 while(c!='\n' && c!='\0' && i<max) {
281 str[i] = src[ind];
282 i++; ind++;
283 c = src[ind];
285 str[i]='\0';
286 if(i==max || c=='\0') {
287 globalStream.Assign(str);
288 //printf("\nCarryover (%d|%d):\n------------\n%s\n-------\n",i,max,str);
289 return -1;
291 return ind;
294 //----------AUX LOAD-----------
295 nsresult auxLoad(char *uriBuf)
297 nsresult rv;
299 nsCOMPtr<nsISupportsPRBool> myBool = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
301 nsCOMPtr<nsIURI> uri;
302 nsCOMPtr<nsIChannel> chan;
303 nsCOMPtr<nsIStreamListener> listener = new MyListener();
304 nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
306 printf("Getting: %s", uriBuf);
308 //If relative link
309 if(strncmp(uriBuf, "http:", 5)) {
310 //Relative link
311 rv = NS_NewURI(getter_AddRefs(uri), uriBuf, baseURI);
312 if (NS_FAILED(rv)) return(rv);
313 } else {
314 //Absolute link, no base needed
315 rv = NS_NewURI(getter_AddRefs(uri), uriBuf);
316 if (NS_FAILED(rv)) return(rv);
319 //Compare to see if exists
320 PRUint32 num;
321 uriList->Count(&num);
322 PRBool equal;
323 nsCOMPtr<nsIURI> uriTmp;
324 for(PRUint32 i = 0; i < num; i++) {
325 uriList->GetElementAt(i, getter_AddRefs(uriTmp));
326 uri->Equals(uriTmp, &equal);
327 if(equal) {
328 printf("(duplicate, canceling) %s\n",uriBuf);
329 return NS_OK;
332 printf("\n");
333 uriList->AppendElement(uri);
334 rv = NS_NewChannel(getter_AddRefs(chan), uri, nsnull, nsnull, callbacks);
335 RETURN_IF_FAILED(rv, "NS_NewChannel");
337 gKeepRunning++;
338 rv = chan->AsyncOpen(listener, myBool);
339 RETURN_IF_FAILED(rv, "AsyncOpen");
341 return NS_OK;
345 //---------Buffer writer fun---------
347 } // namespace
349 using namespace TestPageLoad;
351 //---------MAIN-----------
353 int main(int argc, char **argv)
355 if (test_common_init(&argc, &argv) != 0)
356 return -1;
358 nsresult rv;
360 if (argc == 1) {
361 printf("usage: TestPageLoad <url>\n");
362 return -1;
365 nsCOMPtr<nsIServiceManager> servMan;
366 NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
367 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
368 NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
369 if (registrar)
370 registrar->AutoRegister(nsnull);
372 PRTime start, finish;
374 uriList = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
375 RETURN_IF_FAILED(rv, "do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID)");
377 printf("Loading necko ... \n");
378 nsCOMPtr<nsIChannel> chan;
379 nsCOMPtr<nsIStreamListener> listener = new MyListener();
380 nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
382 rv = NS_NewURI(getter_AddRefs(baseURI), argv[1]);
383 RETURN_IF_FAILED(rv, "NS_NewURI");
385 rv = NS_NewChannel(getter_AddRefs(chan), baseURI, nsnull, nsnull, callbacks);
386 RETURN_IF_FAILED(rv, "NS_OpenURI");
387 gKeepRunning++;
389 //TIMER STARTED-----------------------
390 printf("Starting clock ... \n");
391 start = PR_Now();
392 rv = chan->AsyncOpen(listener, nsnull);
393 RETURN_IF_FAILED(rv, "AsyncOpen");
395 PumpEvents();
397 finish = PR_Now();
398 PRUint32 totalTime32;
399 PRUint64 totalTime64;
400 LL_SUB(totalTime64, finish, start);
401 LL_L2UI(totalTime32, totalTime64);
403 printf("\n\n--------------------\nAll done:\nnum found:%d\nnum start:%d\n", numFound, numStart);
405 printf("\n\n>>PageLoadTime>>%u>>\n\n", totalTime32);
406 } // this scopes the nsCOMPtrs
407 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
408 rv = NS_ShutdownXPCOM(nsnull);
409 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
410 return 0;