michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "TestCommon.h" michael@0: #include "nsIComponentRegistrar.h" michael@0: #include "nsIStreamTransportService.h" michael@0: #include "nsIAsyncInputStream.h" michael@0: #include "nsIProgressEventSink.h" michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsIInterfaceRequestorUtils.h" michael@0: #include "nsIRequest.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsMemory.h" michael@0: #include "nsStringAPI.h" michael@0: #include "nsIFileStreams.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsIFile.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsAutoLock.h" michael@0: #include "prlog.h" michael@0: #include michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: #if defined(PR_LOGGING) michael@0: // michael@0: // set NSPR_LOG_MODULES=Test:5 michael@0: // michael@0: static PRLogModuleInfo *gTestLog = nullptr; michael@0: #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) michael@0: #else michael@0: #define LOG(args) michael@0: #endif michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: class MyListener : public nsIStreamListener michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: MyListener() {} michael@0: virtual ~MyListener() {} michael@0: michael@0: NS_IMETHOD OnStartRequest(nsIRequest *req, nsISupports *ctx) michael@0: { michael@0: LOG(("MyListener::OnStartRequest\n")); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD OnDataAvailable(nsIRequest *req, nsISupports *ctx, michael@0: nsIInputStream *stream, michael@0: uint32_t offset, uint32_t count) michael@0: { michael@0: LOG(("MyListener::OnDataAvailable [offset=%u count=%u]\n", offset, count)); michael@0: michael@0: char buf[500]; michael@0: nsresult rv; michael@0: michael@0: while (count) { michael@0: uint32_t n, amt = std::min(count, sizeof(buf)); michael@0: michael@0: rv = stream->Read(buf, amt, &n); michael@0: if (NS_FAILED(rv)) { michael@0: LOG((" read returned 0x%08x\n", rv)); michael@0: return rv; michael@0: } michael@0: michael@0: LOG((" read %u bytes\n", n)); michael@0: count -= n; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) michael@0: { michael@0: LOG(("MyListener::OnStopRequest [status=%x]\n", status)); michael@0: QuitPumpingEvents(); michael@0: return NS_OK; michael@0: } michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(MyListener, michael@0: nsIRequestObserver, michael@0: nsIStreamListener) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: class MyCallbacks : public nsIInterfaceRequestor michael@0: , public nsIProgressEventSink michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: MyCallbacks() {} michael@0: virtual ~MyCallbacks() {} michael@0: michael@0: NS_IMETHOD GetInterface(const nsID &iid, void **result) michael@0: { michael@0: return QueryInterface(iid, result); michael@0: } michael@0: michael@0: NS_IMETHOD OnStatus(nsIRequest *req, nsISupports *ctx, nsresult status, michael@0: const char16_t *statusArg) michael@0: { michael@0: LOG(("MyCallbacks::OnStatus [status=%x]\n", status)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD OnProgress(nsIRequest *req, nsISupports *ctx, michael@0: uint64_t progress, uint64_t progressMax) michael@0: { michael@0: LOG(("MyCallbacks::OnProgress [progress=%llu/%llu]\n", progress, progressMax)); michael@0: return NS_OK; michael@0: } michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(MyCallbacks, michael@0: nsIInterfaceRequestor, michael@0: nsIProgressEventSink) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: /** michael@0: * asynchronously copy file. michael@0: */ michael@0: static nsresult michael@0: RunTest(nsIFile *file) michael@0: { michael@0: nsresult rv; michael@0: michael@0: LOG(("RunTest\n")); michael@0: michael@0: nsCOMPtr stream; michael@0: rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr uri = do_CreateInstance(kSimpleURICID); michael@0: if (uri) michael@0: uri->SetSpec(NS_LITERAL_CSTRING("foo://bar")); michael@0: michael@0: nsCOMPtr chan; michael@0: rv = NS_NewInputStreamChannel(getter_AddRefs(chan), uri, stream); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = chan->SetNotificationCallbacks(new MyCallbacks()); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = chan->AsyncOpen(new MyListener(), nullptr); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: PumpEvents(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: int michael@0: main(int argc, char* argv[]) michael@0: { michael@0: if (test_common_init(&argc, &argv) != 0) michael@0: return -1; michael@0: michael@0: nsresult rv; michael@0: michael@0: if (argc < 2) { michael@0: printf("usage: %s \n", argv[0]); michael@0: return -1; michael@0: } michael@0: char* fileName = argv[1]; michael@0: { michael@0: nsCOMPtr servMan; michael@0: NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); michael@0: nsCOMPtr registrar = do_QueryInterface(servMan); michael@0: NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); michael@0: if (registrar) michael@0: registrar->AutoRegister(nullptr); michael@0: michael@0: #if defined(PR_LOGGING) michael@0: gTestLog = PR_NewLogModule("Test"); michael@0: #endif michael@0: michael@0: nsCOMPtr file; michael@0: rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(file)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = RunTest(file); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); michael@0: michael@0: // give background threads a chance to finish whatever work they may michael@0: // be doing. michael@0: PR_Sleep(PR_SecondsToInterval(1)); michael@0: } // this scopes the nsCOMPtrs michael@0: // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM michael@0: rv = NS_ShutdownXPCOM(nullptr); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); michael@0: return NS_OK; michael@0: }