New cursor interfaces.

This commit is contained in:
waterson%netscape.com 1998-12-21 23:56:31 +00:00
parent 761f39f1d3
commit 2dece61441
11 changed files with 971 additions and 443 deletions

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@ -20,36 +20,145 @@
#define nsIRDFCursor_h__
#include "nsISupports.h"
#include "prtypes.h"
class nsIRDFDataSource;
class nsIRDFNode;
/**
* A simple cursor that enumerates nodes
*/
class nsIRDFCursor : public nsISupports {
public:
/**
* Determine whether the cursor has more elements.
* @return NS_OK unless a catastrophic error occurs.
*/
NS_IMETHOD HasMoreElements(PRBool* result /* out */) = 0;
/**
* Fetch then next element, and possibly the truth value of the arc
* that leads to the element.
*
* @param next A pointer to receive the next <tt>nsIRDFNode</tt> object.
* @param tv A pointer to a boolean variable to receive the truth value
* of the arc that leads to the element. You pass <tt>nsnull</tt> if
* you don't care to know.
* @return NS_ERROR_UNEXPECTED if the cursor is empty; otherwise, NS_OK
* unless a catastrophic error occurs.
*/
NS_IMETHOD GetNext(nsIRDFNode** next /* out */,
PRBool* tv /* out */) = 0;
};
class nsIRDFResource;
// 1c2abdb0-4cef-11d2-bc16-00805f912fe7
#define NS_IRDFCURSOR_IID \
{ 0x1c2abdb0, 0x4cef, 0x11d2, { 0xbc, 0x16, 0x00, 0x80, 0x5f, 0x91, 0x2f, 0xe7 } }
/**
* An abstract base interface that is the basis for all RDF cursors.
*/
class nsIRDFCursor : public nsISupports {
public:
/**
* Advance the cursor to the next element.
* @return NS_ERROR_UNEXPECTED if the cursor has reached the end
* and there are no more elements to enumerate; otherwise, NS_OK
* unless a catastrophic error occurs.
*/
NS_IMETHOD Advance(void) = 0;
};
// {1ED57100-9904-11d2-8EBA-00805F29F370}
#define NS_IRDFASSERTIONCURSOR_IID \
{ 0x1ed57100, 0x9904, 0x11d2, { 0x8e, 0xba, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
/**
* A cursor that enumerates assertions
* @seealso nsIRDFDataSource::GetTargetS(), nsIRDFDataSource::GetSources()
*/
class nsIRDFAssertionCursor : public nsIRDFCursor {
public:
/**
* Retrieve the data source in which the assertion actually
* lives.
* XXX Is it dangerous to be exposing naked data sources like this?
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource) = 0;
/**
* Retrieve the assertion's subject resource.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetSubject(nsIRDFResource** aSubject) = 0;
/**
* Retrieve the assertion's predicate resource.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate) = 0;
/**
* Retrieve the assertion's object node.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetObject(nsIRDFNode** aObject) = 0;
/**
* Retrieve the assertion's truth value.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetTruthValue(PRBool* aTruthValue) = 0;
};
// {1ED57101-9904-11d2-8EBA-00805F29F370}
#define NS_IRDFARCSOUTCURSOR_IID \
{ 0x1ed57101, 0x9904, 0x11d2, { 0x8e, 0xba, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
/**
* A cursor that enumerates the outbound arcs from a resource node.
* @seealso nsIRDFDataSource::ArcsOut()
*/
class nsIRDFArcsOutCursor : public nsIRDFCursor {
public:
/**
* Retrieve the data source in which the arc is stored.
* XXX Is it dangerous to be exposing naked data sources like this?
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource) = 0;
/**
* Retrieve the "subject" node from which the arcs originate.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetSubject(nsIRDFResource** aSubject) = 0;
/**
* Retrieve the predicate label of the arc.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate) = 0;
/**
* Retrieve the truth value of the arc.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetTruthValue(PRBool* aTruthValue) = 0;
};
// {1ED57102-9904-11d2-8EBA-00805F29F370}
#define NS_IRDFARCSINCURSOR_IID \
{ 0x1ed57102, 0x9904, 0x11d2, { 0x8e, 0xba, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
/**
* A cursor that enumerates the inbound arcs to a node.
* @seealso nsIRDFDataSource::ArcsIn()
*/
class nsIRDFArcsInCursor : public nsIRDFCursor {
public:
/**
* Retrieve the data source in which the arc is stored.
* XXX Is it dangerous to be exposing naked data sources like this?
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource) = 0;
/**
* Retrieve the "object" node in which the arc terminates.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetObject(nsIRDFNode** aObject) = 0;
/**
* Retrieve the predicate label of the arc
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate) = 0;
/**
* Retrieve the truth value of the arc.
* @return NS_OK, unless a catastrophic error occurs.
*/
NS_IMETHOD GetTruthValue(PRBool* aTruthValue) = 0;
};
#endif /* nsIRDFCursor_h__ */

View File

@ -25,7 +25,9 @@
#define NS_IRDFDATASOURCE_IID \
{ 0xf78da58, 0x8321, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
class nsIRDFCursor;
class nsIRDFAssertionCursor;
class nsIRDFArcsInCursor;
class nsIRDFArcsOutCursor;
class nsIRDFDataBase;
class nsIRDFNode;
class nsIRDFObserver;
@ -71,7 +73,7 @@ public:
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources /* out */) = 0;
nsIRDFAssertionCursor** sources /* out */) = 0;
/**
* Find a child of that is related to the source by the given arc
@ -96,7 +98,7 @@ public:
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets /* out */) = 0;
nsIRDFAssertionCursor** targets /* out */) = 0;
/**
* Add an assertion to the graph.
@ -144,7 +146,7 @@ public:
* possible empty) nsIRDFCursor object.
*/
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels /* out */) = 0;
nsIRDFArcsInCursor** labels /* out */) = 0;
/**
* Get a cursor to iterate over all the arcs that originate in
@ -155,7 +157,7 @@ public:
* possible empty) nsIRDFCursor object.
*/
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels /* out */) = 0;
nsIRDFArcsOutCursor** labels /* out */) = 0;
/**
* Request that a data source write it's contents out to

View File

@ -496,7 +496,7 @@ public:
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources) {
nsIRDFAssertionCursor** sources) {
return mInner->GetSources(property, target, tv, sources);
}
@ -510,7 +510,7 @@ public:
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets) {
nsIRDFAssertionCursor** targets) {
return mInner->GetTargets(source, property, tv, targets);
}
@ -544,12 +544,12 @@ public:
}
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels) {
nsIRDFArcsInCursor** labels) {
return mInner->ArcLabelsIn(node, labels);
}
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels) {
nsIRDFArcsOutCursor** labels) {
return mInner->ArcLabelsOut(source, labels);
}

View File

@ -52,8 +52,11 @@
////////////////////////////////////////////////////////////////////////
static NS_DEFINE_IID(kIRDFResourceManagerIID, NS_IRDFRESOURCEMANAGER_IID);
static NS_DEFINE_IID(kIRDFAssertionCursorIID, NS_IRDFASSERTIONCURSOR_IID);
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
static NS_DEFINE_IID(kIRDFResourceManagerIID, NS_IRDFRESOURCEMANAGER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kRDFResourceManagerCID, NS_RDFRESOURCEMANAGER_CID);
@ -66,7 +69,7 @@ DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, nextVal); // ad hoc way to make contain
////////////////////////////////////////////////////////////////////////
class ContainerCursorImpl : public nsIRDFCursor {
class ContainerCursorImpl : public nsIRDFAssertionCursor {
private:
nsIRDFResourceManager* mResourceMgr;
nsIRDFDataSource* mDataSource;
@ -74,25 +77,25 @@ private:
nsIRDFNode* mNext;
PRInt32 mCounter;
void SkipToNext(void);
public:
ContainerCursorImpl(nsIRDFDataSource* ds, nsIRDFResource* container);
virtual ~ContainerCursorImpl(void);
NS_DECL_ISUPPORTS
NS_IMETHOD HasMoreElements(PRBool* result);
NS_IMETHOD GetNext(nsIRDFNode** next, PRBool* tv);
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aResource);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetObject(nsIRDFNode** aObject);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
};
ContainerCursorImpl::ContainerCursorImpl(nsIRDFDataSource* ds,
nsIRDFResource* container)
: mDataSource(ds), mContainer(container), mNext(nsnull), mCounter(1)
{
NS_ASSERTION(ds != nsnull, "null ptr");
NS_ASSERTION(container != nsnull, "null ptr");
NS_INIT_REFCNT();
NS_IF_ADDREF(mDataSource);
NS_IF_ADDREF(mContainer);
@ -105,7 +108,6 @@ ContainerCursorImpl::ContainerCursorImpl(nsIRDFDataSource* ds,
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to acquire resource manager");
NS_ASSERTION(rdf_IsContainer(mResourceMgr, mDataSource, container), "not a container");
SkipToNext();
}
@ -120,52 +122,38 @@ ContainerCursorImpl::~ContainerCursorImpl(void)
NS_IF_RELEASE(mDataSource);
}
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
NS_IMPL_ISUPPORTS(ContainerCursorImpl, kIRDFCursorIID);
NS_IMPL_ADDREF(ContainerCursorImpl);
NS_IMPL_RELEASE(ContainerCursorImpl);
NS_IMETHODIMP
ContainerCursorImpl::HasMoreElements(PRBool* result)
{
NS_IMETHODIMP_(nsresult)
ContainerCursorImpl::QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
*result = (mNext != nsnull);
return NS_OK;
if (iid.Equals(kIRDFAssertionCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFAssertionCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
ContainerCursorImpl::GetNext(nsIRDFNode** next, PRBool* tv)
ContainerCursorImpl::Advance(void)
{
if (!next)
return NS_ERROR_NULL_POINTER;
if (! mNext)
return NS_ERROR_UNEXPECTED;
*next = mNext; // no need to addref, SkipToNext() did it
if (tv) *tv = PR_TRUE;
SkipToNext();
return NS_OK;
}
void
ContainerCursorImpl::SkipToNext(void)
{
if (!mDataSource || !mContainer)
return;
nsresult rv;
mNext = nsnull;
// release the last value that we were holding
NS_IF_RELEASE(mNext);
nsIRDFResource* RDF_nextVal = nsnull;
nsIRDFNode* nextNode = nsnull;
nsIRDFLiteral* nextVal = nsnull;
const PRUnichar* s;
nsAutoString next;
const PRUnichar* p;
nsAutoString s;
PRInt32 last;
PRInt32 err;
@ -179,23 +167,23 @@ ContainerCursorImpl::SkipToNext(void)
if (NS_FAILED(rv = nextNode->QueryInterface(kIRDFLiteralIID, (void**) &nextVal)))
goto done;
if (NS_FAILED(rv = nextVal->GetValue(&s)))
if (NS_FAILED(rv = nextVal->GetValue(&p)))
goto done;
next = s;
last = next.ToInteger(&err);
s = p;
last = s.ToInteger(&err);
if (NS_FAILED(err))
goto done;
while (mCounter < last) {
next = kRDFNameSpaceURI;
next.Append("_");
next.Append(mCounter, 10);
// initialize rv to the case where mCounter has advanced past the
// last element
rv = NS_ERROR_UNEXPECTED;
while (mCounter < last) {
nsIRDFResource* ordinalProperty = nsnull;
if (NS_FAILED(rv = mResourceMgr->GetUnicodeResource(next, &ordinalProperty)))
if (NS_FAILED(rv = GetPredicate(&ordinalProperty)))
break;
rv = mDataSource->GetTarget(mContainer, ordinalProperty, PR_TRUE, &mNext);
NS_IF_RELEASE(ordinalProperty);
@ -213,6 +201,76 @@ done:
NS_IF_RELEASE(nextNode);
NS_IF_RELEASE(nextVal);
NS_IF_RELEASE(RDF_nextVal);
return rv;
}
NS_IMETHODIMP
ContainerCursorImpl::GetDataSource(nsIRDFDataSource** aDataSource)
{
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
NS_ADDREF(mDataSource);
*aDataSource = mDataSource;
return NS_OK;
}
NS_IMETHODIMP
ContainerCursorImpl::GetSubject(nsIRDFResource** aSubject)
{
NS_PRECONDITION(aSubject != nsnull, "null ptr");
if (! aSubject)
return NS_ERROR_NULL_POINTER;
NS_ADDREF(mContainer);
*aSubject = mContainer;
return NS_OK;
}
NS_IMETHODIMP
ContainerCursorImpl::GetPredicate(nsIRDFResource** aPredicate)
{
NS_PRECONDITION(aPredicate != nsnull, "null ptr");
nsAutoString s(kRDFNameSpaceURI);
s.Append("_");
s.Append(mCounter, 10);
// this'll AddRef(), null check, etc.
return mResourceMgr->GetUnicodeResource(s, aPredicate);
}
NS_IMETHODIMP
ContainerCursorImpl::GetObject(nsIRDFNode** aObject)
{
NS_PRECONDITION(aObject != nsnull, "null ptr");
if (! aObject)
return NS_ERROR_NULL_POINTER;
if (! mNext)
return NS_ERROR_UNEXPECTED;
NS_ADDREF(mNext);
*aObject = mNext;
return NS_OK;
}
NS_IMETHODIMP
ContainerCursorImpl::GetTruthValue(PRBool* aTruthValue)
{
NS_PRECONDITION(aTruthValue != nsnull, "null ptr");
if (! aTruthValue)
return NS_ERROR_NULL_POINTER;
*aTruthValue = PR_TRUE;
return NS_OK;
}
@ -221,9 +279,16 @@ done:
nsresult
NS_NewContainerCursor(nsIRDFDataSource* ds,
nsIRDFResource* container,
nsIRDFCursor** cursor)
nsIRDFAssertionCursor** cursor)
{
nsIRDFCursor* result = new ContainerCursorImpl(ds, container);
NS_PRECONDITION(ds != nsnull, "null ptr");
NS_PRECONDITION(container != nsnull, "null ptr");
NS_PRECONDITION(cursor != nsnull, "null ptr");
if (!ds || !container || !cursor)
return NS_ERROR_NULL_POINTER;
ContainerCursorImpl* result = new ContainerCursorImpl(ds, container);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -19,84 +19,198 @@
#include "nscore.h"
#include "nsIRDFCursor.h"
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIRDFArcsInCursorIID, NS_IRDFARCSINCURSOR_IID);
static NS_DEFINE_IID(kIRDFArcsOutCursorIID, NS_IRDFARCSOUTCURSOR_IID);
static NS_DEFINE_IID(kIRDFAssertionCursorIID, NS_IRDFASSERTIONCURSOR_IID);
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
class EmptyCursorImpl : public nsIRDFCursor {
////////////////////////////////////////////////////////////////////////
class EmptyAssertionCursorImpl : public nsIRDFAssertionCursor
{
public:
EmptyCursorImpl(void);
virtual ~EmptyCursorImpl(void) {};
EmptyAssertionCursorImpl(void) {};
virtual ~EmptyAssertionCursorImpl(void) {};
// nsISupports
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_IMETHOD QueryInterface(REFNSIID iid, void** result);
NS_IMETHOD_(nsrefcnt) AddRef(void) {
return 2;
}
NS_IMETHOD_(nsrefcnt) Release(void) {
return 1;
}
NS_IMETHOD QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFAssertionCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFAssertionCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
// nsIRDFCursor
NS_IMETHOD HasMoreElements(PRBool* result);
NS_IMETHOD GetNext(nsIRDFNode** next, PRBool* tv);
NS_IMETHOD Advance(void) {
return NS_ERROR_UNEXPECTED;
}
// nsIRDFAssertionCursor
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetSubject(nsIRDFResource** aResource) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetObject(nsIRDFNode** aObject) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetTruthValue(PRBool* aTruthValue) {
return NS_ERROR_UNEXPECTED;
}
};
EmptyCursorImpl::EmptyCursorImpl(void)
nsresult
NS_NewEmptyRDFAssertionCursor(nsIRDFAssertionCursor** result)
{
}
NS_IMETHODIMP_(nsrefcnt)
EmptyCursorImpl::AddRef(void)
{
return 2;
}
NS_IMETHODIMP_(nsrefcnt)
EmptyCursorImpl::Release(void)
{
return 1;
}
NS_IMETHODIMP
EmptyCursorImpl::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
EmptyCursorImpl::HasMoreElements(PRBool* result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = PR_FALSE;
static EmptyAssertionCursorImpl gEmptyAssertionCursor;
*result = &gEmptyAssertionCursor;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
EmptyCursorImpl::GetNext(nsIRDFNode** next, PRBool* tv)
class EmptyArcsOutCursorImpl : public nsIRDFArcsOutCursor
{
if (! next)
return NS_ERROR_NULL_POINTER;
public:
EmptyArcsOutCursorImpl(void) {};
virtual ~EmptyArcsOutCursorImpl(void) {};
*next = nsnull;
return NS_ERROR_UNEXPECTED;
}
// nsISupports
NS_IMETHOD_(nsrefcnt) AddRef(void) {
return 2;
}
NS_IMETHOD_(nsrefcnt) Release(void) {
return 1;
}
NS_IMETHOD QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFArcsOutCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFArcsOutCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
// nsIRDFCursor
NS_IMETHOD Advance(void) {
return NS_ERROR_UNEXPECTED;
}
// nsIRDFArcsOutCursor
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetSubject(nsIRDFResource** aResource) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetTruthValue(PRBool* aTruthValue) {
return NS_ERROR_UNEXPECTED;
}
};
nsresult
NS_NewEmptyRDFCursor(nsIRDFCursor** result)
NS_NewEmptyRDFArcsOutCursor(nsIRDFArcsOutCursor** result)
{
static EmptyCursorImpl gEmptyCursor;
*result = &gEmptyCursor;
static EmptyArcsOutCursorImpl gEmptyArcsOutCursor;
*result = &gEmptyArcsOutCursor;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
class EmptyArcsInCursorImpl : public nsIRDFArcsInCursor
{
public:
EmptyArcsInCursorImpl(void) {};
virtual ~EmptyArcsInCursorImpl(void) {};
// nsISupports
NS_IMETHOD_(nsrefcnt) AddRef(void) {
return 2;
}
NS_IMETHOD_(nsrefcnt) Release(void) {
return 1;
}
NS_IMETHOD QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFArcsInCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFArcsInCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
// nsIRDFCursor
NS_IMETHOD Advance(void) {
return NS_ERROR_UNEXPECTED;
}
// nsIRDFArcsInCursor
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetObject(nsIRDFNode** aNode) {
return NS_ERROR_UNEXPECTED;
}
NS_IMETHOD GetTruthValue(PRBool* aTruthValue) {
return NS_ERROR_UNEXPECTED;
}
};
nsresult
NS_NewEmptyRDFArcsInCursor(nsIRDFArcsInCursor** result)
{
static EmptyArcsInCursorImpl gEmptyArcsInCursor;
*result = &gEmptyArcsInCursor;
return NS_OK;
}

View File

@ -103,7 +103,7 @@ public:
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources);
nsIRDFAssertionCursor** sources);
NS_IMETHOD GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
@ -113,7 +113,7 @@ public:
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets);
nsIRDFAssertionCursor** targets);
NS_IMETHOD Assert(nsIRDFResource* source,
nsIRDFResource* property,
@ -135,10 +135,10 @@ public:
NS_IMETHOD RemoveObserver(nsIRDFObserver* n);
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels);
nsIRDFArcsInCursor** labels);
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels);
nsIRDFArcsOutCursor** labels);
NS_IMETHOD Flush();
};
@ -214,12 +214,6 @@ class NodeImpl {
protected:
nsIRDFNode* mNode;
/** Maps an nsIRDFNode* property to a property list. Lazily instantiated */
PLHashTable* mProperties;
inline PropertyListElement*
FindPropertyValue(nsIRDFResource* property, nsIRDFNode* value, PRBool tv);
// hash table routines
static void * PR_CALLBACK
AllocTable(void *pool, PRSize size);
@ -237,6 +231,12 @@ protected:
static const PRInt32 kPropertyTableSize;
/** Maps an nsIRDFNode* property to a property list. Lazily instantiated */
PLHashTable* mProperties;
inline PropertyListElement*
FindPropertyValue(nsIRDFResource* property, nsIRDFNode* value, PRBool tv);
public:
NodeImpl(nsIRDFNode* node);
@ -250,8 +250,8 @@ public:
void AddProperty(nsIRDFResource* property, nsIRDFNode* value, PRBool tv);
void RemoveProperty(nsIRDFResource* property, nsIRDFNode* value);
nsIRDFNode* GetProperty(nsIRDFResource* property, PRBool tv);
nsIRDFCursor* GetProperties(nsIRDFResource* property, PRBool tv);
nsIRDFCursor* GetArcLabelsOut(void);
nsIRDFAssertionCursor* GetProperties(nsIRDFDataSource* ds, nsIRDFResource* property, PRBool tv);
nsIRDFArcsOutCursor* GetArcsOut(nsIRDFDataSource* ds);
void Dump(const char* resource);
};
@ -267,122 +267,192 @@ const PRInt32 NodeImpl::kPropertyTableSize = 7;
////////////////////////////////////////////////////////////////////////
// PropertyCursorImpl
class PropertyCursorImpl : public nsIRDFCursor {
// XXX This could really get screwed up if the graph mutates under the
// cursor. Problem is, the NodeImpl isn't refcounted.
class PropertyCursorImpl : public nsIRDFAssertionCursor {
private:
PropertyListElement* mFirst;
PropertyListElement* mNext;
PRBool mTruthValueToMatch;
nsIRDFDataSource* mDataSource;
nsIRDFResource* mSubject;
nsIRDFResource* mPredicate;
PRBool mTruthValue;
public:
PropertyCursorImpl(PropertyListElement* first, PRBool truthValue);
PropertyCursorImpl(PropertyListElement* first,
nsIRDFDataSource* ds,
nsIRDFResource* subject,
nsIRDFResource* predicate,
PRBool tv);
virtual ~PropertyCursorImpl(void);
NS_DECL_ISUPPORTS
NS_IMETHOD HasMoreElements(PRBool* result);
NS_IMETHOD GetNext(nsIRDFNode** next, PRBool* tv);
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aResource);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetObject(nsIRDFNode** aObject);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
};
PropertyCursorImpl::PropertyCursorImpl(PropertyListElement* first, PRBool truthValueToMatch)
PropertyCursorImpl::PropertyCursorImpl(PropertyListElement* first,
nsIRDFDataSource* ds,
nsIRDFResource* subject,
nsIRDFResource* predicate,
PRBool tv)
: mFirst(first),
mNext(first),
mTruthValueToMatch(truthValueToMatch)
mDataSource(ds),
mSubject(subject),
mPredicate(predicate),
mTruthValue(tv)
{
NS_INIT_REFCNT();
while (1) {
if (mNext->GetTruthValue() == mTruthValueToMatch)
break;
if (mNext == mFirst) {
mNext = nsnull; // wrapped all the way back to the start
break;
}
mNext = mNext->GetNext();
}
NS_ADDREF(mDataSource);
NS_ADDREF(mSubject);
NS_ADDREF(mPredicate);
}
PropertyCursorImpl::~PropertyCursorImpl(void)
{
NS_RELEASE(mPredicate);
NS_RELEASE(mSubject);
NS_RELEASE(mDataSource);
}
NS_IMPL_ISUPPORTS(PropertyCursorImpl, kIRDFCursorIID);
NS_IMETHODIMP
PropertyCursorImpl::HasMoreElements(PRBool* result)
PropertyCursorImpl::Advance(void)
{
*result = (mNext != nsnull);
if (! mNext) {
mNext = mFirst;
}
else {
mNext = mNext->GetNext();
}
while (1) {
if (mNext == mFirst)
return NS_ERROR_UNEXPECTED;
if (mNext->GetTruthValue() == mTruthValue)
return NS_OK;
mNext = mNext->GetNext();
}
}
NS_IMETHODIMP
PropertyCursorImpl::GetDataSource(nsIRDFDataSource** aDataSource)
{
NS_ADDREF(mDataSource);
*aDataSource = mDataSource;
return NS_OK;
}
NS_IMETHODIMP
PropertyCursorImpl::GetNext(nsIRDFNode** next, PRBool* tv)
PropertyCursorImpl::GetSubject(nsIRDFResource** aSubject)
{
if (! next || ! tv)
return NS_ERROR_NULL_POINTER;
if (! mNext)
return NS_ERROR_UNEXPECTED;
*next = mNext->GetValue();
if (tv) *tv = mNext->GetTruthValue();
mNext = mNext->GetNext(); // advance past the current node
while (1) {
if (mNext == mFirst) {
mNext = nsnull; // wrapped all the way back to the start
break;
}
if (mNext->GetTruthValue() == mTruthValueToMatch)
break;
mNext = mNext->GetNext();
}
NS_ADDREF(mSubject);
*aSubject = mSubject;
return NS_OK;
}
NS_IMETHODIMP
PropertyCursorImpl::GetPredicate(nsIRDFResource** aPredicate)
{
NS_ADDREF(mPredicate);
*aPredicate = mPredicate;
return NS_OK;
}
NS_IMETHODIMP
PropertyCursorImpl::GetObject(nsIRDFNode** aObject)
{
nsIRDFNode* result = mNext->GetValue();
NS_ADDREF(result);
*aObject = result;
return NS_OK;
}
NS_IMETHODIMP
PropertyCursorImpl::GetTruthValue(PRBool* aTruthValue)
{
*aTruthValue = mTruthValue;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// ArcCursorImpl
// ArcsOutCursorImpl
class ArcCursorImpl : public nsIRDFCursor {
class ArcsOutCursorImpl : public nsIRDFArcsOutCursor {
private:
nsIRDFDataSource* mDataSource;
nsIRDFResource* mSubject;
nsISupportsArray* mProperties;
nsIRDFResource* mCurrent;
static PRIntn Enumerator(PLHashEntry* he, PRIntn index, void* closure);
public:
ArcCursorImpl(PLHashTable* properties);
virtual ~ArcCursorImpl(void);
ArcsOutCursorImpl(nsIRDFDataSource* ds,
nsIRDFResource* subject,
PLHashTable* properties);
virtual ~ArcsOutCursorImpl(void);
NS_DECL_ISUPPORTS
NS_IMETHOD HasMoreElements(PRBool* result);
NS_IMETHOD GetNext(nsIRDFNode** next, PRBool* tv);
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aSubject);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
};
ArcCursorImpl::ArcCursorImpl(PLHashTable* properties)
ArcsOutCursorImpl::ArcsOutCursorImpl(nsIRDFDataSource* ds,
nsIRDFResource* subject,
PLHashTable* properties)
: mDataSource(ds),
mSubject(subject),
mCurrent(nsnull)
{
NS_INIT_REFCNT();
NS_ADDREF(mDataSource);
NS_ADDREF(mSubject);
// XXX this is pretty wasteful
if (NS_SUCCEEDED(NS_NewISupportsArray(&mProperties)))
PL_HashTableEnumerateEntries(properties, Enumerator, mProperties);
}
ArcCursorImpl::~ArcCursorImpl(void)
ArcsOutCursorImpl::~ArcsOutCursorImpl(void)
{
NS_IF_RELEASE(mCurrent);
NS_IF_RELEASE(mProperties);
NS_RELEASE(mSubject);
NS_RELEASE(mDataSource);
}
NS_IMPL_ISUPPORTS(ArcCursorImpl, kIRDFCursorIID);
NS_IMPL_ISUPPORTS(ArcsOutCursorImpl, kIRDFCursorIID);
PRBool
ArcCursorImpl::Enumerator(PLHashEntry* he, PRIntn index, void* closure)
ArcsOutCursorImpl::Enumerator(PLHashEntry* he, PRIntn index, void* closure)
{
nsISupportsArray* properties = NS_STATIC_CAST(nsISupportsArray*, closure);
nsIRDFResource* property = NS_CONST_CAST(nsIRDFResource*, NS_STATIC_CAST(const nsIRDFResource*, he->key));
@ -391,39 +461,53 @@ ArcCursorImpl::Enumerator(PLHashEntry* he, PRIntn index, void* closure)
}
NS_IMETHODIMP
ArcCursorImpl::HasMoreElements(PRBool* result)
ArcsOutCursorImpl::Advance(void)
{
if (! result)
return NS_ERROR_NULL_POINTER;
if (! mProperties || ! mProperties->Count())
return NS_ERROR_UNEXPECTED;
*result = (mProperties && mProperties->Count() > 0);
PRInt32 index = mProperties->Count() - 1;
if (index < 0)
return NS_ERROR_UNEXPECTED;
NS_IF_RELEASE(mCurrent);
// this'll AddRef()...
mCurrent = NS_STATIC_CAST(nsIRDFResource*, mProperties->ElementAt(index));
mProperties->RemoveElementAt(index);
return NS_OK;
}
NS_IMETHODIMP
ArcCursorImpl::GetNext(nsIRDFNode** next, PRBool* tv)
ArcsOutCursorImpl::GetDataSource(nsIRDFDataSource** aDataSource)
{
if (! next)
return NS_ERROR_NULL_POINTER;
NS_ADDREF(mDataSource);
*aDataSource = mDataSource;
return NS_OK;
}
if (! mProperties || ! mProperties->Count())
return NS_ERROR_UNEXPECTED;
NS_IMETHODIMP
ArcsOutCursorImpl::GetSubject(nsIRDFResource** aSubject)
{
NS_ADDREF(mSubject);
*aSubject = mSubject;
return NS_OK;
}
PRInt32 index = mProperties->Count() - 1;
nsISupports* obj = mProperties->ElementAt(index);
NS_IMETHODIMP
ArcsOutCursorImpl::GetPredicate(nsIRDFResource** aPredicate)
{
NS_ADDREF(mCurrent);
*aPredicate = mCurrent;
return NS_OK;
}
PR_ASSERT(obj);
if (obj) {
nsIRDFNode* result;
obj->QueryInterface(kIRDFNodeIID, (void**) &result); // this'll AddRef()
obj->Release();
*next = result;
if (tv) *tv = PR_TRUE;
}
mProperties->RemoveElementAt(index);
NS_IMETHODIMP
ArcsOutCursorImpl::GetTruthValue(PRBool* aTruthValue)
{
*aTruthValue = PR_TRUE; // XXX
return NS_OK;
}
@ -576,8 +660,8 @@ NodeImpl::RemoveProperty(nsIRDFResource* property, nsIRDFNode* value)
}
nsIRDFCursor*
NodeImpl::GetProperties(nsIRDFResource* property, PRBool tv)
nsIRDFAssertionCursor*
NodeImpl::GetProperties(nsIRDFDataSource* ds, nsIRDFResource* property, PRBool tv)
{
if (! mProperties)
return nsnull;
@ -585,20 +669,37 @@ NodeImpl::GetProperties(nsIRDFResource* property, PRBool tv)
PropertyListElement* head
= NS_STATIC_CAST(PropertyListElement*, PL_HashTableLookup(mProperties, property));
nsIRDFCursor* result;
nsIRDFAssertionCursor* result = nsnull;
if (head) {
result = new PropertyCursorImpl(head, tv);
} else {
NS_NewEmptyRDFCursor(&result);
nsIRDFResource* resource;
if (NS_SUCCEEDED(mNode->QueryInterface(kIRDFResourceIID, (void**) &resource))) {
result = new PropertyCursorImpl(head, ds, resource, property, tv);
NS_RELEASE(resource);
}
}
if (! result)
NS_NewEmptyRDFAssertionCursor(&result);
return result;
}
nsIRDFCursor*
NodeImpl::GetArcLabelsOut(void)
nsIRDFArcsOutCursor*
NodeImpl::GetArcsOut(nsIRDFDataSource* ds)
{
return new ArcCursorImpl(mProperties);
nsIRDFArcsOutCursor* result;
nsIRDFResource* resource;
if (NS_SUCCEEDED(mNode->QueryInterface(kIRDFResourceIID, (void**) &resource))) {
result = new ArcsOutCursorImpl(ds, resource, mProperties);
NS_RELEASE(resource);
}
if (! result)
NS_NewEmptyRDFArcsOutCursor(&result);
return result;
}
@ -745,7 +846,7 @@ NS_IMETHODIMP
MemoryDataSourceImpl::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources)
nsIRDFAssertionCursor** sources)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED; // XXX
@ -779,19 +880,17 @@ NS_IMETHODIMP
MemoryDataSourceImpl::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets)
nsIRDFAssertionCursor** targets)
{
NS_PRECONDITION(source && property && targets, "null ptr");
if (!source || !property || !targets)
return NS_ERROR_NULL_POINTER;
NS_NewEmptyRDFCursor(targets); // reasonable default
NodeImpl *u;
if (! (u = NS_STATIC_CAST(NodeImpl*, PL_HashTableLookup(mNodes, source))))
return NS_OK;
if (! (*targets = u->GetProperties(property, tv)))
if (! (*targets = u->GetProperties(this, property, tv)))
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*targets);
@ -892,7 +991,7 @@ MemoryDataSourceImpl::RemoveObserver(nsIRDFObserver* n)
NS_IMETHODIMP
MemoryDataSourceImpl::ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels)
nsIRDFArcsInCursor** labels)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
@ -900,19 +999,17 @@ MemoryDataSourceImpl::ArcLabelsIn(nsIRDFNode* node,
NS_IMETHODIMP
MemoryDataSourceImpl::ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels)
nsIRDFArcsOutCursor** labels)
{
NS_PRECONDITION(source && labels, "null ptr");
if (!source || !labels)
return NS_ERROR_NULL_POINTER;
NS_NewEmptyRDFCursor(labels); // reasonable default
NodeImpl *u;
if (! (u = NS_STATIC_CAST(NodeImpl*, PL_HashTableLookup(mNodes, source))))
return NS_OK;
if (! (*labels = u->GetArcLabelsOut()))
if (! (*labels = u->GetArcsOut(this)))
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*labels);

