Factor interfaces into individual .idl files. Add purge support and re-load support to RDF/XML datasource.

This commit is contained in:
waterson%netscape.com 1999-05-05 03:09:12 +00:00
parent fa278583c8
commit 8224e41a78
8 changed files with 576 additions and 548 deletions

View File

@ -1111,45 +1111,60 @@ CompositeDataSourceImpl::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSource
// need to add the observers of the CompositeDataSourceImpl to the new data source.
NS_IMETHODIMP
CompositeDataSourceImpl::AddDataSource(nsIRDFDataSource* source)
CompositeDataSourceImpl::AddDataSource(nsIRDFDataSource* aDataSource)
{
NS_ASSERTION(source != nsnull, "null ptr");
if (! source)
NS_ASSERTION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
mDataSources.InsertElementAt(source, 0);
source->AddObserver(this);
NS_ADDREF(source);
mDataSources.AppendElement(aDataSource);
aDataSource->AddObserver(this);
NS_ADDREF(aDataSource);
return NS_OK;
}
NS_IMETHODIMP
CompositeDataSourceImpl::RemoveDataSource(nsIRDFDataSource* source)
CompositeDataSourceImpl::RemoveDataSource(nsIRDFDataSource* aDataSource)
{
NS_ASSERTION(source != nsnull, "null ptr");
if (! source)
NS_ASSERTION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
if (mDataSources.IndexOf(source) >= 0) {
mDataSources.RemoveElement(source);
source->RemoveObserver(this);
NS_RELEASE(source);
if (mDataSources.IndexOf(aDataSource) >= 0) {
mDataSources.RemoveElement(aDataSource);
aDataSource->RemoveObserver(this);
NS_RELEASE(aDataSource);
}
return NS_OK;
}
NS_IMETHODIMP
CompositeDataSourceImpl::OnAssert(nsIRDFResource* subject,
nsIRDFResource* predicate,
nsIRDFNode* object)
CompositeDataSourceImpl::OnAssert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
// Make sure that the assertion isn't masked by another
// datasource.
//
// XXX We could make this more efficient if we knew _which_
// datasource actually served up the OnAssert(): we could use
// HasAssertionN() to only search datasources _before_ the
// datasource that coughed up the assertion.
nsresult rv;
PRBool hasAssertion;
rv = HasAssertion(aSource, aProperty, aTarget, PR_TRUE, &hasAssertion);
if (NS_FAILED(rv)) return rv;
if (! hasAssertion)
return NS_OK;
if (mObservers) {
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnAssert(subject, predicate, object);
obs->OnAssert(aSource, aProperty, aTarget);
// XXX ignore return value?
}
}
@ -1157,14 +1172,31 @@ CompositeDataSourceImpl::OnAssert(nsIRDFResource* subject,
}
NS_IMETHODIMP
CompositeDataSourceImpl::OnUnassert(nsIRDFResource* subject,
nsIRDFResource* predicate,
nsIRDFNode* object)
CompositeDataSourceImpl::OnUnassert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
// Make sure that the un-assertion doesn't just unmask the
// same assertion in a different datasource.
//
// XXX We could make this more efficient if we knew _which_
// datasource actually served up the OnAssert(): we could use
// HasAssertionN() to only search datasources _before_ the
// datasource that coughed up the assertion.
//
// XXX What if the unassertion
nsresult rv;
PRBool hasAssertion;
rv = HasAssertion(aSource, aProperty, aTarget, PR_TRUE, &hasAssertion);
if (NS_FAILED(rv)) return rv;
if (hasAssertion)
return NS_OK;
if (mObservers) {
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnUnassert(subject, predicate, object);
obs->OnUnassert(aSource, aProperty, aTarget);
// XXX ignore return value?
}
}

View File

@ -35,6 +35,7 @@
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsIRDFContainerUtils.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFNode.h"
#include "nsIRDFService.h"

View File

