Add copy of .ttf font with .eot extension for testing
[wine-gecko.git] / xpcom / tests / TestPipes.cpp
blobd6a9edecf8f48336b4769f2d36fd6ba1f9e7bc65
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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.org 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):
23 * Pierre Phaneuf <pp@ludusdesign.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "TestHarness.h"
41 #include "nsIThread.h"
42 #include "nsIRunnable.h"
43 #include "nsThreadUtils.h"
44 #include "prprf.h"
45 #include "prinrval.h"
46 #include "nsCRT.h"
47 #include "nsIPipe.h" // new implementation
48 #include "nsAutoLock.h"
51 /** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
52 nsresult TP_NewPipe2(nsIAsyncInputStream** input,
53 nsIAsyncOutputStream** output,
54 PRBool nonBlockingInput,
55 PRBool nonBlockingOutput,
56 PRUint32 segmentSize,
57 PRUint32 segmentCount,
58 nsIMemory* segmentAlloc)
60 nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");
61 if (!pipe)
62 return NS_ERROR_OUT_OF_MEMORY;
64 nsresult rv = pipe->Init(nonBlockingInput,
65 nonBlockingOutput,
66 segmentSize,
67 segmentCount,
68 segmentAlloc);
70 if (NS_FAILED(rv))
71 return rv;
73 pipe->GetInputStream(input);
74 pipe->GetOutputStream(output);
75 return NS_OK;
78 /** NS_NewPipe reimplemented, because it's not exported by XPCOM */
79 #define TP_DEFAULT_SEGMENT_SIZE 4096
80 nsresult TP_NewPipe(nsIInputStream **pipeIn,
81 nsIOutputStream **pipeOut,
82 PRUint32 segmentSize = 0,
83 PRUint32 maxSize = 0,
84 PRBool nonBlockingInput = PR_FALSE,
85 PRBool nonBlockingOutput = PR_FALSE,
86 nsIMemory *segmentAlloc = nsnull);
87 nsresult TP_NewPipe(nsIInputStream **pipeIn,
88 nsIOutputStream **pipeOut,
89 PRUint32 segmentSize,
90 PRUint32 maxSize,
91 PRBool nonBlockingInput,
92 PRBool nonBlockingOutput,
93 nsIMemory *segmentAlloc)
95 if (segmentSize == 0)
96 segmentSize = TP_DEFAULT_SEGMENT_SIZE;
98 // Handle maxSize of PR_UINT32_MAX as a special case
99 PRUint32 segmentCount;
100 if (maxSize == PR_UINT32_MAX)
101 segmentCount = PR_UINT32_MAX;
102 else
103 segmentCount = maxSize / segmentSize;
105 nsIAsyncInputStream *in;
106 nsIAsyncOutputStream *out;
107 nsresult rv = TP_NewPipe2(&in, &out, nonBlockingInput, nonBlockingOutput,
108 segmentSize, segmentCount, segmentAlloc);
109 if (NS_FAILED(rv)) return rv;
111 *pipeIn = in;
112 *pipeOut = out;
113 return NS_OK;
117 #define KEY 0xa7
118 #define ITERATIONS 33333
119 char kTestPattern[] = "My hovercraft is full of eels.\n";
121 PRBool gTrace = PR_FALSE;
123 static nsresult
124 WriteAll(nsIOutputStream *os, const char *buf, PRUint32 bufLen, PRUint32 *lenWritten)
126 const char *p = buf;
127 *lenWritten = 0;
128 while (bufLen) {
129 PRUint32 n;
130 nsresult rv = os->Write(p, bufLen, &n);
131 if (NS_FAILED(rv)) return rv;
132 p += n;
133 bufLen -= n;
134 *lenWritten += n;
136 return NS_OK;
139 class nsReceiver : public nsIRunnable {
140 public:
141 NS_DECL_ISUPPORTS
143 NS_IMETHOD Run() {
144 nsresult rv;
145 char buf[101];
146 PRUint32 count;
147 PRIntervalTime start = PR_IntervalNow();
148 while (PR_TRUE) {
149 rv = mIn->Read(buf, 100, &count);
150 if (NS_FAILED(rv)) {
151 printf("read failed\n");
152 break;
154 if (count == 0) {
155 // printf("EOF count = %d\n", mCount);
156 break;
159 if (gTrace) {
160 buf[count] = '\0';
161 printf("read: %s\n", buf);
163 mCount += count;
165 PRIntervalTime end = PR_IntervalNow();
166 printf("read %d bytes, time = %dms\n", mCount,
167 PR_IntervalToMilliseconds(end - start));
168 return rv;
171 nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) {
174 PRUint32 GetBytesRead() { return mCount; }
176 protected:
177 nsCOMPtr<nsIInputStream> mIn;
178 PRUint32 mCount;
181 NS_IMPL_THREADSAFE_ISUPPORTS1(nsReceiver, nsIRunnable)
183 nsresult
184 TestPipe(nsIInputStream* in, nsIOutputStream* out)
186 nsCOMPtr<nsReceiver> receiver = new nsReceiver(in);
187 if (!receiver)
188 return NS_ERROR_OUT_OF_MEMORY;
190 nsresult rv;
192 nsCOMPtr<nsIThread> thread;
193 rv = NS_NewThread(getter_AddRefs(thread), receiver);
194 if (NS_FAILED(rv)) return rv;
196 PRUint32 total = 0;
197 PRIntervalTime start = PR_IntervalNow();
198 for (PRUint32 i = 0; i < ITERATIONS; i++) {
199 PRUint32 writeCount;
200 char *buf = PR_smprintf("%d %s", i, kTestPattern);
201 PRUint32 len = strlen(buf);
202 rv = WriteAll(out, buf, len, &writeCount);
203 if (gTrace) {
204 printf("wrote: ");
205 for (PRUint32 j = 0; j < writeCount; j++) {
206 putc(buf[j], stdout);
208 printf("\n");
210 PR_smprintf_free(buf);
211 if (NS_FAILED(rv)) return rv;
212 total += writeCount;
214 rv = out->Close();
215 if (NS_FAILED(rv)) return rv;
217 PRIntervalTime end = PR_IntervalNow();
219 thread->Shutdown();
221 printf("wrote %d bytes, time = %dms\n", total,
222 PR_IntervalToMilliseconds(end - start));
223 NS_ASSERTION(receiver->GetBytesRead() == total, "didn't read everything");
225 return NS_OK;
228 ////////////////////////////////////////////////////////////////////////////////
230 class nsShortReader : public nsIRunnable {
231 public:
232 NS_DECL_ISUPPORTS
234 NS_IMETHOD Run() {
235 nsresult rv;
236 char buf[101];
237 PRUint32 count;
238 PRUint32 total = 0;
239 while (PR_TRUE) {
240 //if (gTrace)
241 // printf("calling Read\n");
242 rv = mIn->Read(buf, 100, &count);
243 if (NS_FAILED(rv)) {
244 printf("read failed\n");
245 break;
247 if (count == 0) {
248 break;
251 if (gTrace) {
252 // For next |printf()| call and possible others elsewhere.
253 buf[count] = '\0';
255 printf("read %d bytes: %s\n", count, buf);
258 Received(count);
259 total += count;
261 printf("read %d bytes\n", total);
262 return rv;
265 nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) {
268 void Received(PRUint32 count) {
269 nsAutoCMonitor mon(this);
270 mReceived += count;
271 mon.Notify();
274 PRUint32 WaitForReceipt(const PRUint32 aWriteCount) {
275 nsAutoCMonitor mon(this);
276 PRUint32 result = mReceived;
278 while (result < aWriteCount) {
279 mon.Wait();
281 NS_ASSERTION(mReceived > result, "failed to receive");
282 result = mReceived;
285 mReceived = 0;
286 return result;
289 protected:
290 nsCOMPtr<nsIInputStream> mIn;
291 PRUint32 mReceived;
294 NS_IMPL_THREADSAFE_ISUPPORTS1(nsShortReader, nsIRunnable)
296 nsresult
297 TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
299 nsCOMPtr<nsShortReader> receiver = new nsShortReader(in);
300 if (!receiver)
301 return NS_ERROR_OUT_OF_MEMORY;
303 nsresult rv;
305 nsCOMPtr<nsIThread> thread;
306 rv = NS_NewThread(getter_AddRefs(thread), receiver);
307 if (NS_FAILED(rv)) return rv;
309 PRUint32 total = 0;
310 for (PRUint32 i = 0; i < ITERATIONS; i++) {
311 PRUint32 writeCount;
312 char* buf = PR_smprintf("%d %s", i, kTestPattern);
313 PRUint32 len = strlen(buf);
314 len = len * rand() / RAND_MAX;
315 len = PR_MAX(1, len);
316 rv = WriteAll(out, buf, len, &writeCount);
317 if (NS_FAILED(rv)) return rv;
318 NS_ASSERTION(writeCount == len, "didn't write enough");
319 total += writeCount;
321 if (gTrace)
322 printf("wrote %d bytes: %s\n", writeCount, buf);
323 PR_smprintf_free(buf);
324 //printf("calling Flush\n");
325 out->Flush();
326 //printf("calling WaitForReceipt\n");
327 const PRUint32 received = receiver->WaitForReceipt(writeCount);
328 NS_ASSERTION(received == writeCount, "received wrong amount");
330 rv = out->Close();
331 if (NS_FAILED(rv)) return rv;
333 thread->Shutdown();
335 printf("wrote %d bytes\n", total);
337 return NS_OK;
340 ////////////////////////////////////////////////////////////////////////////////
342 class nsPump : public nsIRunnable
344 public:
345 NS_DECL_ISUPPORTS
347 NS_IMETHOD Run() {
348 nsresult rv;
349 PRUint32 count;
350 while (PR_TRUE) {
351 rv = mOut->WriteFrom(mIn, ~0U, &count);
352 if (NS_FAILED(rv)) {
353 printf("Write failed\n");
354 break;
356 if (count == 0) {
357 printf("EOF count = %d\n", mCount);
358 break;
361 if (gTrace) {
362 printf("Wrote: %d\n", count);
364 mCount += count;
366 mOut->Close();
367 return rv;
370 nsPump(nsIInputStream* in,
371 nsIOutputStream* out)
372 : mIn(in), mOut(out), mCount(0) {
375 protected:
376 nsCOMPtr<nsIInputStream> mIn;
377 nsCOMPtr<nsIOutputStream> mOut;
378 PRUint32 mCount;
381 NS_IMPL_THREADSAFE_ISUPPORTS1(nsPump,
382 nsIRunnable)
384 nsresult
385 TestChainedPipes()
387 nsresult rv;
388 printf("TestChainedPipes\n");
390 nsCOMPtr<nsIInputStream> in1;
391 nsCOMPtr<nsIOutputStream> out1;
392 rv = TP_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999);
393 if (NS_FAILED(rv)) return rv;
395 nsCOMPtr<nsIInputStream> in2;
396 nsCOMPtr<nsIOutputStream> out2;
397 rv = TP_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401);
398 if (NS_FAILED(rv)) return rv;
400 nsCOMPtr<nsPump> pump = new nsPump(in1, out2);
401 if (pump == nsnull) return NS_ERROR_OUT_OF_MEMORY;
403 nsCOMPtr<nsIThread> thread;
404 rv = NS_NewThread(getter_AddRefs(thread), pump);
405 if (NS_FAILED(rv)) return rv;
407 nsCOMPtr<nsReceiver> receiver = new nsReceiver(in2);
408 if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY;
410 nsCOMPtr<nsIThread> receiverThread;
411 rv = NS_NewThread(getter_AddRefs(receiverThread), receiver);
412 if (NS_FAILED(rv)) return rv;
414 PRUint32 total = 0;
415 for (PRUint32 i = 0; i < ITERATIONS; i++) {
416 PRUint32 writeCount;
417 char* buf = PR_smprintf("%d %s", i, kTestPattern);
418 PRUint32 len = strlen(buf);
419 len = len * rand() / RAND_MAX;
420 len = PR_MAX(1, len);
421 rv = WriteAll(out1, buf, len, &writeCount);
422 if (NS_FAILED(rv)) return rv;
423 NS_ASSERTION(writeCount == len, "didn't write enough");
424 total += writeCount;
426 if (gTrace)
427 printf("wrote %d bytes: %s\n", writeCount, buf);
429 PR_smprintf_free(buf);
431 printf("wrote total of %d bytes\n", total);
432 rv = out1->Close();
433 if (NS_FAILED(rv)) return rv;
435 thread->Shutdown();
436 receiverThread->Shutdown();
438 return NS_OK;
441 ////////////////////////////////////////////////////////////////////////////////
443 void
444 RunTests(PRUint32 segSize, PRUint32 segCount)
446 nsresult rv;
447 nsCOMPtr<nsIInputStream> in;
448 nsCOMPtr<nsIOutputStream> out;
449 PRUint32 bufSize = segSize * segCount;
450 printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize);
452 printf("Testing long writes...\n");
453 rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
454 NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed");
455 rv = TestPipe(in, out);
456 NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
458 printf("Testing short writes...\n");
459 rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
460 NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed");
461 rv = TestShortWrites(in, out);
462 NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
465 ////////////////////////////////////////////////////////////////////////////////
467 #if !defined(MOZ_ENABLE_LIBXUL) && defined(DEBUG)
468 extern NS_COM void
469 TestSegmentedBuffer();
470 #endif
473 main(int argc, char* argv[])
475 nsresult rv;
477 nsCOMPtr<nsIServiceManager> servMgr;
478 rv = NS_InitXPCOM2(getter_AddRefs(servMgr), NULL, NULL);
479 if (NS_FAILED(rv)) return rv;
481 if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0)
482 gTrace = PR_TRUE;
484 #if !defined(MOZ_ENABLE_LIBXUL) && defined(DEBUG)
485 printf("Testing segmented buffer...\n");
486 TestSegmentedBuffer();
487 #endif
489 rv = TestChainedPipes();
490 NS_ASSERTION(NS_SUCCEEDED(rv), "TestChainedPipes failed");
491 RunTests(16, 1);
492 RunTests(4096, 16);
494 servMgr = 0;
495 rv = NS_ShutdownXPCOM( NULL );
496 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
498 return 0;
501 ////////////////////////////////////////////////////////////////////////////////