Back to index

lightning-sunbird  0.9+nobinonly
TestStreamChannel.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2002
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Darin Fisher <darin@netscape.com>
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 "TestCommon.h"
00039 #include "nsIComponentRegistrar.h"
00040 #include "nsIStreamTransportService.h"
00041 #include "nsIAsyncInputStream.h"
00042 #include "nsIProgressEventSink.h"
00043 #include "nsIInterfaceRequestor.h"
00044 #include "nsIInterfaceRequestorUtils.h"
00045 #include "nsIProxyObjectManager.h"
00046 #include "nsIRequest.h"
00047 #include "nsIServiceManager.h"
00048 #include "nsIComponentManager.h"
00049 #include "nsCOMPtr.h"
00050 #include "nsMemory.h"
00051 #include "nsString.h"
00052 #include "nsIFileStreams.h"
00053 #include "nsIStreamListener.h"
00054 #include "nsIEventQueueService.h"
00055 #include "nsIEventQueue.h"
00056 #include "nsILocalFile.h"
00057 #include "nsNetUtil.h"
00058 #include "nsAutoLock.h"
00059 #include "prlog.h"
00060 
00062 
00063 #if defined(PR_LOGGING)
00064 //
00065 // set NSPR_LOG_MODULES=Test:5
00066 //
00067 static PRLogModuleInfo *gTestLog = nsnull;
00068 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args)
00069 #else
00070 #define LOG(args)
00071 #endif
00072 
00074 
00075 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
00076 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
00077 
00078 PRBool gDone = PR_FALSE;
00079 nsIEventQueue *gEventQ = nsnull;
00080 
00082 
00083 static void *PR_CALLBACK
00084 DoneEvent_Handler(PLEvent *ev)
00085 {
00086     gDone = PR_TRUE;
00087     return nsnull;
00088 }
00089 
00090 static void PR_CALLBACK
00091 DoneEvent_Cleanup(PLEvent *ev)
00092 {
00093     delete ev;
00094 }
00095 
00096 static void
00097 PostDoneEvent()
00098 {
00099     LOG(("PostDoneEvent\n"));
00100 
00101     PLEvent *ev = new PLEvent();
00102 
00103     PL_InitEvent(ev, nsnull, 
00104             DoneEvent_Handler,
00105             DoneEvent_Cleanup);
00106 
00107     gEventQ->PostEvent(ev);
00108 }
00109 
00111 
00112 class MyListener : public nsIStreamListener
00113 {
00114 public:
00115     NS_DECL_ISUPPORTS
00116 
00117     MyListener() {}
00118     virtual ~MyListener() {}
00119 
00120     NS_IMETHOD OnStartRequest(nsIRequest *req, nsISupports *ctx)
00121     {
00122         LOG(("MyListener::OnStartRequest\n"));
00123         return NS_OK;
00124     }
00125 
00126     NS_IMETHOD OnDataAvailable(nsIRequest *req, nsISupports *ctx,
00127                                nsIInputStream *stream,
00128                                PRUint32 offset, PRUint32 count)
00129     {
00130         LOG(("MyListener::OnDataAvailable [offset=%u count=%u]\n", offset, count));
00131 
00132         char buf[500];
00133         nsresult rv;
00134 
00135         while (count) {
00136             PRUint32 n, amt = PR_MIN(count, sizeof(buf));
00137 
00138             rv = stream->Read(buf, amt, &n);
00139             if (NS_FAILED(rv)) {
00140                 LOG(("  read returned 0x%08x\n", rv));
00141                 return rv;
00142             }
00143 
00144             LOG(("  read %u bytes\n", n));
00145             count -= n;
00146         }
00147 
00148         return NS_OK;
00149     }
00150 
00151     NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
00152     {
00153         LOG(("MyListener::OnStopRequest [status=%x]\n", status));
00154         PostDoneEvent();
00155         return NS_OK;
00156     }
00157 };
00158 
00159 NS_IMPL_ISUPPORTS2(MyListener,
00160                    nsIRequestObserver,
00161                    nsIStreamListener)
00162 
00163 
00164 
00165 class MyCallbacks : public nsIInterfaceRequestor
00166                   , public nsIProgressEventSink
00167 {
00168 public:
00169     NS_DECL_ISUPPORTS
00170 
00171     MyCallbacks() {}
00172     virtual ~MyCallbacks() {}
00173 
00174     NS_IMETHOD GetInterface(const nsID &iid, void **result)
00175     {
00176         return QueryInterface(iid, result);
00177     }
00178 
00179     NS_IMETHOD OnStatus(nsIRequest *req, nsISupports *ctx, nsresult status,
00180                         const PRUnichar *statusArg)
00181     {
00182         LOG(("MyCallbacks::OnStatus [status=%x]\n", status));
00183         return NS_OK;
00184     }
00185 
00186     NS_IMETHOD OnProgress(nsIRequest *req, nsISupports *ctx,
00187                           PRUint64 progress, PRUint64 progressMax)
00188     {
00189         LOG(("MyCallbacks::OnProgress [progress=%llu/%llu]\n", progress, progressMax));
00190         return NS_OK;
00191     }
00192 };
00193 
00194 NS_IMPL_ISUPPORTS2(MyCallbacks,
00195                    nsIInterfaceRequestor,
00196                    nsIProgressEventSink)
00197 
00198 
00199 
00203 static nsresult
00204 RunTest(nsIFile *file)
00205 {
00206     nsresult rv;
00207 
00208     LOG(("RunTest\n"));
00209 
00210     nsCOMPtr<nsIInputStream> stream;
00211     rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
00212     if (NS_FAILED(rv)) return rv;
00213 
00214     nsCOMPtr<nsIURI> uri = do_CreateInstance(kSimpleURICID);
00215     if (uri)
00216         uri->SetSpec(NS_LITERAL_CSTRING("foo://bar"));
00217 
00218     nsCOMPtr<nsIChannel> chan;
00219     rv = NS_NewInputStreamChannel(getter_AddRefs(chan), uri, stream);
00220     if (NS_FAILED(rv)) return rv;
00221 
00222     rv = chan->SetNotificationCallbacks(new MyCallbacks());
00223     if (NS_FAILED(rv)) return rv;
00224 
00225     rv = chan->AsyncOpen(new MyListener(), nsnull);
00226     if (NS_FAILED(rv)) return rv;
00227 
00228     gDone = PR_FALSE;
00229     while (!gDone) {
00230         PLEvent *event;
00231         rv = gEventQ->WaitForEvent(&event);
00232         if (NS_FAILED(rv)) return rv;
00233         rv = gEventQ->HandleEvent(event);
00234         if (NS_FAILED(rv)) return rv;
00235     }
00236 
00237     return NS_OK;
00238 }
00239 
00241 
00242 int
00243 main(int argc, char* argv[])
00244 {
00245     if (test_common_init(&argc, &argv) != 0)
00246         return -1;
00247 
00248     nsresult rv;
00249 
00250     if (argc < 2) {
00251         printf("usage: %s <file-to-read>\n", argv[0]);
00252         return -1;
00253     }
00254     char* fileName = argv[1];
00255     {
00256         nsCOMPtr<nsIServiceManager> servMan;
00257         NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
00258         nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
00259         NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
00260         if (registrar)
00261             registrar->AutoRegister(nsnull);
00262 
00263 #if defined(PR_LOGGING)
00264         gTestLog = PR_NewLogModule("Test");
00265 #endif
00266 
00267         nsCOMPtr<nsIEventQueueService> eventQService =
00268                  do_GetService(kEventQueueServiceCID, &rv);
00269         if (NS_FAILED(rv)) return rv;
00270 
00271         rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
00272         if (NS_FAILED(rv)) return rv;
00273 
00274         nsCOMPtr<nsILocalFile> file;
00275         rv = NS_NewNativeLocalFile(nsDependentCString(fileName), PR_FALSE, getter_AddRefs(file));
00276         if (NS_FAILED(rv)) return rv;
00277 
00278         rv = RunTest(file);
00279         NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
00280 
00281         NS_RELEASE(gEventQ);
00282 
00283         // give background threads a chance to finish whatever work they may
00284         // be doing.
00285         PR_Sleep(PR_SecondsToInterval(1));
00286     } // this scopes the nsCOMPtrs
00287     // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
00288     rv = NS_ShutdownXPCOM(nsnull);
00289     NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
00290     return NS_OK;
00291 }