Bug 1146304 - Touch slider bar or tap forward button, the video got stuck 1s then...
[gecko.git] / netwerk / test / TestPageLoad.cpp
blob4a72ff38745aef8d8adb30662aade1bb98c9d0e0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "TestCommon.h"
7 #include "nsNetUtil.h"
8 #include "nsIServiceManager.h"
9 #include "nsIInterfaceRequestor.h"
10 #include "nsIInterfaceRequestorUtils.h"
11 #include "nsIProgressEventSink.h"
12 #include "nsIComponentManager.h"
13 #include "prprf.h"
14 #include "nsXPCOM.h"
15 #include "nsISupportsPrimitives.h"
16 #include "plstr.h"
17 #include "nsCOMArray.h"
18 #include "nsIComponentRegistrar.h"
19 #include <algorithm>
21 namespace TestPageLoad {
23 int getStrLine(const char *src, char *str, int ind, int max);
24 nsresult auxLoad(char *uriBuf);
25 //----------------------------------------------------------------------
28 #define RETURN_IF_FAILED(rv, ret, step) \
29 PR_BEGIN_MACRO \
30 if (NS_FAILED(rv)) { \
31 printf(">>> %s failed: rv=%x\n", step, static_cast<uint32_t>(rv)); \
32 return ret;\
33 } \
34 PR_END_MACRO
36 static nsCString globalStream;
37 //static char urlBuf[256];
38 static nsCOMPtr<nsIURI> baseURI;
39 static nsCOMArray<nsIURI> uriList;
41 //Temp, should remove:
42 static int numStart=0;
43 static int numFound=0;
45 static int32_t gKeepRunning = 0;
48 //--------writer fun----------------------
50 static NS_METHOD streamParse (nsIInputStream* in,
51 void* closure,
52 const char* fromRawSegment,
53 uint32_t toOffset,
54 uint32_t count,
55 uint32_t *writeCount) {
57 char parseBuf[2048], loc[2048], lineBuf[2048];
58 char *loc_t, *loc_t2;
59 int i = 0;
60 const char *tmp;
62 if(!globalStream.IsEmpty()) {
63 globalStream.Append(fromRawSegment);
64 tmp = globalStream.get();
65 //printf("\n>>NOW:\n^^^^^\n%s\n^^^^^^^^^^^^^^", tmp);
66 } else {
67 tmp = fromRawSegment;
70 while(i < (int)count) {
71 i = getStrLine(tmp, lineBuf, i, count);
72 if(i < 0) {
73 *writeCount = count;
74 return NS_OK;
76 parseBuf[0]='\0';
77 if((loc_t=PL_strcasestr(lineBuf, "img"))!= nullptr
78 || (loc_t=PL_strcasestr(lineBuf, "script"))!=nullptr) {
79 loc_t2=PL_strcasestr(loc_t, "src");
80 if(loc_t2!=nullptr) {
81 loc_t2+=3;
82 strcpy(loc, loc_t2);
83 sscanf(loc, "=\"%[^\"]", parseBuf);
84 if(parseBuf[0]=='\0')
85 sscanf(loc, "=%s", parseBuf);
86 if(parseBuf[0]!='\0'){
87 numFound++;
88 auxLoad(parseBuf);
93 /***NEED BETTER CHECK FOR STYLESHEETS
94 if((loc_t=PL_strcasestr(lineBuf, "link"))!= nullptr) {
95 loc_t2=PL_strcasestr(loc_t, "href");
96 if(loc_t2!=nullptr) {
97 loc_t2+=4;
98 strcpy(loc, loc_t2);
99 //printf("%s\n", loc);
100 sscanf(loc, "=\"%[^\"]", parseBuf);
101 if(parseBuf[0]!='\0'){
102 //printf("%s\n", parseBuf);
103 numFound++;
104 auxLoad(parseBuf);
109 if((loc_t=PL_strcasestr(lineBuf, "background"))!=nullptr) {
110 loc_t+=10;
111 strcpy(loc, loc_t);
112 sscanf(loc, "=\"%[^\"]", parseBuf);
113 if(parseBuf[0]!='\0') {
114 numFound++;
115 auxLoad(parseBuf);
118 i++;
121 *writeCount = count;
122 return NS_OK;
125 //-----------------------------------------------------------------------------
126 // nsIStreamListener implementation
127 //-----------------------------------------------------------------------------
129 class MyListener : public nsIStreamListener
131 virtual ~MyListener() {}
133 public:
134 NS_DECL_ISUPPORTS
135 NS_DECL_NSIREQUESTOBSERVER
136 NS_DECL_NSISTREAMLISTENER
138 MyListener() { }
141 NS_IMPL_ISUPPORTS(MyListener,
142 nsIRequestObserver,
143 nsIStreamListener)
145 NS_IMETHODIMP
146 MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt)
148 //printf(">>> OnStartRequest\n");
149 numStart++;
150 return NS_OK;
153 NS_IMETHODIMP
154 MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status)
156 //printf(">>> OnStopRequest status=%x\n", status);
157 if (--gKeepRunning == 0)
158 QuitPumpingEvents();
159 return NS_OK;
162 NS_IMETHODIMP
163 MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt,
164 nsIInputStream *stream,
165 uint64_t offset, uint32_t count)
167 //printf(">>> OnDataAvailable [count=%u]\n", count);
168 nsresult rv = NS_ERROR_FAILURE;
169 uint32_t bytesRead=0;
170 char buf[1024];
172 if(ctxt == nullptr) {
173 bytesRead=0;
174 rv = stream->ReadSegments(streamParse, nullptr, count, &bytesRead);
175 } else {
176 while (count) {
177 uint32_t amount = std::min<uint32_t>(count, sizeof(buf));
178 rv = stream->Read(buf, amount, &bytesRead);
179 count -= bytesRead;
183 if (NS_FAILED(rv)) {
184 printf(">>> stream->Read failed with rv=%x\n",
185 static_cast<uint32_t>(rv));
186 return rv;
189 return NS_OK;
192 //-----------------------------------------------------------------------------
193 // NotificationCallbacks implementation
194 //-----------------------------------------------------------------------------
196 class MyNotifications : public nsIInterfaceRequestor
197 , public nsIProgressEventSink
199 virtual ~MyNotifications() {}
201 public:
202 NS_DECL_THREADSAFE_ISUPPORTS
203 NS_DECL_NSIINTERFACEREQUESTOR
204 NS_DECL_NSIPROGRESSEVENTSINK
206 MyNotifications() { }
209 NS_IMPL_ISUPPORTS(MyNotifications,
210 nsIInterfaceRequestor,
211 nsIProgressEventSink)
213 NS_IMETHODIMP
214 MyNotifications::GetInterface(const nsIID &iid, void **result)
216 return QueryInterface(iid, result);
219 NS_IMETHODIMP
220 MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx,
221 nsresult status, const char16_t *statusText)
223 //printf("status: %x\n", status);
224 return NS_OK;
227 NS_IMETHODIMP
228 MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx,
229 uint64_t progress, uint64_t progressMax)
231 // char buf[100];
232 // PR_snprintf(buf, sizeof(buf), "%llu/%llu\n", progress, progressMax);
233 // printf("%s", buf);
234 return NS_OK;
237 //-----------------------------------------------------------------------------
238 // main, etc..
239 //-----------------------------------------------------------------------------
241 //---------getStrLine Helper function---------------
242 //Finds a newline in src starting at ind. Puts the
243 //line in str (must be big enough). Returns the index
244 //of the newline, or -1 if at end of string. If reaches
245 //end of string ('\0'), then will copy contents to
246 //globalStream.
247 int getStrLine(const char *src, char *str, int ind, int max) {
248 char c = src[ind];
249 int i=0;
250 globalStream.Assign('\0');
251 while(c!='\n' && c!='\0' && i<max) {
252 str[i] = src[ind];
253 i++; ind++;
254 c = src[ind];
256 str[i]='\0';
257 if(i==max || c=='\0') {
258 globalStream.Assign(str);
259 //printf("\nCarryover (%d|%d):\n------------\n%s\n-------\n",i,max,str);
260 return -1;
262 return ind;
265 //----------AUX LOAD-----------
266 nsresult auxLoad(char *uriBuf)
268 nsresult rv;
270 nsCOMPtr<nsISupportsPRBool> myBool = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
272 nsCOMPtr<nsIURI> uri;
273 nsCOMPtr<nsIChannel> chan;
274 nsCOMPtr<nsIStreamListener> listener = new MyListener();
275 nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
277 printf("Getting: %s", uriBuf);
279 //If relative link
280 if(strncmp(uriBuf, "http:", 5)) {
281 //Relative link
282 rv = NS_NewURI(getter_AddRefs(uri), uriBuf, baseURI);
283 if (NS_FAILED(rv)) return(rv);
284 } else {
285 //Absolute link, no base needed
286 rv = NS_NewURI(getter_AddRefs(uri), uriBuf);
287 if (NS_FAILED(rv)) return(rv);
290 //Compare to see if exists
291 bool equal;
292 for(int32_t i = 0; i < uriList.Count(); i++) {
293 uri->Equals(uriList[i], &equal);
294 if(equal) {
295 printf("(duplicate, canceling) %s\n",uriBuf);
296 return NS_OK;
299 printf("\n");
300 uriList.AppendObject(uri);
301 rv = NS_NewChannel(getter_AddRefs(chan), uri, nullptr, nullptr, callbacks);
302 RETURN_IF_FAILED(rv, rv, "NS_NewChannel");
304 gKeepRunning++;
305 rv = chan->AsyncOpen(listener, myBool);
306 RETURN_IF_FAILED(rv, rv, "AsyncOpen");
308 return NS_OK;
312 //---------Buffer writer fun---------
314 } // namespace
316 using namespace TestPageLoad;
318 //---------MAIN-----------
320 int main(int argc, char **argv)
322 if (test_common_init(&argc, &argv) != 0)
323 return -1;
325 nsresult rv;
327 if (argc == 1) {
328 printf("usage: TestPageLoad <url>\n");
329 return -1;
332 nsCOMPtr<nsIServiceManager> servMan;
333 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
335 PRTime start, finish;
337 printf("Loading necko ... \n");
338 nsCOMPtr<nsIChannel> chan;
339 nsCOMPtr<nsIStreamListener> listener = new MyListener();
340 nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
342 rv = NS_NewURI(getter_AddRefs(baseURI), argv[1]);
343 RETURN_IF_FAILED(rv, -1, "NS_NewURI");
345 rv = NS_NewChannel(getter_AddRefs(chan), baseURI, nullptr, nullptr, callbacks);
346 RETURN_IF_FAILED(rv, -1, "NS_OpenURI");
347 gKeepRunning++;
349 //TIMER STARTED-----------------------
350 printf("Starting clock ... \n");
351 start = PR_Now();
352 rv = chan->AsyncOpen(listener, nullptr);
353 RETURN_IF_FAILED(rv, -1, "AsyncOpen");
355 PumpEvents();
357 finish = PR_Now();
358 uint32_t totalTime32 = uint32_t(finish - start);
360 printf("\n\n--------------------\nAll done:\nnum found:%d\nnum start:%d\n", numFound, numStart);
362 printf("\n\n>>PageLoadTime>>%u>>\n\n", totalTime32);
363 } // this scopes the nsCOMPtrs
364 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
365 rv = NS_ShutdownXPCOM(nullptr);
366 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
367 return 0;