mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
bug 259119, rdf/xml serializer needs to be less memory consuming, first steps of the new APIs, r=bsmedberg, sr=shaver, a=bsmedberg
This commit is contained in:
parent
b5a19bd671
commit
39c3c8adf5
@ -46,6 +46,9 @@ MODULE = rdf
|
||||
GRE_MODULE = 1
|
||||
|
||||
XPIDLSRCS = \
|
||||
rdfIDataSource.idl \
|
||||
rdfITripleVisitor.idl \
|
||||
rdfISerializer.idl \
|
||||
nsIRDFCompositeDataSource.idl \
|
||||
nsIRDFContainer.idl \
|
||||
nsIRDFContainerUtils.idl \
|
||||
|
71
rdf/base/idl/rdfIDataSource.idl
Normal file
71
rdf/base/idl/rdfIDataSource.idl
Normal file
@ -0,0 +1,71 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface rdfITripleVisitor;
|
||||
|
||||
/**
|
||||
* Interface used in RDF to describe data sources.
|
||||
*
|
||||
* @status PLASMA
|
||||
*/
|
||||
|
||||
[scriptable, uuid(ebce86bd-1568-4a34-a808-9ccf9cde8087)]
|
||||
interface rdfIDataSource : nsISupports
|
||||
{
|
||||
/**
|
||||
* Visit all the subject resources in the datasource. The order is
|
||||
* intederminate and may change from one invocation to the next.
|
||||
* The subjects will be in the aSubject argument in calls into
|
||||
* aVisitor, aPredicate and aObject will be null.
|
||||
* @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for
|
||||
* this method, but in this case RDF serializations of this
|
||||
* datasource will not be possible.
|
||||
*/
|
||||
void visitAllSubjects(in rdfITripleVisitor aVisitor);
|
||||
|
||||
/**
|
||||
* Visit all the triples in the datasource. The order is
|
||||
* intederminate and may change from one invocation to the next.
|
||||
* @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for
|
||||
* this method, but in this case RDF serializations of this
|
||||
* datasource will not be possible.
|
||||
*/
|
||||
void visitAllTriples(in rdfITripleVisitor aVisitor);
|
||||
};
|
63
rdf/base/idl/rdfISerializer.idl
Normal file
63
rdf/base/idl/rdfISerializer.idl
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht <axel@pike.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface rdfIDataSource;
|
||||
interface nsIOutputStream;
|
||||
|
||||
/**
|
||||
* Interface used to serialize RDF.
|
||||
*
|
||||
* @status PLASMA
|
||||
*/
|
||||
|
||||
[scriptable, uuid(f0edfcdd-8bca-4d32-9226-7421001396a4)]
|
||||
interface rdfISerializer : nsISupports
|
||||
{
|
||||
/**
|
||||
* Synchronously serialize the given datasource to the outputstream.
|
||||
*
|
||||
* Implementations are not required to implement any buffering or
|
||||
* other stream-based optimizations.
|
||||
*
|
||||
* @param aDataSource The RDF data source to be serialized.
|
||||
* @param aOut The output stream to use.
|
||||
*/
|
||||
void serialize(in rdfIDataSource aDataSource, in nsIOutputStream aOut);
|
||||
};
|
64
rdf/base/idl/rdfITripleVisitor.idl
Normal file
64
rdf/base/idl/rdfITripleVisitor.idl
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <bsmedberg@covad.net>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIRDFResource;
|
||||
interface nsIRDFNode;
|
||||
|
||||
/**
|
||||
* Interface used in RDF to enumerate triples.
|
||||
* Also used by rdfIDataSource::getAllSubjects, then aPredicate,
|
||||
* aObject and aTruthValue are ignored.
|
||||
*
|
||||
* @status PLASMA
|
||||
*/
|
||||
|
||||
[scriptable, function, uuid(aafea151-c271-4505-9978-a100d292800c)]
|
||||
interface rdfITripleVisitor : nsISupports
|
||||
{
|
||||
/**
|
||||
* Callback function for returning query results.
|
||||
*
|
||||
* @param aSubject, aPredicate, aObject describe the (sub-)arc
|
||||
* @returnCode NS_RDF_STOP_VISIT to stop iterating over the query result.
|
||||
* Any error code will stop the iteration as well.
|
||||
*/
|
||||
void visit(in nsIRDFNode aSubject, in nsIRDFResource aPredicate,
|
||||
in nsIRDFNode aObject, in boolean aTruthValue);
|
||||
};
|
@ -95,6 +95,9 @@ static const char kURI##prefix##_##name[] = ns #name
|
||||
willing to record the statement. */
|
||||
#define NS_RDF_ASSERTION_REJECTED NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_RDF, 3)
|
||||
|
||||
/* Return this from rdfITripleVisitor to stop cycling */
|
||||
#define NS_RDF_STOP_VISIT NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_RDF, 4)
|
||||
|
||||
|
||||
|
||||
/* ContractID prefixes for RDF DLL registration. */
|
||||
@ -105,6 +108,8 @@ static const char kURI##prefix##_##name[] = ns #name
|
||||
#define NS_RDF_RESOURCE_FACTORY_CONTRACTID_PREFIX NS_RDF_RESOURCE_FACTORY_CONTRACTID "?name="
|
||||
#define NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX NS_RDF_CONTRACTID "/infer-datasource;1?engine="
|
||||
|
||||
#define NS_RDF_SERIALIZER NS_RDF_CONTRACTID "/serializer;1?format="
|
||||
|
||||
// contract ID is in the form
|
||||
// @mozilla.org/rdf/delegate-factory;1?key=<key>&scheme=<scheme>
|
||||
#define NS_RDF_DELEGATEFACTORY_CONTRACTID "@mozilla.org/rdf/delegate-factory;1"
|
||||
|
@ -56,6 +56,7 @@ REQUIRES = xpcom \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
rdfTriplesSerializer.cpp \
|
||||
nsCompositeDataSource.cpp \
|
||||
nsContainerEnumerator.cpp \
|
||||
nsDefaultResourceFactory.cpp \
|
||||
|
@ -99,6 +99,8 @@
|
||||
#include "prlog.h"
|
||||
#include "rdf.h"
|
||||
|
||||
#include "rdfIDataSource.h"
|
||||
#include "rdfITripleVisitor.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gLog = nsnull;
|
||||
@ -293,7 +295,8 @@ class InMemoryResourceEnumeratorImpl;
|
||||
class InMemoryDataSource : public nsIRDFDataSource,
|
||||
public nsIRDFInMemoryDataSource,
|
||||
public nsIRDFPropagatableDataSource,
|
||||
public nsIRDFPurgeableDataSource
|
||||
public nsIRDFPurgeableDataSource,
|
||||
public rdfIDataSource
|
||||
{
|
||||
protected:
|
||||
nsFixedSizeAllocator mAllocator;
|
||||
@ -309,6 +312,10 @@ protected:
|
||||
nsCOMArray<nsIRDFObserver> mObservers;
|
||||
PRUint32 mNumObservers;
|
||||
|
||||
// VisitFoo needs to block writes, [Un]Assert only allowed
|
||||
// during mReadCount == 0
|
||||
PRUint32 mReadCount;
|
||||
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg);
|
||||
@ -355,6 +362,9 @@ public:
|
||||
// nsIRDFPurgeableDataSource methods
|
||||
NS_DECL_NSIRDFPURGEABLEDATASOURCE
|
||||
|
||||
// rdfIDataSource methods
|
||||
NS_DECL_RDFIDATASOURCE
|
||||
|
||||
protected:
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
SweepForwardArcsEntries(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
@ -867,7 +877,7 @@ NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResu
|
||||
|
||||
|
||||
InMemoryDataSource::InMemoryDataSource(nsISupports* aOuter)
|
||||
: mNumObservers(0)
|
||||
: mNumObservers(0), mReadCount(0)
|
||||
{
|
||||
NS_INIT_AGGREGATED(aOuter);
|
||||
|
||||
@ -988,6 +998,9 @@ InMemoryDataSource::AggregatedQueryInterface(REFNSIID aIID, void** aResult)
|
||||
else if (aIID.Equals(NS_GET_IID(nsIRDFPurgeableDataSource))) {
|
||||
*aResult = NS_STATIC_CAST(nsIRDFPurgeableDataSource*, this);
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(rdfIDataSource))) {
|
||||
*aResult = NS_STATIC_CAST(rdfIDataSource*, this);
|
||||
}
|
||||
else {
|
||||
*aResult = nsnull;
|
||||
return NS_NOINTERFACE;
|
||||
@ -1373,6 +1386,11 @@ InMemoryDataSource::Assert(nsIRDFResource* aSource,
|
||||
if (! aTarget)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mReadCount) {
|
||||
NS_WARNING("Writing to InMemoryDataSource during read\n");
|
||||
return NS_RDF_ASSERTION_REJECTED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
rv = LockedAssert(aSource, aProperty, aTarget, aTruthValue);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@ -1527,6 +1545,11 @@ InMemoryDataSource::Unassert(nsIRDFResource* aSource,
|
||||
if (! aTarget)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mReadCount) {
|
||||
NS_WARNING("Writing to InMemoryDataSource during read\n");
|
||||
return NS_RDF_ASSERTION_REJECTED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = LockedUnassert(aSource, aProperty, aTarget);
|
||||
@ -1571,6 +1594,11 @@ InMemoryDataSource::Change(nsIRDFResource* aSource,
|
||||
if (! aNewTarget)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mReadCount) {
|
||||
NS_WARNING("Writing to InMemoryDataSource during read\n");
|
||||
return NS_RDF_ASSERTION_REJECTED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// XXX We can implement LockedChange() if we decide that this
|
||||
@ -1621,6 +1649,11 @@ InMemoryDataSource::Move(nsIRDFResource* aOldSource,
|
||||
if (! aTarget)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mReadCount) {
|
||||
NS_WARNING("Writing to InMemoryDataSource during read\n");
|
||||
return NS_RDF_ASSERTION_REJECTED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// XXX We can implement LockedMove() if we decide that this
|
||||
@ -2117,4 +2150,130 @@ InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable,
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// rdfIDataSource methods
|
||||
|
||||
class VisitorClosure
|
||||
{
|
||||
public:
|
||||
VisitorClosure(rdfITripleVisitor* aVisitor) :
|
||||
mVisitor(aVisitor),
|
||||
mRv(NS_OK)
|
||||
{};
|
||||
rdfITripleVisitor* mVisitor;
|
||||
nsresult mRv;
|
||||
};
|
||||
|
||||
PLDHashOperator PR_CALLBACK
|
||||
SubjectEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aHdr);
|
||||
VisitorClosure* closure = NS_STATIC_CAST(VisitorClosure*, aArg);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, PL_DHASH_NEXT);
|
||||
|
||||
closure->mRv = closure->mVisitor->Visit(subject, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(closure->mRv) || closure->mRv == NS_RDF_STOP_VISIT)
|
||||
return PL_DHASH_STOP;
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor)
|
||||
{
|
||||
// Lock datasource against writes
|
||||
++mReadCount;
|
||||
|
||||
// Enumerate all of our entries into an nsISupportsArray.
|
||||
VisitorClosure cls(aVisitor);
|
||||
PL_DHashTableEnumerate(&mForwardArcs, SubjectEnumerator, &cls);
|
||||
|
||||
// Unlock datasource
|
||||
--mReadCount;
|
||||
|
||||
return cls.mRv;
|
||||
}
|
||||
|
||||
class TriplesInnerClosure
|
||||
{
|
||||
public:
|
||||
TriplesInnerClosure(nsIRDFNode* aSubject, VisitorClosure* aClosure) :
|
||||
mSubject(aSubject), mOuter(aClosure) {};
|
||||
nsIRDFNode* mSubject;
|
||||
VisitorClosure* mOuter;
|
||||
};
|
||||
|
||||
PLDHashOperator PR_CALLBACK
|
||||
TriplesInnerEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aHdr);
|
||||
Assertion* assertion = entry->mAssertions;
|
||||
TriplesInnerClosure* closure =
|
||||
NS_STATIC_CAST(TriplesInnerClosure*, aArg);
|
||||
while (assertion) {
|
||||
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
|
||||
VisitorClosure* cls = closure->mOuter;
|
||||
cls->mRv = cls->mVisitor->Visit(closure->mSubject,
|
||||
assertion->u.as.mProperty,
|
||||
assertion->u.as.mTarget,
|
||||
assertion->u.as.mTruthValue);
|
||||
if (NS_FAILED(cls->mRv) || cls->mRv == NS_RDF_STOP_VISIT) {
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
assertion = assertion->mNext;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
PLDHashOperator PR_CALLBACK
|
||||
TriplesEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aHdr);
|
||||
VisitorClosure* closure = NS_STATIC_CAST(VisitorClosure*, aArg);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRDFNode> subject = do_QueryInterface(entry->mNode, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, PL_DHASH_NEXT);
|
||||
|
||||
if (entry->mAssertions->mHashEntry) {
|
||||
TriplesInnerClosure cls(subject, closure);
|
||||
PL_DHashTableEnumerate(entry->mAssertions->u.hash.mPropertyHash,
|
||||
TriplesInnerEnumerator, &cls);
|
||||
if (NS_FAILED(closure->mRv)) {
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
Assertion* assertion = entry->mAssertions;
|
||||
while (assertion) {
|
||||
NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes");
|
||||
closure->mRv = closure->mVisitor->Visit(subject,
|
||||
assertion->u.as.mProperty,
|
||||
assertion->u.as.mTarget,
|
||||
assertion->u.as.mTruthValue);
|
||||
if (NS_FAILED(closure->mRv) || closure->mRv == NS_RDF_STOP_VISIT) {
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
assertion = assertion->mNext;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor)
|
||||
{
|
||||
// Lock datasource against writes
|
||||
++mReadCount;
|
||||
|
||||
// Enumerate all of our entries into an nsISupportsArray.
|
||||
VisitorClosure cls(aVisitor);
|
||||
PL_DHashTableEnumerate(&mForwardArcs, TriplesEnumerator, &cls);
|
||||
|
||||
// Unlock datasource
|
||||
--mReadCount;
|
||||
|
||||
return cls.mRv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -123,6 +123,8 @@
|
||||
#include "nsNameSpaceMap.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "rdfIDataSource.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
|
||||
@ -215,7 +217,8 @@ class RDFXMLDataSourceImpl : public nsIRDFDataSource,
|
||||
public nsIRDFRemoteDataSource,
|
||||
public nsIRDFXMLSink,
|
||||
public nsIRDFXMLSource,
|
||||
public nsIStreamListener
|
||||
public nsIStreamListener,
|
||||
public rdfIDataSource
|
||||
{
|
||||
protected:
|
||||
enum LoadState {
|
||||
@ -386,6 +389,21 @@ public:
|
||||
// nsIStreamListener
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
// rdfIDataSource
|
||||
NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<rdfIDataSource> rdfds = do_QueryInterface(mInner, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return rdfds->VisitAllSubjects(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMETHOD VisitAllTriples(rdfITripleVisitor *aVisitor) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<rdfIDataSource> rdfds = do_QueryInterface(mInner, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return rdfds->VisitAllTriples(aVisitor);
|
||||
}
|
||||
|
||||
// Implementation methods
|
||||
PRBool
|
||||
MakeQName(nsIRDFResource* aResource,
|
||||
@ -519,13 +537,14 @@ RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void)
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS6(RDFXMLDataSourceImpl,
|
||||
NS_IMPL_ISUPPORTS7(RDFXMLDataSourceImpl,
|
||||
nsIRDFDataSource,
|
||||
nsIRDFRemoteDataSource,
|
||||
nsIRDFXMLSink,
|
||||
nsIRDFXMLSource,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener)
|
||||
nsIStreamListener,
|
||||
rdfIDataSource)
|
||||
|
||||
|
||||
nsresult
|
||||
|
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Waterson <waterson@netscape.com>
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -50,6 +51,10 @@
|
||||
#include "rdf.h"
|
||||
#include "rdfutil.h"
|
||||
|
||||
#include "rdfIDataSource.h"
|
||||
|
||||
#include "nsITimelineService.h"
|
||||
|
||||
PRInt32 nsRDFXMLSerializer::gRefCnt = 0;
|
||||
nsIRDFContainerUtils* nsRDFXMLSerializer::gRDFC;
|
||||
nsIRDFResource* nsRDFXMLSerializer::kRDF_instanceOf;
|
||||
@ -161,13 +166,25 @@ nsRDFXMLSerializer::Init(nsIRDFDataSource* aDataSource)
|
||||
prefix = do_GetAtom("NC");
|
||||
AddNameSpace(prefix, NS_LITERAL_STRING("http://home.netscape.com/NC-rdf#"));
|
||||
|
||||
mQNames.Init();
|
||||
mPrefixID = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFXMLSerializer::AddNameSpace(nsIAtom* aPrefix, const nsAString& aURI)
|
||||
{
|
||||
mNameSpaces.Put(aURI, aPrefix);
|
||||
nsCOMPtr<nsIAtom> prefix = aPrefix;
|
||||
if (!prefix) {
|
||||
// Make up a prefix, we don't want default namespaces, so
|
||||
// that we can use QNames for elements and attributes alike.
|
||||
nsCAutoString pref;
|
||||
pref.AssignLiteral("NS");
|
||||
pref.AppendInt(++mPrefixID, 10);
|
||||
prefix = do_GetAtom(pref);
|
||||
}
|
||||
mNameSpaces.Put(aURI, prefix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -203,31 +220,24 @@ rdf_BlockingWrite(nsIOutputStream* stream, const nsAString& s)
|
||||
}
|
||||
|
||||
// This converts a property resource (like
|
||||
// "http://www.w3.org/TR/WD-rdf-syntax#Description") into a property
|
||||
// ("Description"), a namespace prefix ("RDF"), and a namespace URI
|
||||
// ("http://www.w3.org/TR/WD-rdf-syntax#").
|
||||
// "http://www.w3.org/TR/WD-rdf-syntax#Description") into a QName
|
||||
// ("RDF:Description"), and registers the namespace, if it's made up.
|
||||
|
||||
PRBool
|
||||
nsRDFXMLSerializer::MakeQName(nsIRDFResource* aResource,
|
||||
nsCString& aProperty,
|
||||
nsCString& aNameSpacePrefix,
|
||||
nsCString& aNameSpaceURI)
|
||||
nsresult
|
||||
nsRDFXMLSerializer::RegisterQName(nsIRDFResource* aResource)
|
||||
{
|
||||
nsCAutoString uri;
|
||||
nsCAutoString uri, qname;
|
||||
aResource->GetValueUTF8(uri);
|
||||
|
||||
nsNameSpaceMap::const_iterator iter = mNameSpaces.GetNameSpaceOf(uri);
|
||||
if (iter != mNameSpaces.last()) {
|
||||
if (iter->mPrefix)
|
||||
iter->mPrefix->ToUTF8String(aNameSpacePrefix);
|
||||
else
|
||||
aNameSpacePrefix.Truncate();
|
||||
|
||||
aNameSpaceURI = iter->mURI;
|
||||
uri.Right(aProperty, uri.Length() - aNameSpaceURI.Length());
|
||||
return PR_TRUE;
|
||||
NS_ENSURE_TRUE(iter->mPrefix, NS_ERROR_UNEXPECTED);
|
||||
iter->mPrefix->ToUTF8String(qname);
|
||||
qname.Append(':');
|
||||
qname += StringTail(uri, uri.Length() - iter->mURI.Length());
|
||||
return mQNames.Put(aResource, qname) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// Okay, so we don't have it in our map. Try to make one up. This
|
||||
// is very bogus.
|
||||
PRInt32 i = uri.RFindChar('#'); // first try a '#'
|
||||
@ -236,30 +246,29 @@ nsRDFXMLSerializer::MakeQName(nsIRDFResource* aResource,
|
||||
if (i == -1) {
|
||||
// Okay, just punt and assume there is _no_ namespace on
|
||||
// this thing...
|
||||
aNameSpaceURI.Truncate();
|
||||
aNameSpacePrefix.Truncate();
|
||||
aProperty = uri;
|
||||
return PR_TRUE;
|
||||
return mQNames.Put(aResource, uri) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Take whatever is to the right of the '#' and call it the
|
||||
// property.
|
||||
aProperty.Truncate();
|
||||
uri.Right(aProperty, uri.Length() - (i + 1));
|
||||
// Take whatever is to the right of the '#' or '/' and call it the
|
||||
// local name, make up a prefix.
|
||||
qname.AssignLiteral("NS");
|
||||
qname.AppendInt(++mPrefixID, 10);
|
||||
{
|
||||
nsCOMPtr<nsIAtom> prefix = do_GetAtom(qname);
|
||||
mNameSpaces.Put(StringHead(uri, i+1), prefix);
|
||||
}
|
||||
qname.Append(':');
|
||||
qname += StringTail(uri, uri.Length() - (i + 1));
|
||||
|
||||
// Truncate the namespace URI down to the string up to and
|
||||
// including the '#'.
|
||||
aNameSpaceURI = uri;
|
||||
aNameSpaceURI.Truncate(i + 1);
|
||||
|
||||
// Just generate a random prefix
|
||||
static PRInt32 gPrefixID = 0;
|
||||
aNameSpacePrefix.AssignLiteral("NS");
|
||||
aNameSpacePrefix.AppendInt(++gPrefixID, 10);
|
||||
return PR_FALSE;
|
||||
return mQNames.Put(aResource, qname) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRDFXMLSerializer::GetQName(nsIRDFResource* aResource, nsCString& aQName)
|
||||
{
|
||||
return mQNames.Get(aResource, &aQName) ? NS_OK : NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsRDFXMLSerializer::IsContainerProperty(nsIRDFResource* aProperty)
|
||||
@ -370,42 +379,24 @@ nsRDFXMLSerializer::SerializeInlineAssertion(nsIOutputStream* aStream,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFLiteral* aValue)
|
||||
{
|
||||
nsCAutoString property, nameSpacePrefix, nameSpaceURI;
|
||||
nsCAutoString attr;
|
||||
|
||||
PRBool wasDefinedAtGlobalScope =
|
||||
MakeQName(aProperty, property, nameSpacePrefix, nameSpaceURI);
|
||||
|
||||
if (nameSpacePrefix.Length()) {
|
||||
attr.Append(nameSpacePrefix);
|
||||
attr.Append(':');
|
||||
}
|
||||
attr.Append(property);
|
||||
|
||||
nsresult rv;
|
||||
nsCString qname;
|
||||
rv = GetQName(aProperty, qname);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = rdf_BlockingWrite(aStream,
|
||||
NS_LITERAL_CSTRING("\n "));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!wasDefinedAtGlobalScope && nameSpacePrefix.Length()) {
|
||||
nsCAutoString nsutf8 =
|
||||
NS_LITERAL_CSTRING("xmlns:") +
|
||||
nameSpacePrefix +
|
||||
NS_LITERAL_CSTRING("=\"") +
|
||||
nameSpaceURI +
|
||||
NS_LITERAL_CSTRING("\" ");
|
||||
rv = rdf_BlockingWrite(aStream, nsutf8);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
const PRUnichar* value;
|
||||
aValue->GetValueConst(&value);
|
||||
NS_ConvertUTF16toUTF8 s(value);
|
||||
|
||||
rdf_EscapeAttributeValue(s);
|
||||
|
||||
attr.AppendLiteral("=\"");
|
||||
rv = rdf_BlockingWrite(aStream, attr);
|
||||
rv = rdf_BlockingWrite(aStream, qname);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = rdf_BlockingWrite(aStream, "=\"", 2);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
s.Append('"');
|
||||
return rdf_BlockingWrite(aStream, s);
|
||||
@ -417,33 +408,15 @@ nsRDFXMLSerializer::SerializeChildAssertion(nsIOutputStream* aStream,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aValue)
|
||||
{
|
||||
nsCAutoString property, nameSpacePrefix, nameSpaceURI;
|
||||
nsCAutoString tag;
|
||||
nsCString qname;
|
||||
nsresult rv = GetQName(aProperty, qname);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool wasDefinedAtGlobalScope =
|
||||
MakeQName(aProperty, property, nameSpacePrefix, nameSpaceURI);
|
||||
|
||||
if (nameSpacePrefix.Length()) {
|
||||
tag.Append(nameSpacePrefix);
|
||||
tag.Append(':');
|
||||
}
|
||||
tag.Append(property);
|
||||
|
||||
nsresult rv = rdf_BlockingWrite(aStream, " <", 5);
|
||||
rv = rdf_BlockingWrite(aStream, " <", 5);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = rdf_BlockingWrite(aStream, tag);
|
||||
rv = rdf_BlockingWrite(aStream, qname);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!wasDefinedAtGlobalScope && nameSpacePrefix.Length()) {
|
||||
nsCAutoString out = NS_LITERAL_CSTRING(" xmlns:") +
|
||||
nameSpacePrefix +
|
||||
NS_LITERAL_CSTRING("=\"") +
|
||||
nameSpaceURI +
|
||||
NS_LITERAL_CSTRING("\"");
|
||||
rv = rdf_BlockingWrite(aStream, out);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRDFResource> resource;
|
||||
nsCOMPtr<nsIRDFLiteral> literal;
|
||||
nsCOMPtr<nsIRDFInt> number;
|
||||
@ -516,8 +489,9 @@ nsRDFXMLSerializer::SerializeChildAssertion(nsIOutputStream* aStream,
|
||||
|
||||
rv = rdf_BlockingWrite(aStream, "</", 2);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
tag.AppendLiteral(">\n");
|
||||
return rdf_BlockingWrite(aStream, tag);
|
||||
rv = rdf_BlockingWrite(aStream, qname);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return rdf_BlockingWrite(aStream, ">\n", 2);
|
||||
|
||||
no_close_tag:
|
||||
return NS_OK;
|
||||
@ -600,7 +574,7 @@ nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream,
|
||||
nsresult rv;
|
||||
|
||||
PRBool isTypedNode = PR_FALSE;
|
||||
nsCAutoString nodeName, nameSpacePrefix, nameSpaceURI;
|
||||
nsCString typeQName;
|
||||
|
||||
nsCOMPtr<nsIRDFNode> typeNode;
|
||||
mDataSource->GetTarget(aResource, kRDF_type, PR_TRUE, getter_AddRefs(typeNode));
|
||||
@ -611,8 +585,7 @@ nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream,
|
||||
// just treat the description as if it weren't a typed node
|
||||
// after all and emit rdf:type as a normal property. This
|
||||
// seems preferable to using a bogus (invented) prefix.
|
||||
isTypedNode = MakeQName(type, nodeName,
|
||||
nameSpacePrefix, nameSpaceURI);
|
||||
isTypedNode = NS_SUCCEEDED(GetQName(type, typeQName));
|
||||
}
|
||||
}
|
||||
|
||||
@ -628,12 +601,7 @@ nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream,
|
||||
rv = rdf_BlockingWrite(aStream, NS_LITERAL_STRING(" <"));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// Watch out for the default namespace!
|
||||
if (!nameSpacePrefix.IsEmpty()) {
|
||||
nameSpacePrefix.Append(':');
|
||||
rv = rdf_BlockingWrite(aStream, nameSpacePrefix);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
rv = rdf_BlockingWrite(aStream, nodeName);
|
||||
rv = rdf_BlockingWrite(aStream, typeQName);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
@ -747,13 +715,9 @@ nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream,
|
||||
rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" </"));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// Watch out for the default namespace!
|
||||
if (!nameSpacePrefix.IsEmpty()) {
|
||||
// ':' already appended above
|
||||
rv = rdf_BlockingWrite(aStream, nameSpacePrefix);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
nodeName.Append(">\n", 2);
|
||||
rdf_BlockingWrite(aStream, nodeName);
|
||||
rdf_BlockingWrite(aStream, typeQName);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rdf_BlockingWrite(aStream, ">\n", 2);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
@ -1057,76 +1021,61 @@ nsRDFXMLSerializer::SerializeEpilogue(nsIOutputStream* aStream)
|
||||
return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("</RDF:RDF>\n"));
|
||||
}
|
||||
|
||||
class QNameCollector : public rdfITripleVisitor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_RDFITRIPLEVISITOR
|
||||
QNameCollector(nsRDFXMLSerializer* aParent)
|
||||
: mParent(aParent){}
|
||||
private:
|
||||
nsRDFXMLSerializer* mParent;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(QNameCollector, rdfITripleVisitor)
|
||||
nsresult
|
||||
nsRDFXMLSerializer::CollectNamespaces()
|
||||
QNameCollector::Visit(nsIRDFNode* aSubject, nsIRDFResource* aPredicate,
|
||||
nsIRDFNode* aObject, PRBool aTruthValue)
|
||||
{
|
||||
// Iterate through all the resources in the datasource, and all of
|
||||
// the arcs-out of each, to collect the set of namespaces in use
|
||||
nsCOMPtr<nsISimpleEnumerator> resources;
|
||||
mDataSource->GetAllResources(getter_AddRefs(resources));
|
||||
if (! resources)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
while (1) {
|
||||
PRBool hasMore = PR_FALSE;
|
||||
resources->HasMoreElements(&hasMore);
|
||||
if (! hasMore)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsISupports> isupports;
|
||||
resources->GetNext(getter_AddRefs(isupports));
|
||||
|
||||
nsCOMPtr<nsIRDFResource> resource =
|
||||
do_QueryInterface(isupports);
|
||||
|
||||
if (! resource)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> arcs;
|
||||
mDataSource->ArcLabelsOut(resource, getter_AddRefs(arcs));
|
||||
|
||||
if (! arcs)
|
||||
continue;
|
||||
|
||||
while (1) {
|
||||
hasMore = PR_FALSE;
|
||||
arcs->HasMoreElements(&hasMore);
|
||||
if (! hasMore)
|
||||
break;
|
||||
|
||||
arcs->GetNext(getter_AddRefs(isupports));
|
||||
|
||||
nsCOMPtr<nsIRDFResource> property =
|
||||
do_QueryInterface(isupports);
|
||||
|
||||
if (! property)
|
||||
continue;
|
||||
|
||||
EnsureNameSpaceFor(property);
|
||||
if (aPredicate == mParent->kRDF_type) {
|
||||
// try to get a type QName for aObject, should be a resource
|
||||
nsCOMPtr<nsIRDFResource> resType = do_QueryInterface(aObject);
|
||||
if (!resType) {
|
||||
// ignore error
|
||||
return NS_OK;
|
||||
}
|
||||
if (mParent->mQNames.Get(resType, nsnull)) {
|
||||
return NS_OK;
|
||||
}
|
||||
mParent->RegisterQName(resType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mParent->mQNames.Get(aPredicate, nsnull)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (aPredicate == mParent->kRDF_instanceOf ||
|
||||
aPredicate == mParent->kRDF_nextVal)
|
||||
return NS_OK;
|
||||
PRBool isOrdinal = PR_FALSE;
|
||||
mParent->gRDFC->IsOrdinalProperty(aPredicate, &isOrdinal);
|
||||
if (isOrdinal)
|
||||
return NS_OK;
|
||||
|
||||
mParent->RegisterQName(aPredicate);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRDFXMLSerializer::EnsureNameSpaceFor(nsIRDFResource* aResource)
|
||||
nsRDFXMLSerializer::CollectNamespaces()
|
||||
{
|
||||
nsCAutoString property;
|
||||
nsCAutoString nameSpacePrefix;
|
||||
nsCAutoString nameSpaceURI;
|
||||
|
||||
if (! MakeQName(aResource, property, nameSpacePrefix, nameSpaceURI)) {
|
||||
#ifdef DEBUG_waterson
|
||||
const char* s;
|
||||
aResource->GetValueConst(&s);
|
||||
printf("*** Creating namespace for %s\n", s);
|
||||
#endif
|
||||
nsCOMPtr<nsIAtom> prefix = do_GetAtom(nameSpacePrefix);
|
||||
mNameSpaces.Put(nameSpaceURI, prefix);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
// Iterate over all Triples to get namespaces for subject resource types
|
||||
// and Predicates and cache all the QNames we want to use.
|
||||
nsCOMPtr<rdfITripleVisitor> collector =
|
||||
new QNameCollector(this);
|
||||
nsCOMPtr<rdfIDataSource> ds = do_QueryInterface(mDataSource); // XXX API
|
||||
NS_ENSURE_TRUE(collector && ds, NS_ERROR_FAILURE);
|
||||
return ds->VisitAllTriples(collector);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -1135,6 +1084,7 @@ NS_IMETHODIMP
|
||||
nsRDFXMLSerializer::Serialize(nsIOutputStream* aStream)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_TIMELINE_START_TIMER("rdf/xml-ser");
|
||||
|
||||
rv = CollectNamespaces();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@ -1173,7 +1123,11 @@ nsRDFXMLSerializer::Serialize(nsIOutputStream* aStream)
|
||||
break;
|
||||
}
|
||||
|
||||
return SerializeEpilogue(aStream);
|
||||
rv = SerializeEpilogue(aStream);
|
||||
NS_TIMELINE_STOP_TIMER("rdf/xml-ser");
|
||||
NS_TIMELINE_MARK("rdf/xml-ser");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Waterson <waterson@netscape.com>
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -46,6 +47,9 @@
|
||||
#include "nsNameSpaceMap.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
#include "rdfITripleVisitor.h"
|
||||
|
||||
class nsString;
|
||||
class nsIOutputStream;
|
||||
class nsIRDFContainerUtils;
|
||||
@ -71,11 +75,10 @@ protected:
|
||||
virtual ~nsRDFXMLSerializer();
|
||||
|
||||
// Implementation methods
|
||||
PRBool
|
||||
MakeQName(nsIRDFResource* aResource,
|
||||
nsCString& aPproperty,
|
||||
nsCString& aNameSpacePrefix,
|
||||
nsCString& aNameSpaceURI);
|
||||
nsresult
|
||||
RegisterQName(nsIRDFResource* aResource);
|
||||
nsresult
|
||||
GetQName(nsIRDFResource* aResource, nsCString& aQName);
|
||||
|
||||
nsresult
|
||||
SerializeInlineAssertion(nsIOutputStream* aStream,
|
||||
@ -121,9 +124,6 @@ protected:
|
||||
nsresult
|
||||
CollectNamespaces();
|
||||
|
||||
nsresult
|
||||
EnsureNameSpaceFor(nsIRDFResource* aResource);
|
||||
|
||||
PRBool
|
||||
IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType);
|
||||
|
||||
@ -131,6 +131,12 @@ protected:
|
||||
nsNameSpaceMap mNameSpaces;
|
||||
nsXPIDLCString mBaseURLSpec;
|
||||
|
||||
// hash mapping resources to utf8-encoded QNames
|
||||
nsDataHashtable<nsISupportsHashKey, nsCString> mQNames;
|
||||
friend class QNameCollector;
|
||||
|
||||
PRUint32 mPrefixID;
|
||||
|
||||
static PRInt32 gRefCnt;
|
||||
static nsIRDFResource* kRDF_instanceOf;
|
||||
static nsIRDFResource* kRDF_type;
|
||||
|
183
rdf/base/src/rdfTriplesSerializer.cpp
Normal file
183
rdf/base/src/rdfTriplesSerializer.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsIBufferedStreams.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include "rdfISerializer.h"
|
||||
#include "rdfIDataSource.h"
|
||||
#include "rdfITripleVisitor.h"
|
||||
|
||||
#include "nsIRDFResource.h"
|
||||
#include "nsIRDFLiteral.h"
|
||||
|
||||
class TriplesVisitor : public rdfITripleVisitor
|
||||
{
|
||||
public:
|
||||
TriplesVisitor(nsIOutputStream* aOut) : mOut(aOut) {};
|
||||
NS_DECL_RDFITRIPLEVISITOR
|
||||
NS_DECL_ISUPPORTS
|
||||
protected:
|
||||
nsresult writeResource(nsIRDFResource* aResource);
|
||||
nsIOutputStream* mOut;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(TriplesVisitor, rdfITripleVisitor)
|
||||
|
||||
nsresult
|
||||
TriplesVisitor::writeResource(nsIRDFResource *aResource)
|
||||
{
|
||||
nsCString res;
|
||||
PRUint32 writeCount, wroteCount;
|
||||
mOut->Write("<", 1, &wroteCount);
|
||||
NS_ENSURE_TRUE(wroteCount == 1, NS_ERROR_FAILURE);
|
||||
nsresult rv = aResource->GetValueUTF8(res);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
writeCount = res.Length();
|
||||
mOut->Write(res.get(), writeCount, &wroteCount);
|
||||
NS_ENSURE_TRUE(writeCount == wroteCount, NS_ERROR_FAILURE);
|
||||
mOut->Write("> ", 2, &wroteCount);
|
||||
NS_ENSURE_TRUE(wroteCount == 2, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TriplesVisitor::Visit(nsIRDFNode *aSubject, nsIRDFResource *aPredicate,
|
||||
nsIRDFNode *aObject, PRBool aTruthValue)
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> subjectRes = do_QueryInterface(aSubject);
|
||||
nsresult rv = NS_OK;
|
||||
if (subjectRes) {
|
||||
rv = writeResource(subjectRes);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = writeResource(aPredicate);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsIRDFResource> res = do_QueryInterface(aObject);
|
||||
nsCOMPtr<nsIRDFLiteral> lit;
|
||||
nsCOMPtr<nsIRDFInt> intLit;
|
||||
PRUint32 wroteCount;
|
||||
if (res) {
|
||||
rv = writeResource(res);
|
||||
} else if ((lit = do_QueryInterface(aObject)) != nsnull) {
|
||||
const PRUnichar *value;
|
||||
lit->GetValueConst(&value);
|
||||
nsCAutoString object;
|
||||
object.AppendLiteral("\"");
|
||||
AppendUTF16toUTF8(value, object);
|
||||
object.AppendLiteral("\" ");
|
||||
PRUint32 writeCount = object.Length();
|
||||
rv = mOut->Write(object.get(), writeCount, &wroteCount);
|
||||
NS_ENSURE_TRUE(writeCount == wroteCount, NS_ERROR_FAILURE);
|
||||
} else if ((intLit = do_QueryInterface(aObject)) != nsnull) {
|
||||
PRInt32 value;
|
||||
intLit->GetValue(&value);
|
||||
nsPrintfCString
|
||||
object(128,
|
||||
"\"%i\"^^<http://www.w3.org/2001/XMLSchema#integer> ",
|
||||
value);
|
||||
PRUint32 writeCount = object.Length();
|
||||
rv = mOut->Write(object.get(), writeCount, &wroteCount);
|
||||
NS_ENSURE_TRUE(writeCount == wroteCount, NS_ERROR_FAILURE);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return mOut->Write(".\n", 2, &wroteCount);
|
||||
}
|
||||
|
||||
class rdfTriplesSerializer : public rdfISerializer
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_RDFISERIALIZER
|
||||
|
||||
rdfTriplesSerializer();
|
||||
|
||||
private:
|
||||
~rdfTriplesSerializer();
|
||||
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewTriplesSerializer(rdfISerializer** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aResult = new rdfTriplesSerializer();
|
||||
if (! *aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(rdfTriplesSerializer, rdfISerializer)
|
||||
|
||||
rdfTriplesSerializer::rdfTriplesSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
rdfTriplesSerializer::~rdfTriplesSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
rdfTriplesSerializer::Serialize(rdfIDataSource *aDataSource,
|
||||
nsIOutputStream *aOut)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIBufferedOutputStream> bufout =
|
||||
do_CreateInstance(NS_BUFFEREDOUTPUTSTREAM_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = bufout->Init(aOut, 1024);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<rdfITripleVisitor> tv = new TriplesVisitor(bufout);
|
||||
NS_ENSURE_TRUE(tv, NS_ERROR_OUT_OF_MEMORY);
|
||||
return aDataSource->VisitAllTriples(tv);
|
||||
}
|
@ -105,4 +105,8 @@
|
||||
#define NS_RDFXMLPARSER_CID \
|
||||
{ 0xa4048e94, 0x1dd1, 0x11b2, { 0xa6, 0x76, 0x8a, 0x06, 0xc0, 0x86, 0xcc, 0x7d } }
|
||||
|
||||
// {0a5cd734-eb65-4d14-88a0-9f0bb2aba206}
|
||||
#define NS_RDFNTRIPLES_SERIALIZER_CID \
|
||||
{ 0x0a5cd734, 0xeb65, 0x4d14, { 0x88, 0xa0, 0x9f, 0x0b, 0xb2, 0xab, 0xa2, 0x06 } }
|
||||
|
||||
#endif // nsRDFCID_h__
|
||||
|
@ -57,6 +57,8 @@
|
||||
#include "nsRDFXMLParser.h"
|
||||
#include "nsRDFXMLSerializer.h"
|
||||
|
||||
#include "rdfISerializer.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Functions used to create new instances of a given object by the
|
||||
@ -101,6 +103,36 @@ MAKE_CTOR(RDFContainerUtils,RDFContainerUtils,RDFContainerUtils)
|
||||
MAKE_CTOR(RDFContentSink,RDFContentSink,RDFContentSink)
|
||||
MAKE_CTOR(RDFDefaultResource,DefaultResource,RDFResource)
|
||||
|
||||
#define MAKE_RDF_CTOR(_func,_new,_ifname) \
|
||||
static NS_IMETHODIMP \
|
||||
CreateNew##_func(nsISupports* aOuter, REFNSIID aIID, void **aResult) \
|
||||
{ \
|
||||
if (!aResult) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
if (aOuter) { \
|
||||
*aResult = nsnull; \
|
||||
return NS_ERROR_NO_AGGREGATION; \
|
||||
} \
|
||||
rdfI##_ifname* inst; \
|
||||
nsresult rv = NS_New##_new(&inst); \
|
||||
if (NS_FAILED(rv)) { \
|
||||
*aResult = nsnull; \
|
||||
return rv; \
|
||||
} \
|
||||
rv = inst->QueryInterface(aIID, aResult); \
|
||||
if (NS_FAILED(rv)) { \
|
||||
*aResult = nsnull; \
|
||||
} \
|
||||
NS_RELEASE(inst); /* get rid of extra refcnt */ \
|
||||
return rv; \
|
||||
}
|
||||
|
||||
extern nsresult
|
||||
NS_NewTriplesSerializer(rdfISerializer** aResult);
|
||||
|
||||
MAKE_RDF_CTOR(TriplesSerializer, TriplesSerializer, Serializer)
|
||||
|
||||
// The list of components we register
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{ // register our build-in datasources:
|
||||
@ -175,6 +207,12 @@ static const nsModuleComponentInfo components[] =
|
||||
nsRDFXMLSerializer::Create
|
||||
},
|
||||
|
||||
{ "RDF/NTriples Serializer",
|
||||
NS_RDFNTRIPLES_SERIALIZER_CID,
|
||||
NS_RDF_SERIALIZER "ntriples",
|
||||
CreateNewTriplesSerializer
|
||||
},
|
||||
|
||||
// XXX move this to XPFE at some point.
|
||||
{ "Local Store", NS_LOCALSTORE_CID,
|
||||
NS_LOCALSTORE_CONTRACTID, NS_NewLocalStore },
|
||||
|
@ -42,7 +42,7 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = rdfcat rdfpoll
|
||||
DIRS = rdfcat rdfpoll triplescat
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
66
rdf/tests/triplescat/Makefile.in
Normal file
66
rdf/tests/triplescat/Makefile.in
Normal file
@ -0,0 +1,66 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Axel Hecht <axel@pike.org>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
PROGRAM = triplescat$(BIN_SUFFIX)
|
||||
CPPSRCS = triplescat.cpp
|
||||
REQUIRES = xpcom \
|
||||
rdf \
|
||||
necko \
|
||||
string \
|
||||
$(NULL)
|
||||
|
||||
LIBS = \
|
||||
$(LIBS_DIR) \
|
||||
$(XPCOM_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
MAPFILE=triplescat.map
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
CXXFLAGS += $(MOZ_TOOLKIT_REGISTRY_CFLAGS)
|
199
rdf/tests/triplescat/triplescat.cpp
Normal file
199
rdf/tests/triplescat/triplescat.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
* Chase Tingley <tingley@sundell.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* A simple test program that reads in RDF/XML into an in-memory data
|
||||
* source, then serializes NTriples format back to stdout (or none).
|
||||
*
|
||||
* The program takes a single parameter: the URL from which to read,
|
||||
* plus an optional parameter -q
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsCOMPtr.h"
|
||||
//#include "nsString.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIRDFRemoteDataSource.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIRDFXMLSource.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "plevent.h"
|
||||
#include "plstr.h"
|
||||
#include "prio.h"
|
||||
#include "prthread.h"
|
||||
|
||||
#include "rdf.h"
|
||||
#include "rdfIDataSource.h"
|
||||
#include "rdfITripleVisitor.h"
|
||||
#include "rdfISerializer.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Blatantly stolen from netwerk/test/
|
||||
#define RETURN_IF_FAILED(rv, step) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (NS_FAILED(rv)) { \
|
||||
printf(">>> %s failed: rv=%x\n", step, rv); \
|
||||
return rv;\
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConsoleOutputStreamImpl : public nsIOutputStream
|
||||
{
|
||||
public:
|
||||
ConsoleOutputStreamImpl(void) {}
|
||||
virtual ~ConsoleOutputStreamImpl(void) {}
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIBaseStream interface
|
||||
NS_IMETHOD Close(void) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIOutputStream interface
|
||||
NS_IMETHOD Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount) {
|
||||
PR_Write(PR_GetSpecialFD(PR_StandardOutput), aBuf, aCount);
|
||||
*aWriteCount = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval) {
|
||||
NS_NOTREACHED("WriteFrom");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval) {
|
||||
NS_NOTREACHED("WriteSegments");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
IsNonBlocking(PRBool *aNonBlocking) {
|
||||
NS_NOTREACHED("IsNonBlocking");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHOD Flush(void) {
|
||||
PR_Sync(PR_GetSpecialFD(PR_StandardOutput));
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ConsoleOutputStreamImpl, nsIOutputStream)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s <url>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
NS_InitXPCOM2(nsnull, nsnull, nsnull);
|
||||
|
||||
// Get netlib off the floor...
|
||||
nsCOMPtr<nsIEventQueueService> theEventQueueService =
|
||||
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
RETURN_IF_FAILED(rv, "EventQueueService");
|
||||
|
||||
nsIEventQueue* eq = nsnull;
|
||||
rv = theEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, &eq);
|
||||
RETURN_IF_FAILED(rv, "GetThreadEventQueue");
|
||||
|
||||
// Create a stream data source and initialize it on argv[1], which
|
||||
// is hopefully a "file:" URL.
|
||||
nsCOMPtr<nsIRDFDataSource> ds =
|
||||
do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource",
|
||||
&rv);
|
||||
RETURN_IF_FAILED(rv, "RDF/XML datasource creation");
|
||||
|
||||
nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds, &rv);
|
||||
RETURN_IF_FAILED(rv, "QI to nsIRDFRemoteDataSource");
|
||||
|
||||
rv = remote->Init(argv[1]);
|
||||
RETURN_IF_FAILED(rv, "datasource initialization");
|
||||
|
||||
// Okay, this should load the XML file...
|
||||
rv = remote->Refresh(PR_FALSE);
|
||||
RETURN_IF_FAILED(rv, "datasource refresh");
|
||||
|
||||
// Pump events until the load is finished
|
||||
PRBool done = PR_FALSE;
|
||||
while (!done) {
|
||||
eq->ProcessPendingEvents();
|
||||
remote->GetLoaded(&done);
|
||||
}
|
||||
|
||||
nsCOMPtr<rdfIDataSource> rdfds = do_QueryInterface(ds, &rv);
|
||||
RETURN_IF_FAILED(rv, "QI to rdIDataSource");
|
||||
{
|
||||
nsCOMPtr<nsIOutputStream> out = new ConsoleOutputStreamImpl();
|
||||
nsCOMPtr<rdfISerializer> ser =
|
||||
do_CreateInstance(NS_RDF_SERIALIZER "ntriples", &rv);
|
||||
RETURN_IF_FAILED(rv, "Creation of NTriples Serializer");
|
||||
rv = ser->Serialize(rdfds, out);
|
||||
RETURN_IF_FAILED(rv, "Serialization to NTriples");
|
||||
out->Close();
|
||||
}
|
||||
|
||||
theEventQueueService->DestroyThreadEventQueue();
|
||||
|
||||
return NS_OK;
|
||||
}
|
Loading…
Reference in New Issue
Block a user