netwerk/test/TestFileInput2.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsIServiceManager.h"
michael@0 7 #include "nsIComponentRegistrar.h"
michael@0 8 #include "nsIInputStream.h"
michael@0 9 #include "nsIOutputStream.h"
michael@0 10 #include "nsIRunnable.h"
michael@0 11 #include "nsIThread.h"
michael@0 12 #include "nsCOMArray.h"
michael@0 13 #include "nsISimpleEnumerator.h"
michael@0 14 #include "prinrval.h"
michael@0 15 #include "nsIFileStreams.h"
michael@0 16 #include "nsIFileChannel.h"
michael@0 17 #include "nsIFile.h"
michael@0 18 #include "nsNetUtil.h"
michael@0 19 #include <stdio.h>
michael@0 20
michael@0 21 ////////////////////////////////////////////////////////////////////////////////
michael@0 22
michael@0 23 #include <math.h>
michael@0 24 #include "prprf.h"
michael@0 25 #include "nsAutoLock.h"
michael@0 26
michael@0 27 class nsTimeSampler {
michael@0 28 public:
michael@0 29 nsTimeSampler();
michael@0 30 void Reset();
michael@0 31 void StartTime();
michael@0 32 void EndTime();
michael@0 33 void AddTime(PRIntervalTime time);
michael@0 34 PRIntervalTime LastInterval() { return mLastInterval; }
michael@0 35 char* PrintStats();
michael@0 36 protected:
michael@0 37 PRIntervalTime mStartTime;
michael@0 38 double mSquares;
michael@0 39 double mTotalTime;
michael@0 40 uint32_t mCount;
michael@0 41 PRIntervalTime mLastInterval;
michael@0 42 };
michael@0 43
michael@0 44 nsTimeSampler::nsTimeSampler()
michael@0 45 {
michael@0 46 Reset();
michael@0 47 }
michael@0 48
michael@0 49 void
michael@0 50 nsTimeSampler::Reset()
michael@0 51 {
michael@0 52 mStartTime = 0;
michael@0 53 mSquares = 0;
michael@0 54 mTotalTime = 0;
michael@0 55 mCount = 0;
michael@0 56 mLastInterval = 0;
michael@0 57 }
michael@0 58
michael@0 59 void
michael@0 60 nsTimeSampler::StartTime()
michael@0 61 {
michael@0 62 mStartTime = PR_IntervalNow();
michael@0 63 }
michael@0 64
michael@0 65 void
michael@0 66 nsTimeSampler::EndTime()
michael@0 67 {
michael@0 68 NS_ASSERTION(mStartTime != 0, "Forgot to call StartTime");
michael@0 69 PRIntervalTime endTime = PR_IntervalNow();
michael@0 70 mLastInterval = endTime - mStartTime;
michael@0 71 AddTime(mLastInterval);
michael@0 72 mStartTime = 0;
michael@0 73 }
michael@0 74
michael@0 75 void
michael@0 76 nsTimeSampler::AddTime(PRIntervalTime time)
michael@0 77 {
michael@0 78 nsAutoCMonitor mon(this);
michael@0 79 mTotalTime += time;
michael@0 80 mSquares += (double)time * (double)time;
michael@0 81 mCount++;
michael@0 82 }
michael@0 83
michael@0 84 char*
michael@0 85 nsTimeSampler::PrintStats()
michael@0 86 {
michael@0 87 double mean = mTotalTime / mCount;
michael@0 88 double variance = fabs(mSquares / mCount - mean * mean);
michael@0 89 double stddev = sqrt(variance);
michael@0 90 uint32_t imean = (uint32_t)mean;
michael@0 91 uint32_t istddev = (uint32_t)stddev;
michael@0 92 return PR_smprintf("%d +/- %d ms",
michael@0 93 PR_IntervalToMilliseconds(imean),
michael@0 94 PR_IntervalToMilliseconds(istddev));
michael@0 95 }
michael@0 96
michael@0 97 ////////////////////////////////////////////////////////////////////////////////
michael@0 98
michael@0 99 nsTimeSampler gTimeSampler;
michael@0 100
michael@0 101 typedef nsresult (*CreateFun)(nsIRunnable* *result,
michael@0 102 nsIFile* inPath,
michael@0 103 nsIFile* outPath,
michael@0 104 uint32_t bufferSize);
michael@0 105
michael@0 106 ////////////////////////////////////////////////////////////////////////////////
michael@0 107
michael@0 108 nsresult
michael@0 109 Copy(nsIInputStream* inStr, nsIOutputStream* outStr,
michael@0 110 char* buf, uint32_t bufSize, uint32_t *copyCount)
michael@0 111 {
michael@0 112 nsresult rv;
michael@0 113 while (true) {
michael@0 114 uint32_t count;
michael@0 115 rv = inStr->Read(buf, bufSize, &count);
michael@0 116 if (NS_FAILED(rv)) return rv;
michael@0 117 if (count == 0) break;
michael@0 118
michael@0 119 uint32_t writeCount;
michael@0 120 rv = outStr->Write(buf, count, &writeCount);
michael@0 121 if (NS_FAILED(rv)) return rv;
michael@0 122 NS_ASSERTION(writeCount == count, "didn't write all the data");
michael@0 123 *copyCount += writeCount;
michael@0 124 }
michael@0 125 rv = outStr->Flush();
michael@0 126 return rv;
michael@0 127 }
michael@0 128
michael@0 129 ////////////////////////////////////////////////////////////////////////////////
michael@0 130
michael@0 131 class FileSpecWorker : public nsIRunnable {
michael@0 132 public:
michael@0 133
michael@0 134 NS_IMETHOD Run() {
michael@0 135 nsresult rv;
michael@0 136
michael@0 137 PRIntervalTime startTime = PR_IntervalNow();
michael@0 138 PRIntervalTime endTime;
michael@0 139 nsCOMPtr<nsIInputStream> inStr;
michael@0 140 nsCOMPtr<nsIOutputStream> outStr;
michael@0 141 uint32_t copyCount = 0;
michael@0 142
michael@0 143 // Open the input stream:
michael@0 144 nsCOMPtr<nsIInputStream> fileIn;
michael@0 145 rv = NS_NewLocalFileInputStream(getter_AddRefs(fileIn), mInPath);
michael@0 146 if (NS_FAILED(rv)) return rv;
michael@0 147
michael@0 148 rv = NS_NewBufferedInputStream(getter_AddRefs(inStr), fileIn, 65535);
michael@0 149 if (NS_FAILED(rv)) return rv;
michael@0 150
michael@0 151 // Open the output stream:
michael@0 152 nsCOMPtr<nsIOutputStream> fileOut;
michael@0 153 rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOut),
michael@0 154 mOutPath,
michael@0 155 PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
michael@0 156 0664);
michael@0 157 if (NS_FAILED(rv)) return rv;
michael@0 158
michael@0 159 rv = NS_NewBufferedOutputStream(getter_AddRefs(outStr), fileOut, 65535);
michael@0 160 if (NS_FAILED(rv)) return rv;
michael@0 161
michael@0 162 // Copy from one to the other
michael@0 163 rv = Copy(inStr, outStr, mBuffer, mBufferSize, &copyCount);
michael@0 164 if (NS_FAILED(rv)) return rv;
michael@0 165
michael@0 166 endTime = PR_IntervalNow();
michael@0 167 gTimeSampler.AddTime(endTime - startTime);
michael@0 168
michael@0 169 return rv;
michael@0 170 }
michael@0 171
michael@0 172 NS_DECL_ISUPPORTS
michael@0 173
michael@0 174 FileSpecWorker()
michael@0 175 : mInPath(nullptr), mOutPath(nullptr), mBuffer(nullptr),
michael@0 176 mBufferSize(0)
michael@0 177 {
michael@0 178 }
michael@0 179
michael@0 180 nsresult Init(nsIFile* inPath, nsIFile* outPath,
michael@0 181 uint32_t bufferSize)
michael@0 182 {
michael@0 183 mInPath = inPath;
michael@0 184 mOutPath = outPath;
michael@0 185 mBuffer = new char[bufferSize];
michael@0 186 mBufferSize = bufferSize;
michael@0 187 return (mInPath && mOutPath && mBuffer)
michael@0 188 ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 189 }
michael@0 190
michael@0 191 static nsresult Create(nsIRunnable* *result,
michael@0 192 nsIFile* inPath,
michael@0 193 nsIFile* outPath,
michael@0 194 uint32_t bufferSize)
michael@0 195 {
michael@0 196 FileSpecWorker* worker = new FileSpecWorker();
michael@0 197 if (worker == nullptr)
michael@0 198 return NS_ERROR_OUT_OF_MEMORY;
michael@0 199 NS_ADDREF(worker);
michael@0 200
michael@0 201 nsresult rv = worker->Init(inPath, outPath, bufferSize);
michael@0 202 if (NS_FAILED(rv)) {
michael@0 203 NS_RELEASE(worker);
michael@0 204 return rv;
michael@0 205 }
michael@0 206 *result = worker;
michael@0 207 return NS_OK;
michael@0 208 }
michael@0 209
michael@0 210 virtual ~FileSpecWorker() {
michael@0 211 delete[] mBuffer;
michael@0 212 }
michael@0 213
michael@0 214 protected:
michael@0 215 nsCOMPtr<nsIFile> mInPath;
michael@0 216 nsCOMPtr<nsIFile> mOutPath;
michael@0 217 char* mBuffer;
michael@0 218 uint32_t mBufferSize;
michael@0 219 };
michael@0 220
michael@0 221 NS_IMPL_ISUPPORTS(FileSpecWorker, nsIRunnable)
michael@0 222
michael@0 223 ////////////////////////////////////////////////////////////////////////////////
michael@0 224
michael@0 225 #include "nsIIOService.h"
michael@0 226 #include "nsIChannel.h"
michael@0 227
michael@0 228 class FileChannelWorker : public nsIRunnable {
michael@0 229 public:
michael@0 230
michael@0 231 NS_IMETHOD Run() {
michael@0 232 nsresult rv;
michael@0 233
michael@0 234 PRIntervalTime startTime = PR_IntervalNow();
michael@0 235 PRIntervalTime endTime;
michael@0 236 uint32_t copyCount = 0;
michael@0 237 nsCOMPtr<nsIFileChannel> inCh;
michael@0 238 nsCOMPtr<nsIFileChannel> outCh;
michael@0 239 nsCOMPtr<nsIInputStream> inStr;
michael@0 240 nsCOMPtr<nsIOutputStream> outStr;
michael@0 241
michael@0 242 rv = NS_NewLocalFileChannel(getter_AddRefs(inCh), mInPath);
michael@0 243 if (NS_FAILED(rv)) return rv;
michael@0 244
michael@0 245 rv = inCh->Open(getter_AddRefs(inStr));
michael@0 246 if (NS_FAILED(rv)) return rv;
michael@0 247
michael@0 248 //rv = NS_NewLocalFileChannel(getter_AddRefs(outCh), mOutPath);
michael@0 249 //if (NS_FAILED(rv)) return rv;
michael@0 250
michael@0 251 //rv = outCh->OpenOutputStream(0, -1, 0, getter_AddRefs(outStr));
michael@0 252 //if (NS_FAILED(rv)) return rv;
michael@0 253
michael@0 254 // Copy from one to the other
michael@0 255 rv = Copy(inStr, outStr, mBuffer, mBufferSize, &copyCount);
michael@0 256 if (NS_FAILED(rv)) return rv;
michael@0 257
michael@0 258 endTime = PR_IntervalNow();
michael@0 259 gTimeSampler.AddTime(endTime - startTime);
michael@0 260
michael@0 261 return rv;
michael@0 262 }
michael@0 263
michael@0 264 NS_DECL_ISUPPORTS
michael@0 265
michael@0 266 FileChannelWorker()
michael@0 267 : mInPath(nullptr), mOutPath(nullptr), mBuffer(nullptr),
michael@0 268 mBufferSize(0)
michael@0 269 {
michael@0 270 }
michael@0 271
michael@0 272 nsresult Init(nsIFile* inPath, nsIFile* outPath,
michael@0 273 uint32_t bufferSize)
michael@0 274 {
michael@0 275 mInPath = inPath;
michael@0 276 mOutPath = outPath;
michael@0 277 mBuffer = new char[bufferSize];
michael@0 278 mBufferSize = bufferSize;
michael@0 279 return (mInPath && mOutPath && mBuffer)
michael@0 280 ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 281 }
michael@0 282
michael@0 283 static nsresult Create(nsIRunnable* *result,
michael@0 284 nsIFile* inPath,
michael@0 285 nsIFile* outPath,
michael@0 286 uint32_t bufferSize)
michael@0 287 {
michael@0 288 FileChannelWorker* worker = new FileChannelWorker();
michael@0 289 if (worker == nullptr)
michael@0 290 return NS_ERROR_OUT_OF_MEMORY;
michael@0 291 NS_ADDREF(worker);
michael@0 292
michael@0 293 nsresult rv = worker->Init(inPath, outPath, bufferSize);
michael@0 294 if (NS_FAILED(rv)) {
michael@0 295 NS_RELEASE(worker);
michael@0 296 return rv;
michael@0 297 }
michael@0 298 *result = worker;
michael@0 299 return NS_OK;
michael@0 300 }
michael@0 301
michael@0 302 virtual ~FileChannelWorker() {
michael@0 303 delete[] mBuffer;
michael@0 304 }
michael@0 305
michael@0 306 protected:
michael@0 307 nsCOMPtr<nsIFile> mInPath;
michael@0 308 nsCOMPtr<nsIFile> mOutPath;
michael@0 309 char* mBuffer;
michael@0 310 uint32_t mBufferSize;
michael@0 311 };
michael@0 312
michael@0 313 NS_IMPL_ISUPPORTS(FileChannelWorker, nsIRunnable)
michael@0 314
michael@0 315 ////////////////////////////////////////////////////////////////////////////////
michael@0 316
michael@0 317 void
michael@0 318 Test(CreateFun create, uint32_t count,
michael@0 319 nsIFile* inDirSpec, nsIFile* outDirSpec, uint32_t bufSize)
michael@0 320 {
michael@0 321 nsresult rv;
michael@0 322 uint32_t i;
michael@0 323
michael@0 324 nsAutoCString inDir;
michael@0 325 nsAutoCString outDir;
michael@0 326 (void)inDirSpec->GetNativePath(inDir);
michael@0 327 (void)outDirSpec->GetNativePath(outDir);
michael@0 328 printf("###########\nTest: from %s to %s, bufSize = %d\n",
michael@0 329 inDir.get(), outDir.get(), bufSize);
michael@0 330 gTimeSampler.Reset();
michael@0 331 nsTimeSampler testTime;
michael@0 332 testTime.StartTime();
michael@0 333
michael@0 334 nsCOMArray<nsIThread> threads;
michael@0 335
michael@0 336 nsCOMPtr<nsISimpleEnumerator> entries;
michael@0 337 rv = inDirSpec->GetDirectoryEntries(getter_AddRefs(entries));
michael@0 338 NS_ASSERTION(NS_SUCCEEDED(rv), "GetDirectoryEntries failed");
michael@0 339
michael@0 340 i = 0;
michael@0 341 bool hasMore;
michael@0 342 while (i < count && NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore) {
michael@0 343 nsCOMPtr<nsISupports> next;
michael@0 344 rv = entries->GetNext(getter_AddRefs(next));
michael@0 345 if (NS_FAILED(rv)) goto done;
michael@0 346
michael@0 347 nsCOMPtr<nsIFile> inSpec = do_QueryInterface(next, &rv);
michael@0 348 if (NS_FAILED(rv)) goto done;
michael@0 349
michael@0 350 nsCOMPtr<nsIFile> outSpec;
michael@0 351 rv = outDirSpec->Clone(getter_AddRefs(outSpec)); // don't munge the original
michael@0 352 if (NS_FAILED(rv)) goto done;
michael@0 353
michael@0 354 nsAutoCString leafName;
michael@0 355 rv = inSpec->GetNativeLeafName(leafName);
michael@0 356 if (NS_FAILED(rv)) goto done;
michael@0 357
michael@0 358 rv = outSpec->AppendNative(leafName);
michael@0 359 if (NS_FAILED(rv)) goto done;
michael@0 360
michael@0 361 bool exists;
michael@0 362 rv = outSpec->Exists(&exists);
michael@0 363 if (NS_FAILED(rv)) goto done;
michael@0 364
michael@0 365 if (exists) {
michael@0 366 rv = outSpec->Remove(false);
michael@0 367 if (NS_FAILED(rv)) goto done;
michael@0 368 }
michael@0 369
michael@0 370 nsCOMPtr<nsIThread> thread;
michael@0 371 nsCOMPtr<nsIRunnable> worker;
michael@0 372 rv = create(getter_AddRefs(worker),
michael@0 373 inSpec,
michael@0 374 outSpec,
michael@0 375 bufSize);
michael@0 376 if (NS_FAILED(rv)) goto done;
michael@0 377
michael@0 378 rv = NS_NewThread(getter_AddRefs(thread), worker, 0, PR_JOINABLE_THREAD);
michael@0 379 if (NS_FAILED(rv)) goto done;
michael@0 380
michael@0 381 bool inserted = threads.InsertObjectAt(thread, i);
michael@0 382 NS_ASSERTION(inserted, "not inserted");
michael@0 383
michael@0 384 i++;
michael@0 385 }
michael@0 386
michael@0 387 uint32_t j;
michael@0 388 for (j = 0; j < i; j++) {
michael@0 389 nsIThread* thread = threads.ObjectAt(j);
michael@0 390 thread->Join();
michael@0 391 }
michael@0 392
michael@0 393 done:
michael@0 394 NS_ASSERTION(rv == NS_OK, "failed");
michael@0 395
michael@0 396 testTime.EndTime();
michael@0 397 char* testStats = testTime.PrintStats();
michael@0 398 char* workerStats = gTimeSampler.PrintStats();
michael@0 399 printf(" threads = %d\n work time = %s,\n test time = %s\n",
michael@0 400 i, workerStats, testStats);
michael@0 401 PR_smprintf_free(workerStats);
michael@0 402 PR_smprintf_free(testStats);
michael@0 403 }
michael@0 404
michael@0 405 ////////////////////////////////////////////////////////////////////////////////
michael@0 406
michael@0 407 int
michael@0 408 main(int argc, char* argv[])
michael@0 409 {
michael@0 410 nsresult rv;
michael@0 411
michael@0 412 if (argc < 2) {
michael@0 413 printf("usage: %s <in-dir> <out-dir>\n", argv[0]);
michael@0 414 return -1;
michael@0 415 }
michael@0 416 char* inDir = argv[1];
michael@0 417 char* outDir = argv[2];
michael@0 418
michael@0 419 {
michael@0 420 nsCOMPtr<nsIServiceManager> servMan;
michael@0 421 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
michael@0 422 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
michael@0 423 NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
michael@0 424 if (registrar)
michael@0 425 registrar->AutoRegister(nullptr);
michael@0 426
michael@0 427 nsCOMPtr<nsIFile> inDirFile;
michael@0 428 rv = NS_NewNativeLocalFile(nsDependentCString(inDir), false, getter_AddRefs(inDirFile));
michael@0 429 if (NS_FAILED(rv)) return rv;
michael@0 430
michael@0 431 nsCOMPtr<nsIFile> outDirFile;
michael@0 432 rv = NS_NewNativeLocalFile(nsDependentCString(outDir), false, getter_AddRefs(outDirFile));
michael@0 433 if (NS_FAILED(rv)) return rv;
michael@0 434
michael@0 435 CreateFun create = FileChannelWorker::Create;
michael@0 436 Test(create, 1, inDirFile, outDirFile, 16 * 1024);
michael@0 437 #if 1
michael@0 438 printf("FileChannelWorker *****************************\n");
michael@0 439 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 440 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 441 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 442 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 443 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 444 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 445 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 446 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 447 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 448 #endif
michael@0 449 create = FileSpecWorker::Create;
michael@0 450 printf("FileSpecWorker ********************************\n");
michael@0 451 #if 1
michael@0 452 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 453 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 454 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 455 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 456 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 457 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 458 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 459 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 460 Test(create, 20, inDirFile, outDirFile, 16 * 1024);
michael@0 461 #endif
michael@0 462 #if 1
michael@0 463 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 464 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 465 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 466 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 467 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 468 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 469 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 470 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 471 Test(create, 20, inDirFile, outDirFile, 4 * 1024);
michael@0 472 #endif
michael@0 473 } // this scopes the nsCOMPtrs
michael@0 474 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
michael@0 475 rv = NS_ShutdownXPCOM(nullptr);
michael@0 476 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
michael@0 477 return 0;
michael@0 478 }
michael@0 479
michael@0 480 ////////////////////////////////////////////////////////////////////////////////

mercurial