Back to index

lightning-sunbird  0.9+nobinonly
TestWriteStream.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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.org 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 "nsIFileTransportService.h"
00039 #include "nsIChannel.h"
00040 #include "nsITransport.h"
00041 #include "nsIServiceManager.h"
00042 #include "nsIComponentManager.h"
00043 #include "nsCOMPtr.h"
00044 #include "nsIMemory.h"
00045 #include "nsString.h"
00046 #include "nsCRT.h"
00047 #include "nsIFileStream.h"
00048 #include "nsIStreamListener.h"
00049 #include "nsIEventQueueService.h"
00050 #include "nsIEventQueue.h"
00051 #include "nsILocalFile.h"
00052 #include "plhash.h"
00053 #include "nsIComponentRegistrar.h"
00054 
00055 static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
00056 
00058 
00059 // A supply of stream data to either store or compare with
00060 class nsITestDataStream {
00061 public:
00062     virtual ~nsITestDataStream() {};
00063     virtual PRUint32 Next() = 0;
00064     virtual void Read(char* aBuf, PRUint32 aCount) = 0;
00065 
00066     virtual PRBool Match(char* aBuf, PRUint32 aCount) = 0;
00067     virtual void Skip(PRUint32 aCount) = 0;
00068 };
00069 
00070 // A reproducible stream of random data.
00071 class RandomStream : public nsITestDataStream {
00072 public:
00073     RandomStream(PRUint32 aSeed) {
00074         mStartSeed = mState = aSeed;
00075     }
00076 
00077     PRUint32 GetStartSeed() {
00078         return mStartSeed;
00079     }
00080 
00081     PRUint32 Next() {
00082         mState = 1103515245 * mState + 12345;
00083         return mState;
00084     }
00085 
00086     void Read(char* aBuf, PRUint32 aCount) {
00087         PRUint32 i;
00088         for (i = 0; i < aCount; i++) {
00089             *aBuf++ = Next();
00090         }
00091     }
00092 
00093     PRBool
00094     Match(char* aBuf, PRUint32 aCount) {
00095         PRUint32 i;
00096         for (i = 0; i < aCount; i++) {
00097             if (*aBuf++ != (char)(Next() & 0xff))
00098                 return PR_FALSE;
00099         }
00100         return PR_TRUE;
00101     }
00102 
00103     void
00104     Skip(PRUint32 aCount) {
00105         while (aCount--)
00106             Next();
00107     }
00108 
00109 protected:
00110 
00111     PRUint32 mState;
00112     PRUint32 mStartSeed;
00113 };
00114 
00115 PRIntervalTime gDuration;
00116 PRUint32 gTotalBytesWritten = 0;
00117 
00119 
00120 nsresult
00121 TestSyncWrite(char* filename, PRUint32 startPosition, PRInt32 length)
00122 {
00123     nsresult rv;
00124     nsCOMPtr<nsIOutputStream> outStream ;
00125     RandomStream *randomStream;
00126     char buf[500];
00127 
00128     nsCOMPtr<nsIFileTransportService> fts = 
00129              do_GetService(kFileTransportServiceCID, &rv) ;
00130     if (NS_FAILED(rv)) return rv ;
00131 
00132     nsCOMPtr<nsILocalFile> fs;
00133     rv = NS_NewNativeLocalFile(nsDependentCString(filename), PR_FALSE, getter_AddRefs(fs));
00134     if (NS_FAILED(rv)) return rv ;
00135 
00136     nsCOMPtr<nsITransport> transport;
00137     rv = fts->CreateTransport(fs, PR_RDWR | PR_CREATE_FILE, 0664, PR_TRUE,
00138                               getter_AddRefs(transport)) ;
00139     if (NS_FAILED(rv)) return rv ;
00140 
00141     rv = transport->OpenOutputStream(startPosition, -1, 0, getter_AddRefs(outStream)) ;
00142     if (NS_FAILED(rv)) return rv;
00143 
00144     PRIntervalTime startTime = PR_IntervalNow();
00145 
00146     randomStream = new RandomStream(PL_HashString(filename));
00147 
00148     int remaining = length;
00149     while (remaining) {
00150         PRUint32 numWritten;
00151         int amount = PR_MIN(sizeof buf, remaining);
00152         randomStream->Read(buf, amount);
00153 
00154         rv = outStream->Write(buf, amount, &numWritten);
00155         NS_ASSERTION(NS_SUCCEEDED(rv), " ");
00156         NS_ASSERTION(numWritten == (PRUint32)amount, "Write() bug?");
00157 
00158         remaining -= amount;
00159     }
00160     outStream->Close();
00161     gTotalBytesWritten += length;
00162 
00163     PRIntervalTime endTime = PR_IntervalNow();
00164     gDuration += (endTime - startTime);
00165 
00166     delete randomStream;
00167 
00168     return NS_OK;
00169 }
00170 
00171 #define MAX_FILES_TO_WRITE 15
00172 
00173 nsresult
00174 TestSyncWrites(char* filenamePrefix, PRUint32 startPosition, PRInt32 length)
00175 {
00176     char filename[100];
00177     int test;
00178     nsresult rv;
00179 
00180     for (test = 0; test < MAX_FILES_TO_WRITE; test++) {
00181         sprintf(filename, "%s_%d", filenamePrefix, test);
00182 
00183         rv = TestSyncWrite(filename, startPosition, length);
00184         if (NS_FAILED(rv)) return rv;
00185     }
00186 
00187     double rate = gTotalBytesWritten / PR_IntervalToMilliseconds(gDuration);
00188     rate *= 1000;
00189     rate /= (1024 * 1024);
00190     printf("Wrote %7d bytes at a rate of %6.2f MB per second \n",
00191            gTotalBytesWritten, rate);
00192 
00193     return NS_OK;
00194 }
00195 
00197 int
00198 main(int argc, char* argv[])
00199 {
00200     nsresult rv;
00201 
00202     if (argc < 3) {
00203         printf("usage: %s <file-prefix-to-write> <num-bytes>\n", argv[0]);
00204         return -1;
00205     }
00206     char* fileName = argv[1];
00207     int length = atoi(argv[2]);
00208     {
00209         nsCOMPtr<nsIServiceManager> servMan;
00210         NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
00211         nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
00212         NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
00213         if (registrar)
00214             registrar->AutoRegister(nsnull);
00215 
00216         rv = TestSyncWrites(fileName, 0, length);
00217         NS_ASSERTION(NS_SUCCEEDED(rv), "TestAsyncRead failed");
00218 
00219     } // this scopes the nsCOMPtrs
00220     // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
00221     rv = NS_ShutdownXPCOM(nsnull);
00222     NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
00223     return NS_OK;
00224 }