View File

@ -1093,8 +1093,7 @@ nsRDFDocument::CreateChildren(nsIRDFContent* element)
nsIRDFResource* resource = nsnull;
nsIRDFCursor* properties = nsnull;
PRBool moreProperties;
nsIRDFArcsOutCursor* properties = nsnull;
if (NS_FAILED(rv = element->GetResource(resource)))
goto done;
@ -1103,20 +1102,12 @@ nsRDFDocument::CreateChildren(nsIRDFContent* element)
if (NS_FAILED(rv = mDB->ArcLabelsOut(resource, &properties)))
goto done;
while (NS_SUCCEEDED(rv = properties->HasMoreElements(&moreProperties)) && moreProperties) {
nsIRDFNode* node = nsnull;
while (NS_SUCCEEDED(rv = properties->Advance())) {
nsIRDFResource* property = nsnull;
if (NS_FAILED(rv = properties->GetNext(&node, nsnull)))
if (NS_FAILED(rv = properties->GetPredicate(&property)))
break;
if (NS_FAILED(rv = node->QueryInterface(kIRDFResourceIID, (void**) &property))) {
NS_RELEASE(node);
break;
}
NS_RELEASE(node);
const char* s;
if (NS_FAILED(rv = property->GetValue(&s))) {
NS_RELEASE(property);
@ -1127,31 +1118,27 @@ nsRDFDocument::CreateChildren(nsIRDFContent* element)
// Create a second cursor that'll enumerate all of the values
// for all of the arcs.
nsIRDFCursor* values;
if (NS_FAILED(rv = mDB->GetTargets(resource, property, PR_TRUE, &values))) {
nsIRDFAssertionCursor* assertions;
if (NS_FAILED(rv = mDB->GetTargets(resource, property, PR_TRUE, &assertions))) {
NS_RELEASE(property);
break;
}
PRBool moreValues;
while (NS_SUCCEEDED(rv = values->HasMoreElements(&moreValues)) && moreValues) {
nsIRDFNode* valueNode;
PRBool tv;
if (NS_SUCCEEDED(rv = values->GetNext(&valueNode, &tv))) {
if (tv) {
// At this point, the specific nsRDFDocument
// implementations will create an appropriate child
// element (or elements).
rv = AddChild(element, property, valueNode);
}
NS_RELEASE(valueNode);
while (NS_SUCCEEDED(rv = assertions->Advance())) {
nsIRDFNode* value;
if (NS_SUCCEEDED(rv = assertions->GetObject(&value))) {
// At this point, the specific nsRDFDocument
// implementations will create an appropriate child
// element (or elements).
rv = AddChild(element, property, value);
NS_RELEASE(value);
}
if (NS_FAILED(rv))
break;
}
NS_RELEASE(values);
NS_RELEASE(assertions);
NS_RELEASE(property);
if (NS_FAILED(rv))

View File

@ -352,8 +352,7 @@ RDFTreeDocumentImpl::AddColumnsFromContainer(nsIContent* parent,
nsIRDFResource* NC_Column = nsnull;
nsIRDFResource* NC_Title = nsnull;
nsIRDFCursor* cursor = nsnull;
PRBool moreElements;
nsIRDFAssertionCursor* cursor = nsnull;
if (NS_FAILED(rv = mResourceMgr->GetResource(kURINC_Column, &NC_Column)))
goto done;
@ -364,9 +363,9 @@ RDFTreeDocumentImpl::AddColumnsFromContainer(nsIContent* parent,
if (NS_FAILED(rv = NS_NewContainerCursor(mDB, columns, &cursor)))
goto done;
while (NS_SUCCEEDED(rv = cursor->HasMoreElements(&moreElements)) && moreElements) {
while (NS_SUCCEEDED(rv = cursor->Advance())) {
nsIRDFNode* columnNode;
if (NS_SUCCEEDED(rv = cursor->GetNext(&columnNode, nsnull))) {
if (NS_SUCCEEDED(rv = cursor->GetObject(&columnNode))) {
nsIRDFResource* column;
if (NS_SUCCEEDED(rv = columnNode->QueryInterface(kIRDFResourceIID, (void**) &column))) {
// XXX okay, error recovery leaves a bit to be desired here...
@ -450,32 +449,24 @@ RDFTreeDocumentImpl::AddColumnsFromMultiAttributes(nsIContent* parent,
if (NS_FAILED(rv = EnsureChildElement(parent, kColumnsTag, columnsElement)))
return rv;
PRBool moreElements;
nsIRDFCursor* cursor = nsnull;
nsIRDFArcsOutCursor* cursor = nsnull;
if (NS_FAILED(rv = mDB->ArcLabelsOut(columns, &cursor)))
goto done;
while (NS_SUCCEEDED(rv = cursor->HasMoreElements(&moreElements)) && moreElements) {
nsIRDFNode* propertyNode;
if (NS_SUCCEEDED(rv = cursor->GetNext(&propertyNode, nsnull))) {
nsIRDFResource* property;
if (NS_SUCCEEDED(rv = propertyNode->QueryInterface(kIRDFResourceIID,
(void**) &property))) {
nsIRDFNode* titleNode;
if (NS_SUCCEEDED(rv = mDB->GetTarget(columns, property, PR_TRUE, &titleNode))) {
nsIRDFLiteral* title;
if (NS_SUCCEEDED(rv = titleNode->QueryInterface(kIRDFLiteralIID,
(void**) &title))) {
rv = AddColumn(columnsElement, property, title);
NS_RELEASE(title);
}
NS_RELEASE(titleNode);
while (NS_SUCCEEDED(rv = cursor->Advance())) {
nsIRDFResource* property;
if (NS_SUCCEEDED(rv = cursor->GetPredicate(&property))) {
nsIRDFNode* titleNode;
if (NS_SUCCEEDED(rv = mDB->GetTarget(columns, property, PR_TRUE, &titleNode))) {
nsIRDFLiteral* title;
if (NS_SUCCEEDED(rv = titleNode->QueryInterface(kIRDFLiteralIID,
(void**) &title))) {
rv = AddColumn(columnsElement, property, title);
NS_RELEASE(title);
}
NS_RELEASE(property);
NS_RELEASE(titleNode);
}
NS_RELEASE(propertyNode);
NS_RELEASE(property);
}
if (NS_FAILED(rv))

View File

@ -49,43 +49,52 @@
*/
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
static NS_DEFINE_IID(kIRDFDataBaseIID, NS_IRDFDATABASE_IID);
static NS_DEFINE_IID(kIRDFDataSourceIID, NS_IRDFDATASOURCE_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIRDFArcsInCursorIID, NS_IRDFARCSINCURSOR_IID);
static NS_DEFINE_IID(kIRDFArcsOutCursorIID, NS_IRDFARCSOUTCURSOR_IID);
static NS_DEFINE_IID(kIRDFAssertionCursorIID, NS_IRDFASSERTIONCURSOR_IID);
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
static NS_DEFINE_IID(kIRDFDataBaseIID, NS_IRDFDATABASE_IID);
static NS_DEFINE_IID(kIRDFDataSourceIID, NS_IRDFDATASOURCE_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kRDFBookmarkDataSourceCID, NS_RDFBOOKMARKDATASOURCE_CID);
////////////////////////////////////////////////////////////////////////
// MultiCursor
//
// This class encapsulates all of the behavior that is necessary to
// stripe a cursor across several different data sources, including
// checks to determine whether an negation in an "earlier" data
// source masks an assertion in a "later" data source.
//
class MultiCursor : public nsIRDFCursor {
class MultiCursor {
private:
nsIRDFDataSource* mDataSource0;
nsIRDFDataSource* mDataSource0;
nsIRDFDataSource** mDataSources;
nsIRDFCursor* mCurrentCursor;
nsIRDFNode* mNextResult;
PRBool mNextTruthValue;
PRInt32 mNextDataSource;
PRInt32 mCount;
nsIRDFCursor* mCurrentCursor;
nsIRDFNode* mNextResult;
PRBool mNextTruthValue;
PRInt32 mNextDataSource;
PRInt32 mCount;
public:
MultiCursor(nsVoidArray& dataSources);
virtual ~MultiCursor(void);
NS_DECL_ISUPPORTS
NS_IMETHOD HasMoreElements(PRBool* result);
NS_IMETHOD GetNext(nsIRDFNode** next, PRBool* tv);
NS_IMETHOD AdvanceImpl(void);
virtual nsresult
GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result) = 0;
virtual nsresult
HasNegation(nsIRDFDataSource* ds0,
nsIRDFNode* nodeToTest,
PRBool tv,
PRBool* result) = 0;
IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result) = 0;
nsIRDFCursor*
GetCurrentCursor(void) {
return mCurrentCursor;
}
};
@ -97,8 +106,6 @@ MultiCursor::MultiCursor(nsVoidArray& dataSources)
mCount(0),
mNextDataSource(0)
{
NS_INIT_REFCNT();
mCount = dataSources.Count();
mDataSources = new nsIRDFDataSource*[mCount];
@ -126,25 +133,10 @@ MultiCursor::~MultiCursor(void)
NS_IF_RELEASE(mDataSource0);
}
NS_IMPL_ISUPPORTS(MultiCursor, kIRDFCursorIID);
NS_IMETHODIMP
MultiCursor::HasMoreElements(PRBool* result)
MultiCursor::AdvanceImpl(void)
{
nsresult rv;
if (! mDataSources)
return NS_ERROR_OUT_OF_MEMORY;
// If we've already queued up a next target, then yep, there are
// more elements.
if (mNextResult) {
*result = PR_TRUE;
return NS_OK;
}
// Otherwise, we'll need to find a next target, switching cursors
// if necessary.
*result = PR_FALSE;
while (mNextDataSource < mCount) {
if (! mCurrentCursor) {
@ -157,29 +149,22 @@ MultiCursor::HasMoreElements(PRBool* result)
}
do {
if (NS_FAILED(rv = mCurrentCursor->HasMoreElements(result)))
return rv;
// Is the current cursor depleted?
if (!*result)
// If we can't advance the current cursor, then it's
// depleted. Break out of this loop and advance to the
// next cursor.
if (NS_FAILED(rv = mCurrentCursor->Advance()))
break;
// Even if the current cursor has more elements, we still
// need to check that the current element isn't masked by
// the "main" data source.
// "Peek" ahead and pull out the next target.
if (NS_FAILED(mCurrentCursor->GetNext(&mNextResult, &mNextTruthValue)))
return rv;
// See if data source zero has the negation
// XXX rvg --- this needs to be fixed so that we look at all the prior
// data sources for negations
PRBool hasNegation;
if (NS_FAILED(rv = HasNegation(mDataSource0,
mNextResult,
mNextTruthValue,
&hasNegation)))
if (NS_FAILED(rv = IsCurrentNegatedBy(mDataSource0,
&hasNegation)))
return rv;
// if not, we're done
@ -188,7 +173,6 @@ MultiCursor::HasMoreElements(PRBool* result)
// Otherwise, we found the negation in data source
// zero. Gotta keep lookin'...
NS_RELEASE(mNextResult);
} while (1);
NS_RELEASE(mCurrentCursor);
@ -197,57 +181,53 @@ MultiCursor::HasMoreElements(PRBool* result)
}
// if we get here, there aren't any elements left.
return NS_OK;
}
NS_IMETHODIMP
MultiCursor::GetNext(nsIRDFNode** next, PRBool* tv)
{
nsresult rv;
PRBool hasMore;
if (NS_FAILED(rv = HasMoreElements(&hasMore)))
return rv;
if (! hasMore)
return NS_ERROR_UNEXPECTED;
*next = mNextResult; // no need to AddRef() again...
if (tv) *tv = mNextTruthValue;
mNextResult = nsnull; // ...because we'll just "transfer ownership".
return NS_OK;
return NS_ERROR_UNEXPECTED;
}
////////////////////////////////////////////////////////////////////////
// dbNodeCursorImpl
class dbNodeCursorImpl : public MultiCursor {
// SimpleDBAssertionCursorImpl
//
// An assertion cursor implementation for the simple db.
//
class SimpleDBAssertionCursorImpl : public MultiCursor,
public nsIRDFAssertionCursor
{
private:
nsIRDFResource* mSource;
nsIRDFResource* mProperty;
PRBool mTruthValue;
public:
dbNodeCursorImpl(nsVoidArray& dataSources,
SimpleDBAssertionCursorImpl(nsVoidArray& dataSources,
nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv);
virtual ~dbNodeCursorImpl();
virtual ~SimpleDBAssertionCursorImpl();
// MultiCursor protocol methods
virtual nsresult
GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result);
virtual nsresult
HasNegation(nsIRDFDataSource* ds0,
nsIRDFNode* nodeToTest,
PRBool tv,
PRBool* result);
IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFAssertionCursor interface
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aResource);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetObject(nsIRDFNode** aObject);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
};
dbNodeCursorImpl::dbNodeCursorImpl(nsVoidArray& dataSources,
SimpleDBAssertionCursorImpl::SimpleDBAssertionCursorImpl(nsVoidArray& dataSources,
nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv)
@ -261,50 +241,165 @@ dbNodeCursorImpl::dbNodeCursorImpl(nsVoidArray& dataSources,
}
dbNodeCursorImpl::~dbNodeCursorImpl(void)
SimpleDBAssertionCursorImpl::~SimpleDBAssertionCursorImpl(void)
{
NS_IF_RELEASE(mProperty);
NS_IF_RELEASE(mSource);
}
NS_IMPL_ADDREF(SimpleDBAssertionCursorImpl);
NS_IMPL_RELEASE(SimpleDBAssertionCursorImpl);
NS_IMETHODIMP_(nsresult)
SimpleDBAssertionCursorImpl::QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFAssertionCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFAssertionCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
dbNodeCursorImpl::GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result)
SimpleDBAssertionCursorImpl::GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result)
{
return ds->GetTargets(mSource, mProperty, mTruthValue, result);
return ds->GetTargets(mSource, mProperty, mTruthValue,
(nsIRDFAssertionCursor**) result);
}
nsresult
dbNodeCursorImpl::HasNegation(nsIRDFDataSource* ds0,
nsIRDFNode* target,
PRBool tv,
PRBool* result)
SimpleDBAssertionCursorImpl::IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result)
{
return ds0->HasAssertion(mSource, mProperty, target, !tv, result);
nsresult rv;
// No need to QueryInterface() b/c this is a closed system.
nsIRDFAssertionCursor* c =
(nsIRDFAssertionCursor*) GetCurrentCursor();
PRBool tv;
if (NS_FAILED(rv = c->GetTruthValue(&tv)))
return rv;
nsIRDFNode* object;
if (NS_FAILED(rv = c->GetObject(&object)))
return rv;
rv = ds0->HasAssertion(mSource, mProperty, object, !tv, result);
NS_RELEASE(object);
return rv;
}
NS_IMETHODIMP
SimpleDBAssertionCursorImpl::Advance(void)
{
return AdvanceImpl();
}
NS_IMETHODIMP
SimpleDBAssertionCursorImpl::GetDataSource(nsIRDFDataSource** aDataSource)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetDataSource(aDataSource);
}
NS_IMETHODIMP
SimpleDBAssertionCursorImpl::GetSubject(nsIRDFResource** aResource)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetSubject(aResource);
}
NS_IMETHODIMP
SimpleDBAssertionCursorImpl::GetPredicate(nsIRDFResource** aPredicate)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetPredicate(aPredicate);
}
NS_IMETHODIMP
SimpleDBAssertionCursorImpl::GetObject(nsIRDFNode** aObject)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetObject(aObject);
}
NS_IMETHODIMP
SimpleDBAssertionCursorImpl::GetTruthValue(PRBool* aTruthValue)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetTruthValue(aTruthValue);
}
////////////////////////////////////////////////////////////////////////
// dbArcCursorImpl
// SimpleDBArcsOutCursorImpl
class dbArcCursorImpl : public MultiCursor {
class SimpleDBArcsOutCursorImpl : public MultiCursor,
public nsIRDFArcsOutCursor
{
private:
nsIRDFResource* mSource;
public:
dbArcCursorImpl(nsVoidArray& dataSources, nsIRDFResource* source);
SimpleDBArcsOutCursorImpl(nsVoidArray& dataSources, nsIRDFResource* source);
virtual ~dbArcCursorImpl();
virtual ~SimpleDBArcsOutCursorImpl();
// MultiCursor protocol methods
virtual nsresult
GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result);
virtual nsresult
HasNegation(nsIRDFDataSource* ds0,
nsIRDFNode* nodeToTest,
PRBool tv,
PRBool* result);
IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFArcsOutCursor interface
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aSubject);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
};
dbArcCursorImpl::dbArcCursorImpl(nsVoidArray& dataSources,
SimpleDBArcsOutCursorImpl::SimpleDBArcsOutCursorImpl(nsVoidArray& dataSources,
nsIRDFResource* source)
: MultiCursor(dataSources),
mSource(source)
@ -313,27 +408,101 @@ dbArcCursorImpl::dbArcCursorImpl(nsVoidArray& dataSources,
}
dbArcCursorImpl::~dbArcCursorImpl(void)
SimpleDBArcsOutCursorImpl::~SimpleDBArcsOutCursorImpl(void)
{
NS_IF_RELEASE(mSource);
}
nsresult
dbArcCursorImpl::GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result)
SimpleDBArcsOutCursorImpl::GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result)
{
return ds->ArcLabelsOut(mSource, result);
return ds->ArcLabelsOut(mSource, (nsIRDFArcsOutCursor**) result);
}
nsresult
dbArcCursorImpl::HasNegation(nsIRDFDataSource* ds0,
nsIRDFNode* target,
PRBool tv,
PRBool* result)
SimpleDBArcsOutCursorImpl::IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result)
{
*result = PR_FALSE;
return NS_OK;
}
NS_IMPL_ADDREF(SimpleDBArcsOutCursorImpl);
NS_IMPL_RELEASE(SimpleDBArcsOutCursorImpl);
NS_IMETHODIMP_(nsresult)
SimpleDBArcsOutCursorImpl::QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFAssertionCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFArcsOutCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::Advance(void)
{
return AdvanceImpl();
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetDataSource(nsIRDFDataSource** aDataSource)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetDataSource(aDataSource);
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetSubject(nsIRDFResource** aSubject)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetSubject(aSubject);
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetPredicate(nsIRDFResource** aPredicate)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetPredicate(aPredicate);
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetTruthValue(PRBool* aTruthValue)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetTruthValue(aTruthValue);
}
////////////////////////////////////////////////////////////////////////
@ -363,7 +532,7 @@ public:
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources);
nsIRDFAssertionCursor** sources);
NS_IMETHOD GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
@ -373,7 +542,7 @@ public:
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets);
nsIRDFAssertionCursor** targets);
NS_IMETHOD Assert(nsIRDFResource* source,
nsIRDFResource* property,
@ -395,10 +564,10 @@ public:
NS_IMETHOD RemoveObserver(nsIRDFObserver* n);
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels);
nsIRDFArcsInCursor** labels);
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels);
nsIRDFArcsOutCursor** labels);
NS_IMETHOD Flush();
@ -413,19 +582,6 @@ public:
SimpleDataBaseImpl::SimpleDataBaseImpl(void)
{
NS_INIT_REFCNT();
#if 0
// Add standard data sources here.
// XXX this is so wrong.
nsIRDFDataSource* ds;
if (NS_SUCCEEDED(nsRepository::CreateInstance(kRDFBookmarkDataSourceCID,
nsnull,
kIRDFDataSourceIID,
(void**) &ds))) {
AddDataSource(ds);
NS_RELEASE(ds);
}
#endif
}
@ -504,7 +660,7 @@ NS_IMETHODIMP
SimpleDataBaseImpl::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources)
nsIRDFAssertionCursor** sources)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
@ -542,13 +698,13 @@ NS_IMETHODIMP
SimpleDataBaseImpl::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets)
nsIRDFAssertionCursor** targets)
{
if (! targets)
return NS_ERROR_NULL_POINTER;
nsIRDFCursor* result;
result = new dbNodeCursorImpl(mDataSources, source, property, tv);
nsIRDFAssertionCursor* result;
result = new SimpleDBAssertionCursorImpl(mDataSources, source, property, tv);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
@ -674,7 +830,7 @@ SimpleDataBaseImpl::RemoveObserver(nsIRDFObserver* n)
NS_IMETHODIMP
SimpleDataBaseImpl::ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels)
nsIRDFArcsInCursor** labels)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
@ -682,12 +838,12 @@ SimpleDataBaseImpl::ArcLabelsIn(nsIRDFNode* node,
NS_IMETHODIMP
SimpleDataBaseImpl::ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels)
nsIRDFArcsOutCursor** labels)
{
if (! labels)
return NS_ERROR_NULL_POINTER;
nsIRDFCursor* result = new dbArcCursorImpl(mDataSources, source);
nsIRDFArcsOutCursor* result = new SimpleDBArcsOutCursorImpl(mDataSources, source);
if (! result)
return NS_ERROR_NULL_POINTER;

View File

@ -27,6 +27,7 @@
#include "nsIParser.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFContentSink.h"
#include "nsIRDFCursor.h"
#include "nsIStreamListener.h"
#include "nsIURL.h"
#include "nsParserCIID.h"
@ -70,7 +71,7 @@ public:
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFCursor** sources) {
nsIRDFAssertionCursor** sources) {
return mInner->GetSources(property, target, tv, sources);
}
@ -84,7 +85,7 @@ public:
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFCursor** targets) {
nsIRDFAssertionCursor** targets) {
return mInner->GetTargets(source, property, tv, targets);
}
@ -118,12 +119,12 @@ public:
}
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsIRDFCursor** labels) {
nsIRDFArcsInCursor** labels) {
return mInner->ArcLabelsIn(node, labels);
}
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsIRDFCursor** labels) {
nsIRDFArcsOutCursor** labels) {
return mInner->ArcLabelsOut(source, labels);
}

View File

@ -150,7 +150,7 @@ rdf_ContainerAddElement(nsIRDFResourceManager* mgr,
nsresult
NS_NewContainerCursor(nsIRDFDataSource* ds,
nsIRDFResource* container,
nsIRDFCursor** cursor);
nsIRDFAssertionCursor** cursor);
/**
@ -158,7 +158,13 @@ NS_NewContainerCursor(nsIRDFDataSource* ds,
* return the same object.
*/
nsresult
NS_NewEmptyRDFCursor(nsIRDFCursor** result);
NS_NewEmptyRDFAssertionCursor(nsIRDFAssertionCursor** result);
nsresult
NS_NewEmptyRDFArcsInCursor(nsIRDFArcsInCursor** result);
nsresult
NS_NewEmptyRDFArcsOutCursor(nsIRDFArcsOutCursor** result);
// XXX need to move nsEmptyCursor stuff here.