@ -39,8 +39,10 @@
#include "nscore.h"
#include "nsIOutputStream.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFLiteral.h"
#include "nsIRDFNode.h"
#include "nsIRDFObserver.h"
#include "nsIRDFPurgeableDataSource.h"
#include "nsIServiceManager.h"
#include "nsISupportsArray.h"
#include "nsAutoLock.h"
@ -69,15 +71,61 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
// This struct is used as the slot value in the forward and reverse
// arcs hash tables.
struct Assertion
class Assertion
{
nsIRDFResource* mSource;
nsIRDFResource* mProperty;
nsIRDFNode* mTarget;
PRBool mTruthValue;
public:
Assertion(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue);
~Assertion();
// public for now, because I'm too lazy to go thru and clean this up.
nsIRDFResource* mSource; // OWNER
nsIRDFResource* mProperty; // OWNER
nsIRDFNode* mTarget; // OWNER
Assertion* mNext;
Assertion* mInvNext;
PRBool mTruthValue;
// For nsIRDFPurgeableDataSource
void Mark() { mMarked = PR_TRUE; }
PRBool IsMarked() { return mMarked; }
void Unmark() { mMarked = PR_FALSE; }
private:
PRBool mMarked;
PRInt16 mRefCnt; // XXX not used yet: to be used for threadsafety
};
Assertion::Assertion(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue)
: mSource(aSource),
mProperty(aProperty),
mTarget(aTarget),
mNext(nsnull),
mInvNext(nsnull),
mTruthValue(aTruthValue),
mMarked(PR_FALSE),
mRefCnt(0)
{
NS_ADDREF(mSource);
NS_ADDREF(mProperty);
NS_ADDREF(mTarget);
}
Assertion::~Assertion()
{
NS_RELEASE(mSource);
NS_RELEASE(mProperty);
NS_RELEASE(mTarget);
}
////////////////////////////////////////////////////////////////////////
// Utility routines
@ -101,12 +149,12 @@ rdf_CompareNodes(const void* v1, const void* v2)
return (PRIntn) result;
}
////////////////////////////////////////////////////////////////////////
// InMemoryDataSource
class InMemoryResourceEnumeratorImpl;
class InMemoryDataSource : public nsIRDFDataSource
class InMemoryDataSource : public nsIRDFDataSource,
public nsIRDFPurgeableDataSource
{
protected:
char* mURL;
@ -213,12 +261,33 @@ public:
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments);
// nsIRDFPurgeableDataSource methods
NS_IMETHOD Mark(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue,
PRBool* aDidMark);
NS_IMETHOD Sweep();
protected:
static PRIntn SweepForwardArcsEntries(PLHashEntry* he, PRIntn index, void* arg);
public:
// Implemenatation methods
Assertion* GetForwardArcs(nsIRDFResource* u);
Assertion* GetReverseArcs(nsIRDFNode* v);
void SetForwardArcs(nsIRDFResource* u, Assertion* as);
void SetReverseArcs(nsIRDFNode* v, Assertion* as);
#ifdef PR_LOGGING
void
LogOperation(const char* aOperation,
nsIRDFResource* asource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue = PR_TRUE);
#endif
// This datasource's monitor object.
PRLock* mLock;
@ -510,19 +579,24 @@ NS_IMPL_RELEASE(InMemoryDataSource);
NS_IMETHODIMP
InMemoryDataSource::QueryInterface(REFNSIID iid, void** result)
{
NS_PRECONDITION(result != nsnull, "null ptr");
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kISupportsIID) ||
iid.Equals(nsIRDFDataSource::GetIID())) {
*result = NS_STATIC_CAST(nsIRDFDataSource*, this);
NS_ADDREF(this);
return NS_OK;
}
else if (iid.Equals(nsIRDFPurgeableDataSource::GetIID())) {
*result = NS_STATIC_CAST(nsIRDFPurgeableDataSource*, this);
}
else {
*result = nsnull;
return NS_NOINTERFACE;
}
NS_ADDREF(this);
return NS_OK;
}
InMemoryDataSource::InMemoryDataSource(void)
@ -589,10 +663,6 @@ InMemoryDataSource::DeleteForwardArcsEntry(PLHashEntry* he, PRIntn index, void*
while (as) {
Assertion* doomed = as;
as = as->mNext;
NS_RELEASE(doomed->mSource);
NS_RELEASE(doomed->mProperty);
NS_RELEASE(doomed->mTarget);
delete doomed;
}
return HT_ENUMERATE_NEXT;
@ -637,6 +707,59 @@ InMemoryDataSource::SetReverseArcs(nsIRDFNode* v, Assertion* as)
}
}
#ifdef PR_LOGGING
void
InMemoryDataSource::LogOperation(const char* aOperation,
nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue)
{
if (! PR_LOG_TEST(gLog, PR_LOG_ALWAYS))
return;
nsXPIDLCString uri;
aSource->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
("InMemoryDataSource(%s): %s", mURL, aOperation));
PR_LOG(gLog, PR_LOG_ALWAYS,
(" [(%p)%s]--", aSource, (const char*) uri));
aProperty->GetValue(getter_Copies(uri));
char tv = (aTruthValue ? '-' : '!');
PR_LOG(gLog, PR_LOG_ALWAYS,
(" --%c[(%p)%s]--", tv, aProperty, (const char*) uri));
nsCOMPtr<nsIRDFResource> resource;
nsCOMPtr<nsIRDFLiteral> literal;
if ((resource = do_QueryInterface(aTarget)) != nsnull) {
resource->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->[(%p)%s]", aTarget, (const char*) uri));
}
else if ((literal = do_QueryInterface(aTarget)) != nsnull) {
nsXPIDLString value;
literal->GetValue(getter_Copies(value));
nsAutoString valueStr(value);
char* valueCStr = valueStr.ToNewCString();
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->(\"%s\")\n", valueCStr));
delete[] valueCStr;
}
else {
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->(unknown-type)\n"));
}
}
#endif
NS_IMETHODIMP
InMemoryDataSource::Init(const char* uri)
{
@ -682,21 +805,12 @@ InMemoryDataSource::GetSource(nsIRDFResource* property,
NS_AUTOLOCK(mLock);
nsresult rv;
for (Assertion* as = GetReverseArcs(target); as != nsnull; as = as->mNext) {
PRBool eq;
if (NS_FAILED(rv = property->EqualsResource(as->mProperty, &eq)))
return rv;
if (! eq)
continue;
if (as->mTruthValue != tv)
continue;
*source = as->mSource;
NS_ADDREF(as->mSource);
return NS_OK;
if ((property == as->mProperty) && (as->mTruthValue == tv)) {
*source = as->mSource;
NS_ADDREF(as->mSource);
return NS_OK;
}
}
*source = nsnull;
return NS_RDF_NO_VALUE;
@ -722,21 +836,12 @@ InMemoryDataSource::GetTarget(nsIRDFResource* source,
NS_AUTOLOCK(mLock);
nsresult rv;
for (Assertion* as = GetForwardArcs(source); as != nsnull; as = as->mNext) {
PRBool eq;
if (NS_FAILED(rv = property->EqualsResource(as->mProperty, &eq)))
return rv;
if (! eq)
continue;
if (as->mTruthValue != tv)
continue;
*target = as->mTarget;
NS_ADDREF(as->mTarget);
return NS_OK;
if ((property == as->mProperty) && (as->mTruthValue == tv)) {
*target = as->mTarget;
NS_ADDREF(as->mTarget);
return NS_OK;
}
}
// If we get here, then there was no target with for the specified
@ -769,10 +874,7 @@ InMemoryDataSource::HasAssertion(nsIRDFResource* source,
nsresult rv;
for (Assertion* as = GetForwardArcs(source); as != nsnull; as = as->mNext) {
PRBool eq;
if (NS_FAILED(rv = property->EqualsResource(as->mProperty, &eq)))
return rv;
if (! eq)
if (property != as->mProperty)
continue;
if (NS_FAILED(rv = target->EqualsNode(as->mTarget, &eq)))
@ -868,43 +970,7 @@ InMemoryDataSource::SafeAssert(nsIRDFResource* source,
NS_AUTOLOCK(mLock);
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_ALWAYS)) {
nsXPIDLCString uri;
source->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
("InMemoryDataSource(%s):", mURL));
PR_LOG(gLog, PR_LOG_ALWAYS,
("ASSERT [(%p)%s]--", source, (const char*) uri));
property->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
(" --%c[(%p)%s]--", (tv ? '-' : '!'), property, (const char*) uri));
nsCOMPtr<nsIRDFResource> resource;
nsCOMPtr<nsIRDFLiteral> literal;
if ((resource = do_QueryInterface(target)) != nsnull) {
resource->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->[(%p)%s]", target, (const char*) uri));
}
else if ((literal = do_QueryInterface(target)) != nsnull) {
nsXPIDLString value;
literal->GetValue(getter_Copies(value));
nsAutoString valueStr(value);
char* valueCStr = valueStr.ToNewCString();
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->(\"%s\")\n", valueCStr));
delete[] valueCStr;
}
else {
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->(unknown-type)\n"));
}
}
LogOperation("ASSERT", source, property, target, tv);
#endif
nsresult rv;
@ -915,12 +981,8 @@ InMemoryDataSource::SafeAssert(nsIRDFResource* source,
// Walk to the end of the linked list.
// XXX shouldn't we just keep a pointer to the end, or insert at the front???
while (next) {
PRBool eq;
if (NS_FAILED(rv = property->EqualsResource(next->mProperty, &eq)))
return rv;
if (eq) {
if (property == next->mProperty) {
PRBool eq;
if (NS_FAILED(rv = target->EqualsNode(next->mTarget, &eq)))
return rv;
@ -936,23 +998,10 @@ InMemoryDataSource::SafeAssert(nsIRDFResource* source,
next = next->mNext;
}
as = new Assertion;
as = new Assertion(source, property, target, tv);
if (! as)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(source);
as->mSource = source;
NS_ADDREF(property);
as->mProperty = property;
NS_ADDREF(target);
as->mTarget = target;
as->mTruthValue = tv;
as->mNext = nsnull;
as->mInvNext = nsnull;
// Link it in to the "forward arcs" table
if (!prev) {
SetForwardArcs(source, as);
@ -1012,43 +1061,7 @@ InMemoryDataSource::SafeUnassert(nsIRDFResource* source,
NS_AUTOLOCK(mLock);
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_ALWAYS)) {
nsXPIDLCString uri;
source->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
("InMemoryDataSource(%s):", mURL));
PR_LOG(gLog, PR_LOG_ALWAYS,
("UNASSERT [(%p)%s]--", source, (const char*) uri));
property->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
(" ---[(%p)%s]--", property, (const char*) uri));
nsCOMPtr<nsIRDFResource> resource;
nsCOMPtr<nsIRDFLiteral> literal;
if ((resource = do_QueryInterface(target)) != nsnull) {
resource->GetValue(getter_Copies(uri));
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->[(%p)%s]", target, (const char*) uri));
}
else if ((literal = do_QueryInterface(target)) != nsnull) {
nsXPIDLString value;
literal->GetValue(getter_Copies(value));
nsAutoString valueStr(value);
char* valueCStr = valueStr.ToNewCString();
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->(\"%s\")\n", valueCStr));
delete[] valueCStr;
}
else {
PR_LOG(gLog, PR_LOG_ALWAYS,
(" -->(unknown-type)\n"));
}
}
LogOperation("UNASSERT", source, property, target);
#endif
nsresult rv;
@ -1057,12 +1070,8 @@ InMemoryDataSource::SafeUnassert(nsIRDFResource* source,
Assertion* as = nsnull;
while (next) {
PRBool eq;
if (NS_FAILED(rv = property->EqualsResource(next->mProperty, &eq)))
return rv;
if (eq) {
if (property == next->mProperty) {
PRBool eq;
if (NS_FAILED(rv = target->EqualsNode(next->mTarget, &eq)))
return rv;
@ -1111,9 +1120,6 @@ InMemoryDataSource::SafeUnassert(nsIRDFResource* source,
#endif
// Delete the assertion struct & release resources
NS_RELEASE(as->mSource);
NS_RELEASE(as->mProperty);
NS_RELEASE(as->mTarget);
delete as;
return NS_OK;
@ -1298,6 +1304,174 @@ InMemoryDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////
// nsIRDFPurgeableDataSource methods
NS_IMETHODIMP
InMemoryDataSource::Mark(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue,
PRBool* aDidMark)
{
NS_PRECONDITION(aSource != nsnull, "null ptr");
if (! aSource)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aProperty != nsnull, "null ptr");
if (! aProperty)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aTarget != nsnull, "null ptr");
if (! aTarget)
return NS_ERROR_NULL_POINTER;
NS_AUTOLOCK(mLock);
nsresult rv;
for (Assertion* as = GetForwardArcs(aSource); as != nsnull; as = as->mNext) {
PRBool eq;
if (aProperty != as->mProperty)
continue;
if (NS_FAILED(rv = aTarget->EqualsNode(as->mTarget, &eq)))
return rv;
if (! eq)
continue;
if (as->mTruthValue != aTruthValue)
continue;
// found it! so mark it.
as->Mark();
*aDidMark = PR_TRUE;
#ifdef PR_LOGGING
LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue);
#endif
return NS_OK;
}
// If we get here, we couldn't find the assertion
*aDidMark = PR_FALSE;
return NS_OK;
}
struct SweepInfo {
Assertion* mUnassertList;
PLHashTable* mReverseArcs;
};
NS_IMETHODIMP
InMemoryDataSource::Sweep()
{
SweepInfo info = { nsnull, mReverseArcs };
{
// Remove all the assertions while holding the lock, but don't notify anyone.
NS_AUTOLOCK(mLock);
PL_HashTableEnumerateEntries(mForwardArcs, SweepForwardArcsEntries, &info);
}
// Now we've left the autolock. Do the notification.
Assertion* as = info.mUnassertList;
while (as) {
#ifdef PR_LOGGING
LogOperation("SWEEP", as->mSource, as->mProperty, as->mTarget, as->mTruthValue);
#endif
if (mObservers) {
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnUnassert(as->mSource, as->mProperty, as->mTarget);
// XXX ignore return value?
}
}
Assertion* doomed = as;
as = as->mNext;
delete doomed;
}
return NS_OK;
}
PRIntn
InMemoryDataSource::SweepForwardArcsEntries(PLHashEntry* he, PRIntn index, void* arg)
{
SweepInfo* info = (SweepInfo*) arg;
Assertion* as = (Assertion*) he->value;
Assertion* prev = nsnull;
while (as) {
if (as->IsMarked()) {
prev = as;
as->Unmark();
as = as->mNext;
}
else {
// remove from the list of assertions in the datasource
Assertion* next = as->mNext;
if (prev) {
prev->mNext = next;
}
else {
// it's the first one. update the hashtable entry.
he->value = next;
}
// remove from the reverse arcs
PLHashEntry** hep =
PL_HashTableRawLookup(info->mReverseArcs,
(PLHashNumber) as->mTarget, // because we know we're using rdf_HashPointer()
as->mTarget);
Assertion* ras = (Assertion*) ((*hep)->value);
NS_ASSERTION(ras != nsnull, "no assertion in reverse arcs");
Assertion* rprev = nsnull;
while (ras) {
if (ras == as) {
if (rprev) {
rprev->mInvNext = ras->mInvNext;
}
else {
// it's the first one. update the hashtable entry.
(*hep)->value = ras->mInvNext;
}
as->mInvNext = nsnull; // for my sanity.
break;
}
rprev = ras;
ras = ras->mInvNext;
}
// Wow, it was the _only_ one. Unhash it.
if (! (*hep)->value)
PL_HashTableRawRemove(info->mReverseArcs, hep, *hep);
// add to the list of assertions to unassert
as->mNext = info->mUnassertList;
info->mUnassertList = as;
// Advance to the next assertion
as = next;
}
}
PRIntn result = HT_ENUMERATE_NEXT;
// if no more assertions exist for this resource, then unhash it.
if (! he->value)
result |= HT_ENUMERATE_REMOVE;
return result;
}
////////////////////////////////////////////////////////////////////////
nsresult NS_NewRDFInMemoryDataSource(nsIRDFDataSource** result);

View File

@ -25,6 +25,7 @@
#include "nsCOMPtr.h"
#include "nsIRDFContainer.h"
#include "nsIRDFContainerUtils.h"
#include "nsIRDFService.h"
#include "nsIServiceManager.h"
#include "nsRDFCID.h"

View File

@ -49,6 +49,7 @@
#include "nsINameSpace.h"
#include "nsINameSpaceManager.h"
#include "nsIRDFContainer.h"
#include "nsIRDFContainerUtils.h"
#include "nsIRDFContentSink.h"
#include "nsIRDFNode.h"
#include "nsIRDFService.h"
@ -243,8 +244,6 @@ protected:
nsIURL* mDocumentURL;
PRUint32 mGenSym; // for generating anonymous resources
PRBool mHaveSetRootResource;
};
PRInt32 RDFContentSinkImpl::gRefCnt = 0;
@ -276,8 +275,7 @@ RDFContentSinkImpl::RDFContentSinkImpl()
mText(nsnull),
mTextLength(0),
mTextSize(0),
mConstrainSize(PR_TRUE),
mHaveSetRootResource(PR_FALSE)
mConstrainSize(PR_TRUE)
{
NS_INIT_REFCNT();
@ -591,67 +589,11 @@ RDFContentSinkImpl::AddComment(const nsIParserNode& aNode)
NS_IMETHODIMP
RDFContentSinkImpl::AddProcessingInstruction(const nsIParserNode& aNode)
{
PR_LOG(gLog, PR_LOG_ALWAYS,
("rdfxml: ignoring processing instruction at line %d",
aNode.GetSourceLineNumber()));
static const char kStyleSheetPI[] = "<?xml-stylesheet";
static const char kCSSType[] = "text/css";
static const char kDataSourcePI[] = "<?rdf-datasource";
static const char kContentModelBuilderPI[] = "<?rdf-builder";
nsresult rv = NS_OK;
FlushText();
if (! mDataSource)
return NS_OK;
// XXX For now, we don't add the PI to the content model.
// We just check for a style sheet PI
const nsString& text = aNode.GetText();
// If it's a stylesheet PI...
if (0 == text.Find(kStyleSheetPI)) {
nsAutoString href;
if (NS_FAILED(rv = nsRDFParserUtils::GetQuotedAttributeValue(text, "href", href)))
return rv;
// If there was an error or there's no href, we can't do
// anything with this PI
if (! href.Length())
return NS_OK;
nsAutoString type;
if (NS_FAILED(rv = nsRDFParserUtils::GetQuotedAttributeValue(text, "type", type)))
return rv;
if (! type.Equals(kCSSType))
return NS_OK;
nsIURL* url = nsnull;
nsAutoString absURL;
nsAutoString emptyURL;
emptyURL.Truncate();
if (NS_FAILED(rv = NS_MakeAbsoluteURL(mDocumentURL, emptyURL, href, absURL)))
return rv;
if (NS_FAILED(rv = NS_NewURL(&url, absURL)))
return rv;
rv = mDataSource->AddCSSStyleSheetURL(url);
NS_RELEASE(url);
}
else if (0 == text.Find(kDataSourcePI)) {
nsAutoString href;
rv = nsRDFParserUtils::GetQuotedAttributeValue(text, "href", href);
if (NS_FAILED(rv) || (0 == href.Length()))
return rv;
char uri[256];
href.ToCString(uri, sizeof(uri));
rv = mDataSource->AddNamedDataSourceURI(uri);
}
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -1246,13 +1188,7 @@ RDFContentSinkImpl::OpenObject(const nsIParserNode& aNode)
AddProperties(aNode, rdfResource);
if (mDataSource && !mHaveSetRootResource) {
mHaveSetRootResource = PR_TRUE;
mDataSource->SetRootResource(rdfResource);
}
NS_RELEASE(rdfResource);
return NS_OK;
}

View File

@ -37,19 +37,36 @@ PRUnichar
nsRDFParserUtils::EntityToUnicode(const char* buf)
{
if ((buf[0] == 'g' || buf[0] == 'G') &&
(buf[1] == 't' || buf[1] == 'T'))
(buf[1] == 't' || buf[1] == 'T') &&
(buf[2] == '\0'))
return PRUnichar('>');
if ((buf[0] == 'l' || buf[0] == 'L') &&
(buf[1] == 't' || buf[1] == 'T'))
(buf[1] == 't' || buf[1] == 'T') &&
(buf[2] == '\0'))
return PRUnichar('<');
if ((buf[0] == 'a' || buf[0] == 'A') &&
(buf[1] == 'm' || buf[1] == 'M') &&
(buf[2] == 'p' || buf[2] == 'P'))
(buf[2] == 'p' || buf[2] == 'P') &&
(buf[3] == '\0'))
return PRUnichar('&');
NS_NOTYETIMPLEMENTED("this is a named entity that I can't handle...");
if ((buf[0] == 'a' || buf[0] == 'A') &&
(buf[1] == 'p' || buf[1] == 'P') &&
(buf[2] == 'o' || buf[2] == 'O') &&
(buf[3] == 's' || buf[3] == 'S') &&
(buf[4] == '\0'))
return PRUnichar('\'');
if ((buf[0] == 'q' || buf[0] == 'Q') &&
(buf[1] == 'u' || buf[1] == 'U') &&
(buf[2] == 'o' || buf[2] == 'O') &&
(buf[3] == 't' || buf[3] == 'T') &&
(buf[4] == '\0'))
return PRUnichar('"');
NS_NOTYETIMPLEMENTED("look this up in the declared-entity table");
return PRUnichar('?');
}

