michael@0: /* -*- Mode: C++; tab-width: 4; 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: /* michael@0: michael@0: A simple test program that reads in RDF/XML into an in-memory data michael@0: source, then uses the RDF/XML serialization API to write an michael@0: equivalent (but not identical) RDF/XML file back to stdout. michael@0: michael@0: The program takes a single parameter: the URL from which to read. michael@0: michael@0: */ michael@0: michael@0: #include michael@0: #include "nsXPCOM.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: #include "nsIIOService.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsIOutputStream.h" michael@0: #include "nsIRDFCompositeDataSource.h" michael@0: #include "nsIRDFNode.h" michael@0: #include "nsIRDFRemoteDataSource.h" michael@0: #include "nsIRDFService.h" michael@0: #include "nsIRDFXMLSource.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsIURL.h" michael@0: #include "nsRDFCID.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "plstr.h" michael@0: #include "prio.h" michael@0: #include "prthread.h" michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // CIDs michael@0: michael@0: // rdf michael@0: static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // Blatantly stolen from netwerk/test/ michael@0: #define RETURN_IF_FAILED(rv, step) \ michael@0: PR_BEGIN_MACRO \ michael@0: if (NS_FAILED(rv)) { \ michael@0: printf(">>> %s failed: rv=%x\n", step, static_cast(rv)); \ michael@0: return 1;\ michael@0: } \ michael@0: PR_END_MACRO michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: michael@0: class ConsoleOutputStreamImpl : public nsIOutputStream michael@0: { michael@0: public: michael@0: ConsoleOutputStreamImpl(void) {} michael@0: virtual ~ConsoleOutputStreamImpl(void) {} michael@0: michael@0: // nsISupports interface michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: // nsIOutputStream interface michael@0: NS_IMETHOD Close(void) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD Write(const char* aBuf, uint32_t aCount, uint32_t *aWriteCount) { michael@0: PR_Write(PR_GetSpecialFD(PR_StandardOutput), aBuf, aCount); michael@0: *aWriteCount = aCount; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHOD michael@0: WriteFrom(nsIInputStream *inStr, uint32_t count, uint32_t *_retval) { michael@0: NS_NOTREACHED("WriteFrom"); michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHOD michael@0: WriteSegments(nsReadSegmentFun reader, void * closure, uint32_t count, uint32_t *_retval) { michael@0: NS_NOTREACHED("WriteSegments"); michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHOD michael@0: IsNonBlocking(bool *aNonBlocking) { michael@0: NS_NOTREACHED("IsNonBlocking"); michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHOD Flush(void) { michael@0: PR_Sync(PR_GetSpecialFD(PR_StandardOutput)); michael@0: return NS_OK; michael@0: } michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(ConsoleOutputStreamImpl, nsIOutputStream) michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: michael@0: int michael@0: main(int argc, char** argv) michael@0: { michael@0: nsresult rv; michael@0: michael@0: if (argc < 2) { michael@0: fprintf(stderr, "usage: %s \n", argv[0]); michael@0: return 1; michael@0: } michael@0: michael@0: NS_InitXPCOM2(nullptr, nullptr, nullptr); michael@0: michael@0: // Create a stream data source and initialize it on argv[1], which michael@0: // is hopefully a "file:" URL. michael@0: nsCOMPtr ds = do_CreateInstance(kRDFXMLDataSourceCID, michael@0: &rv); michael@0: RETURN_IF_FAILED(rv, "RDF/XML datasource creation"); michael@0: michael@0: nsCOMPtr remote = do_QueryInterface(ds, &rv); michael@0: RETURN_IF_FAILED(rv, "QI to nsIRDFRemoteDataSource"); michael@0: michael@0: rv = remote->Init(argv[1]); michael@0: RETURN_IF_FAILED(rv, "datasource initialization"); michael@0: michael@0: // Okay, this should load the XML file... michael@0: rv = remote->Refresh(false); michael@0: RETURN_IF_FAILED(rv, "datasource refresh"); michael@0: michael@0: // Pump events until the load is finished michael@0: nsCOMPtr thread = do_GetCurrentThread(); michael@0: bool done = false; michael@0: while (!done) { michael@0: NS_ENSURE_TRUE(NS_ProcessNextEvent(thread), 1); michael@0: remote->GetLoaded(&done); michael@0: } michael@0: michael@0: // And this should write it back out. The do_QI() on the pointer michael@0: // is a hack to make sure that the new object gets AddRef()-ed. michael@0: nsCOMPtr out = michael@0: do_QueryInterface(new ConsoleOutputStreamImpl, &rv); michael@0: RETURN_IF_FAILED(rv, "creation of console output stream"); michael@0: michael@0: nsCOMPtr source = do_QueryInterface(ds); michael@0: RETURN_IF_FAILED(rv, "QI to nsIRDFXMLSource"); michael@0: michael@0: rv = source->Serialize(out); michael@0: RETURN_IF_FAILED(rv, "datasoure serialization"); michael@0: michael@0: return 0; michael@0: }