michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 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 "nsIResProtocolHandler.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIIOService.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsIComponentRegistrar.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsIEventQueueService.h" michael@0: #include "nsIURI.h" michael@0: #include "nsCRT.h" michael@0: #include "nsNetCID.h" michael@0: michael@0: static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); michael@0: static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: nsresult michael@0: SetupMapping() michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr serv(do_GetService(kIOServiceCID, &rv)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr ph; michael@0: rv = serv->GetProtocolHandler("res", getter_AddRefs(ph)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr resPH = do_QueryInterface(ph, &rv); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = resPH->AppendSubstitution("foo", "file://y|/"); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = resPH->AppendSubstitution("foo", "file://y|/mozilla/dist/win32_D.OBJ/bin/"); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: nsresult michael@0: TestOpenInputStream(const char* url) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr serv(do_GetService(kIOServiceCID, &rv)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr channel; michael@0: rv = serv->NewChannel(url, michael@0: nullptr, // base uri michael@0: getter_AddRefs(channel)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr in; michael@0: rv = channel->Open(getter_AddRefs(in)); michael@0: if (NS_FAILED(rv)) { michael@0: fprintf(stdout, "failed to OpenInputStream for %s\n", url); michael@0: return NS_OK; michael@0: } michael@0: michael@0: char buf[1024]; michael@0: while (1) { michael@0: uint32_t amt; michael@0: rv = in->Read(buf, sizeof(buf), &amt); michael@0: if (NS_FAILED(rv)) return rv; michael@0: if (amt == 0) break; // eof michael@0: michael@0: char* str = buf; michael@0: while (amt-- > 0) { michael@0: fputc(*str++, stdout); michael@0: } michael@0: } michael@0: nsCOMPtr uri; michael@0: char* str; michael@0: michael@0: rv = channel->GetOriginalURI(getter_AddRefs(uri)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: rv = uri->GetSpec(&str); michael@0: if (NS_FAILED(rv)) return rv; michael@0: fprintf(stdout, "%s resolved to ", str); michael@0: free(str); michael@0: michael@0: rv = channel->GetURI(getter_AddRefs(uri)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: rv = uri->GetSpec(&str); michael@0: if (NS_FAILED(rv)) return rv; michael@0: fprintf(stdout, "%s\n", str); michael@0: free(str); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: bool gDone = false; michael@0: nsIEventQueue* gEventQ = nullptr; michael@0: michael@0: class Listener : public nsIStreamListener michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: Listener() {} michael@0: virtual ~Listener() {} michael@0: michael@0: NS_IMETHOD OnStartRequest(nsIRequest *request, nsISupports *ctxt) { michael@0: nsresult rv; michael@0: nsCOMPtr uri; michael@0: nsCOMPtr channel = do_QueryInterface(request); michael@0: michael@0: rv = channel->GetURI(getter_AddRefs(uri)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: char* str; michael@0: rv = uri->GetSpec(&str); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: fprintf(stdout, "Starting to load %s\n", str); michael@0: free(str); michael@0: } michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *ctxt, michael@0: nsresult aStatus) { michael@0: nsresult rv; michael@0: nsCOMPtr uri; michael@0: nsCOMPtr channel = do_QueryInterface(request); michael@0: michael@0: rv = channel->GetURI(getter_AddRefs(uri)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: char* str; michael@0: rv = uri->GetSpec(&str); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: fprintf(stdout, "Ending load %s, status=%x\n", str, aStatus); michael@0: free(str); michael@0: } michael@0: } michael@0: gDone = true; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD OnDataAvailable(nsIRequest *request, nsISupports *ctxt, michael@0: nsIInputStream *inStr, michael@0: uint64_t sourceOffset, uint32_t count) { michael@0: nsresult rv; michael@0: char buf[1024]; michael@0: while (count > 0) { michael@0: uint32_t amt; michael@0: rv = inStr->Read(buf, sizeof(buf), &amt); michael@0: count -= amt; michael@0: char* c = buf; michael@0: while (amt-- > 0) { michael@0: fputc(*c++, stdout); michael@0: } michael@0: } michael@0: return NS_OK; michael@0: } michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(Listener, nsIStreamListener, nsIRequestObserver) michael@0: michael@0: nsresult michael@0: TestAsyncRead(const char* url) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr eventQService = michael@0: do_GetService(kEventQueueServiceCID, &rv); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr serv(do_GetService(kIOServiceCID, &rv)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr channel; michael@0: rv = serv->NewChannel(url, michael@0: nullptr, // base uri michael@0: getter_AddRefs(channel)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr listener = new Listener(); michael@0: if (listener == nullptr) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: rv = channel->AsyncOpen(nullptr, listener); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: while (!gDone) { michael@0: PLEvent* event; michael@0: rv = gEventQ->GetEvent(&event); michael@0: if (NS_FAILED(rv)) return rv; michael@0: rv = gEventQ->HandleEvent(event); michael@0: if (NS_FAILED(rv)) return rv; michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: int michael@0: main(int argc, char* argv[]) michael@0: { michael@0: nsresult rv; 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: NS_ASSERTION(NS_SUCCEEDED(rv), "AutoregisterComponents failed"); michael@0: michael@0: if (argc < 2) { michael@0: printf("usage: %s resource://foo/\n", argv[0]); michael@0: return -1; michael@0: } michael@0: michael@0: rv = SetupMapping(); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "SetupMapping failed"); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = TestOpenInputStream(argv[1]); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "TestOpenInputStream failed"); michael@0: michael@0: rv = TestAsyncRead(argv[1]); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "TestAsyncRead failed"); 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 rv; michael@0: } michael@0: michael@0: ////////////////////////////////////////////////////////////////////////////////