View File

@ -34,7 +34,6 @@
#include "nsIComponentManager.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFNode.h"
#include "nsIRDFResourceFactory.h"
#include "nsIRDFService.h"
#include "nsIRDFXMLDataSource.h"
#include "nsRDFCID.h"
@ -846,17 +845,20 @@ ServiceImpl::GetDataSource(const char* uri, nsIRDFDataSource** aDataSource)
{
// First, check the cache to see if we already have this
// datasource loaded and initialized.
nsIRDFDataSource* ds =
NS_STATIC_CAST(nsIRDFDataSource*, PL_HashTableLookup(mNamedDataSources, uri));
{
nsIRDFDataSource* cached =
NS_STATIC_CAST(nsIRDFDataSource*, PL_HashTableLookup(mNamedDataSources, uri));
if (ds) {
NS_ADDREF(ds);
*aDataSource = ds;
return NS_OK;
if (cached) {
NS_ADDREF(cached);
*aDataSource = cached;
return NS_OK;
}
}
// Nope. So go to the repository to try to create it.
nsresult rv;
nsCOMPtr<nsIRDFDataSource> ds;
nsAutoString rdfName(uri);
static const char kRDFPrefix[] = "rdf:";
PRInt32 pos = rdfName.Find(kRDFPrefix);
@ -881,9 +883,15 @@ ServiceImpl::GetDataSource(const char* uri, nsIRDFDataSource** aDataSource)
rv = nsComponentManager::CreateInstance(progID, nsnull,
nsIRDFDataSource::GetIID(),
(void**)&ds);
getter_AddRefs(ds));
if (progID != buf)
delete[] progID;
if (NS_FAILED(rv)) return rv;
rv = ds->Init(uri);
if (NS_FAILED(rv)) return rv;
}
else {
// Try to load this as an RDF/XML data source
@ -892,32 +900,24 @@ ServiceImpl::GetDataSource(const char* uri, nsIRDFDataSource** aDataSource)
nsIRDFDataSource::GetIID(),
(void**) &ds);
if (NS_FAILED(rv)) return rv;
rv = ds->Init(uri);
if (NS_FAILED(rv)) return rv;
// XXX hack for now: make sure that the data source is
// synchronously loaded. In the long run, we should factor out
// the "loading" from the "creating". See nsRDFXMLDataSource::Init().
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRDFXMLDataSource> rdfxmlDataSource(do_QueryInterface(ds));
NS_ASSERTION(rdfxmlDataSource, "not an RDF/XML data source!");
if (rdfxmlDataSource) {
rv = rdfxmlDataSource->SetSynchronous(PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to make RDF/XML data source synchronous");
}
}
nsCOMPtr<nsIRDFXMLDataSource> rdfxmlDataSource(do_QueryInterface(ds));
NS_ASSERTION(rdfxmlDataSource, "not an RDF/XML data source!");
if (! rdfxmlDataSource) return NS_ERROR_UNEXPECTED;
rv = rdfxmlDataSource->Open(PR_TRUE);
if (NS_FAILED(rv)) return rv;
}
if (NS_FAILED(rv)) {
// XXX only a warning, because the URI may have been ill-formed.
NS_WARNING("unable to create data source");
return rv;
}
rv = ds->Init(uri);
if (NS_FAILED(rv)) {
NS_RELEASE(ds);
NS_ERROR("unable to initialize data source");
return rv;
}
*aDataSource = ds;
NS_ADDREF(*aDataSource);
return NS_OK;
}

View File

@ -44,6 +44,7 @@
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsIDTD.h"
#include "nsIRDFPurgeableDataSource.h"
#include "nsIInputStream.h"
#include "nsINameSpaceManager.h"
#include "nsIOutputStream.h"
@ -124,7 +125,7 @@ public:
*aLength = mSize - mIndex;
return NS_OK;
}
NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount) {
PRUint32 readCount = 0;
while (mIndex < mSize && aCount > 0) {
@ -161,18 +162,13 @@ protected:
NameSpaceMap* Next;
};
nsIRDFDataSource* mInner;
PRBool mIsSynchronous; // true if the document should be loaded synchronously
nsIRDFDataSource* mInner; // OWNER
PRBool mIsWritable; // true if the document can be written back
PRBool mIsDirty; // true if the document should be written back
nsVoidArray mObservers;
char** mNamedDataSourceURIs;
PRInt32 mNumNamedDataSourceURIs;
nsIURL** mCSSStyleSheetURLs;
PRInt32 mNumCSSStyleSheetURLs;
nsIRDFResource* mRootResource;
PRBool mIsLoading; // true while the document is loading
nsVoidArray mObservers; // WEAK REFERENCES
PRBool mIsLoading; // true while the document is loading
NameSpaceMap* mNameSpaces;
nsCOMPtr<nsIURL> mURL;
// pseudo-constants
static PRInt32 gRefCnt;
@ -224,9 +220,9 @@ public:
return mInner->GetTargets(source, property, tv, targets);
}
NS_IMETHOD Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
NS_IMETHOD Assert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool tv);
NS_IMETHOD Unassert(nsIRDFResource* source,
@ -286,18 +282,13 @@ public:
}
// nsIRDFXMLDataSource interface
NS_IMETHOD SetSynchronous(PRBool aIsSynchronous);
NS_IMETHOD GetReadOnly(PRBool* aIsReadOnly);
NS_IMETHOD SetReadOnly(PRBool aIsReadOnly);
NS_IMETHOD Open(PRBool aBlocking);
NS_IMETHOD BeginLoad(void);
NS_IMETHOD Interrupt(void);
NS_IMETHOD Resume(void);
NS_IMETHOD EndLoad(void);
NS_IMETHOD SetRootResource(nsIRDFResource* aResource);
NS_IMETHOD GetRootResource(nsIRDFResource** aResource);
NS_IMETHOD AddCSSStyleSheetURL(nsIURL* aStyleSheetURL);
NS_IMETHOD GetCSSStyleSheetURLs(nsIURL*** aStyleSheetURLs, PRInt32* aCount);
NS_IMETHOD AddNamedDataSourceURI(const char* aNamedDataSourceURI);
NS_IMETHOD GetNamedDataSourceURIs(const char* const** aNamedDataSourceURIs, PRInt32* aCount);
NS_IMETHOD AddNameSpace(nsIAtom* aPrefix, const nsString& aURI);
NS_IMETHOD AddXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver);
NS_IMETHOD RemoveXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver);
@ -367,14 +358,8 @@ NS_NewRDFXMLDataSource(nsIRDFXMLDataSource** result)
RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void)
: mInner(nsnull),
mIsSynchronous(PR_FALSE),
mIsWritable(PR_TRUE),
mIsDirty(PR_FALSE),
mNamedDataSourceURIs(nsnull),
mNumNamedDataSourceURIs(0),
mCSSStyleSheetURLs(nsnull),
mNumCSSStyleSheetURLs(0),
mRootResource(nsnull),
mIsLoading(PR_FALSE),
mNameSpaces(nsnull)
{
@ -422,18 +407,6 @@ RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void)
Flush();
while (mNumNamedDataSourceURIs-- > 0) {
delete mNamedDataSourceURIs[mNumNamedDataSourceURIs];
}
delete mNamedDataSourceURIs;
while (mNumCSSStyleSheetURLs-- > 0) {
NS_RELEASE(mCSSStyleSheetURLs[mNumCSSStyleSheetURLs]);
}
delete mCSSStyleSheetURLs;
while (mNameSpaces) {
NameSpaceMap* doomed = mNameSpaces;
mNameSpaces = mNameSpaces->Next;
@ -442,7 +415,6 @@ RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void)
delete doomed;
}
NS_IF_RELEASE(mRootResource);
NS_RELEASE(mInner);
if (--gRefCnt == 0) {
@ -516,7 +488,7 @@ rdf_BlockingParse(nsIURL* aURL, nsIStreamListener* aConsumer)
break; // eof
proxy->SetBuffer(buf, readCount);
// XXX shouldn't netlib be doing this???
if (NS_FAILED(rv = aConsumer->OnDataAvailable(aURL, proxy, readCount)))
break;
@ -538,7 +510,6 @@ RDFXMLDataSourceImpl::Init(const char* uri)
{
static const char kFileURIPrefix[] = "file:";
static const char kResourceURIPrefix[] = "resource:";
nsAutoString utf8("UTF-8");
NS_PRECONDITION(mInner != nsnull, "not initialized");
if (! mInner)
@ -546,134 +517,85 @@ static const char kResourceURIPrefix[] = "resource:";
nsresult rv;
nsIRDFService* rdfService = nsnull;
nsINameSpaceManager* ns = nsnull;
nsIRDFContentSink* sink = nsnull;
nsIParser* parser = nsnull;
nsIDTD* dtd = nsnull;
nsIStreamListener* lsnr = nsnull;
nsIURL* url = nsnull;
const char* realURL;
if (NS_FAILED(rv = NS_NewURL(&url, uri)))
goto done;
rv = NS_NewURL(getter_AddRefs(mURL), uri);
if (NS_FAILED(rv)) return rv;
// XXX this is a hack: any "file:" URI is considered writable. All
// others are considered read-only.
url->GetSpec(&realURL);
const char* realURL;
mURL->GetSpec(&realURL);
if ((PL_strncmp(realURL, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) &&
(PL_strncmp(realURL, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) {
mIsWritable = PR_FALSE;
}
if (NS_FAILED(rv = mInner->Init(realURL)))
goto done;
rv = mInner->Init(realURL);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID,
kIRDFServiceIID,
(nsISupports**) &rdfService)))
goto done;
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv = rdfService->RegisterDataSource(this, PR_FALSE)))
goto done;
rv = rdf->RegisterDataSource(this, PR_FALSE);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
nsnull,
kINameSpaceManagerIID,
(void**) &ns)))
goto done;
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kRDFContentSinkCID,
nsnull,
kIRDFContentSinkIID,
(void**) &sink)))
goto done;
if (NS_FAILED(sink->Init(url, ns)))
goto done;
// We set the content sink's data source directly to our in-memory
// store. This allows the initial content to be generated "directly".
if (NS_FAILED(rv = sink->SetDataSource(this)))
goto done;
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kParserCID,
nsnull,
kIParserIID,
(void**) &parser)))
goto done;
parser->SetDocumentCharset(utf8, kCharsetFromDocTypeDefault);
parser->SetContentSink(sink);
// XXX this should eventually be kRDFDTDCID (oh boy, that's a
// pretty identifier). The RDF DTD will be a much more
// RDF-resilient parser.
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kWellFormedDTDCID,
nsnull,
kIDTDIID,
(void**) &dtd)))
goto done;
parser->RegisterDTD(dtd);
if (NS_FAILED(rv = parser->QueryInterface(kIStreamListenerIID, (void**) &lsnr)))
goto done;
if (NS_FAILED(parser->Parse(url)))
goto done;
// XXX Yet another hack to get the registry stuff
// bootstrapped. Force "file:" and "resource:" URIs to be loaded
// by a blocking read. Maybe there needs to be a distinct
// interface for stream data sources?
if (mIsSynchronous) {
rv = rdf_BlockingParse(url, lsnr);
}
else {
rv = NS_OpenURL(url, lsnr);
}
done:
NS_IF_RELEASE(lsnr);
NS_IF_RELEASE(dtd);
NS_IF_RELEASE(parser);
NS_IF_RELEASE(sink);
if (rdfService) {
nsServiceManager::ReleaseService(kRDFServiceCID, rdfService);
rdfService = nsnull;
}
NS_IF_RELEASE(url);
return rv;
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv)
RDFXMLDataSourceImpl::Assert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue)
{
// We don't accept assertions unless we're writable (except in the
// case that we're actually _reading_ the datasource in).
if (!mIsLoading && !mIsWritable)
return NS_RDF_ASSERTION_REJECTED;
nsresult rv;
nsresult rv = mInner->Assert(source, property, target, tv);
if (mIsLoading) {
PRBool hasAssertion = PR_FALSE;
if (rv == NS_RDF_ASSERTION_ACCEPTED) {
if (!mIsLoading)
mIsDirty = PR_TRUE;
nsCOMPtr<nsIRDFPurgeableDataSource> gcable = do_QueryInterface(mInner);
if (gcable) {
rv = gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &hasAssertion);
if (NS_FAILED(rv)) return rv;
}
rv = NS_RDF_ASSERTION_ACCEPTED;
if (! hasAssertion) {
rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
if (NS_SUCCEEDED(rv) && gcable) {
// Now mark the new assertion, so it doesn't get
// removed when we sweep. Ignore rv, because we want
// to return what mInner->Assert() gave us.
PRBool didMark;
(void) gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &didMark);
}
if (NS_FAILED(rv)) return rv;
}
return rv;
}
else if (mIsWritable) {
rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
return rv;
if (rv == NS_RDF_ASSERTION_ACCEPTED)
mIsDirty = PR_TRUE;
return rv;
}
else {
return NS_RDF_ASSERTION_REJECTED;
}
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source,
nsIRDFResource* property,
RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target)
{
// We don't accept assertions unless we're writable (except in the
@ -724,12 +646,13 @@ done:
// nsIRDFXMLDataSource methods
NS_IMETHODIMP
RDFXMLDataSourceImpl::SetSynchronous(PRBool aIsSynchronous)
RDFXMLDataSourceImpl::GetReadOnly(PRBool* aIsReadOnly)
{
mIsSynchronous = aIsSynchronous;
*aIsReadOnly = !mIsWritable;
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::SetReadOnly(PRBool aIsReadOnly)
{
@ -739,6 +662,76 @@ RDFXMLDataSourceImpl::SetReadOnly(PRBool aIsReadOnly)
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::Open(PRBool aBlocking)
{
nsresult rv;
nsCOMPtr<nsINameSpaceManager> nsmgr;
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
nsnull,
kINameSpaceManagerIID,
getter_AddRefs(nsmgr));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFContentSink> sink;
rv = nsComponentManager::CreateInstance(kRDFContentSinkCID,
nsnull,
kIRDFContentSinkIID,
getter_AddRefs(sink));
if (NS_FAILED(rv)) return rv;
rv = sink->Init(mURL, nsmgr);
if (NS_FAILED(rv)) return rv;
// We set the content sink's data source directly to our in-memory
// store. This allows the initial content to be generated "directly".
rv = sink->SetDataSource(this);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIParser> parser;
rv = nsComponentManager::CreateInstance(kParserCID,
nsnull,
kIParserIID,
getter_AddRefs(parser));
nsAutoString utf8("UTF-8");
parser->SetDocumentCharset(utf8, kCharsetFromDocTypeDefault);
parser->SetContentSink(sink);
// XXX this should eventually be kRDFDTDCID (oh boy, that's a
// pretty identifier). The RDF DTD will be a much more
// RDF-resilient parser.
nsCOMPtr<nsIDTD> dtd;
rv = nsComponentManager::CreateInstance(kWellFormedDTDCID,
nsnull,
kIDTDIID,
getter_AddRefs(dtd));
if (NS_FAILED(rv)) return rv;
parser->RegisterDTD(dtd);
nsCOMPtr<nsIStreamListener> lsnr;
rv = parser->QueryInterface(kIStreamListenerIID, getter_AddRefs(lsnr));
if (NS_FAILED(rv)) return rv;
rv = parser->Parse(mURL);
if (NS_FAILED(rv)) return rv;
if (aBlocking) {
rv = rdf_BlockingParse(mURL, lsnr);
}
else {
rv = NS_OpenURL(mURL, lsnr);
}
return rv;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::BeginLoad(void)
{
@ -774,6 +767,11 @@ NS_IMETHODIMP
RDFXMLDataSourceImpl::EndLoad(void)
{
mIsLoading = PR_FALSE;
nsCOMPtr<nsIRDFPurgeableDataSource> gcable = do_QueryInterface(mInner);
if (gcable) {
gcable->Sweep();
}
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
nsIRDFXMLDataSourceObserver* obs = (nsIRDFXMLDataSourceObserver*) mObservers[i];
obs->OnEndLoad(this);
@ -781,113 +779,6 @@ RDFXMLDataSourceImpl::EndLoad(void)
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::SetRootResource(nsIRDFResource* aResource)
{
NS_PRECONDITION(aResource != nsnull, "null ptr");
if (! aResource)
return NS_ERROR_NULL_POINTER;
NS_IF_RELEASE(mRootResource);
mRootResource = aResource;
NS_IF_ADDREF(mRootResource);
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
nsIRDFXMLDataSourceObserver* obs = (nsIRDFXMLDataSourceObserver*) mObservers[i];
obs->OnRootResourceFound(this, mRootResource);
}
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::GetRootResource(nsIRDFResource** aResource)
{
NS_IF_ADDREF(mRootResource);
*aResource = mRootResource;
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::AddCSSStyleSheetURL(nsIURL* aCSSStyleSheetURL)
{
NS_PRECONDITION(aCSSStyleSheetURL != nsnull, "null ptr");
if (! aCSSStyleSheetURL)
return NS_ERROR_NULL_POINTER;
nsIURL** p = new nsIURL*[mNumCSSStyleSheetURLs + 1];
if (! p)
return NS_ERROR_OUT_OF_MEMORY;
PRInt32 i;
for (i = mNumCSSStyleSheetURLs - 1; i >= 0; --i)
p[i] = mCSSStyleSheetURLs[i];
NS_ADDREF(aCSSStyleSheetURL);
p[mNumCSSStyleSheetURLs] = aCSSStyleSheetURL;
++mNumCSSStyleSheetURLs;
mCSSStyleSheetURLs = p;
for (i = mObservers.Count() - 1; i >= 0; --i) {
nsIRDFXMLDataSourceObserver* obs = (nsIRDFXMLDataSourceObserver*) mObservers[i];
obs->OnCSSStyleSheetAdded(this, aCSSStyleSheetURL);
}
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::GetCSSStyleSheetURLs(nsIURL*** aCSSStyleSheetURLs, PRInt32* aCount)
{
*aCSSStyleSheetURLs = mCSSStyleSheetURLs;
*aCount = mNumCSSStyleSheetURLs;
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::AddNamedDataSourceURI(const char* aNamedDataSourceURI)
{
NS_PRECONDITION(aNamedDataSourceURI != nsnull, "null ptr");
if (! aNamedDataSourceURI)
return NS_ERROR_NULL_POINTER;
char** p = new char*[mNumNamedDataSourceURIs + 1];
if (! p)
return NS_ERROR_OUT_OF_MEMORY;
PRInt32 i;
for (i = mNumNamedDataSourceURIs - 1; i >= 0; --i)
p[i] = mNamedDataSourceURIs[i];
PRInt32 len = PL_strlen(aNamedDataSourceURI);
char* buf = new char[len + 1];
if (! buf) {
delete p;
return NS_ERROR_OUT_OF_MEMORY;
}
PL_strcpy(buf, aNamedDataSourceURI);
p[mNumNamedDataSourceURIs] = buf;
++mNumNamedDataSourceURIs;
mNamedDataSourceURIs = p;
for (i = mObservers.Count() - 1; i >= 0; --i) {
nsIRDFXMLDataSourceObserver* obs = (nsIRDFXMLDataSourceObserver*) mObservers[i];
obs->OnNamedDataSourceAdded(this, aNamedDataSourceURI);
}
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::GetNamedDataSourceURIs(const char* const** aNamedDataSourceURIs, PRInt32* aCount)
{
*aNamedDataSourceURIs = mNamedDataSourceURIs;
*aCount = mNumNamedDataSourceURIs;
return NS_OK;
}
NS_IMETHODIMP
RDFXMLDataSourceImpl::AddNameSpace(nsIAtom* aPrefix, const nsString& aURI)
{
@ -1384,7 +1275,7 @@ static const char kRDFAlt[] = "RDF:Alt";
else if (property == kRDF_instanceOf) {
// don't serialize instanceOf -- it's implicit in the tag
}
else if (property == kRDF_nextVal) {
else if (property == kRDF_nextVal) {
// don't serialize nextVal -- it's internal state
}
else {
@ -1414,30 +1305,6 @@ static const char kXMLNS[] = "\n xmlns";
rdf_BlockingWrite(aStream, kXMLVersion, sizeof(kXMLVersion) - 1);
PRInt32 i;
// Write out style sheet processing instructions
for (i = 0; i < mNumCSSStyleSheetURLs; ++i) {
static const char kCSSStyleSheet1[] = "<?xml-stylesheet href=\"";
static const char kCSSStyleSheet2[] = "\" type=\"text/css\"?>\n";
const char* url;
mCSSStyleSheetURLs[i]->GetSpec(&url);
rdf_BlockingWrite(aStream, kCSSStyleSheet1, sizeof(kCSSStyleSheet1) - 1);
rdf_BlockingWrite(aStream, url);
rdf_BlockingWrite(aStream, kCSSStyleSheet2, sizeof(kCSSStyleSheet2) - 1);
}
// Write out named data source processing instructions
for (i = 0; i < mNumNamedDataSourceURIs; ++i) {
static const char kNamedDataSource1[] = "<?rdf-datasource href=\"";
static const char kNamedDataSource2[] = "\"?>\n";
rdf_BlockingWrite(aStream, kNamedDataSource1, sizeof(kNamedDataSource1) - 1);
rdf_BlockingWrite(aStream, mNamedDataSourceURIs[i]);
rdf_BlockingWrite(aStream, kNamedDataSource2, sizeof(kNamedDataSource2) - 1);
}
// global name space declarations
rdf_BlockingWrite(aStream, kOpenRDF, sizeof(kOpenRDF) - 1);
for (NameSpaceMap* entry = mNameSpaces; entry != nsnull; entry = entry->Next) {