Bug 68213. Require users of nsFixedSizeAllocator to specify object size at Free() time to avoid 8 byte overhead per allocation. r=harishd, brendan, shaver, hyatt; sr=scc
git-svn-id: svn://10.0.0.236/trunk@91251 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
049707d100
commit
1ef6e620b4
@ -98,25 +98,34 @@ public:
|
||||
|
||||
nsIContent* mElement;
|
||||
|
||||
static nsXBLAttributeEntry*
|
||||
Create(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, nsIContent* aContent) {
|
||||
void* place = nsXBLPrototypeBinding::kAttrPool.Alloc(sizeof(nsXBLAttributeEntry));
|
||||
return place ? ::new (place) nsXBLAttributeEntry(aSrcAtom, aDstAtom, aContent) : nsnull;
|
||||
}
|
||||
|
||||
static void
|
||||
Destroy(nsXBLAttributeEntry* aSelf) {
|
||||
aSelf->~nsXBLAttributeEntry();
|
||||
nsXBLPrototypeBinding::kAttrPool.Free(aSelf, sizeof(*aSelf));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> mSrcAttribute;
|
||||
nsCOMPtr<nsIAtom> mDstAttribute;
|
||||
nsCOMPtr<nsIXBLAttributeEntry> mNext;
|
||||
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize);
|
||||
}
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize);
|
||||
}
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
nsXBLAttributeEntry(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, nsIContent* aContent) {
|
||||
NS_INIT_REFCNT(); mSrcAttribute = aSrcAtom; mDstAttribute = aDstAtom; mElement = aContent;
|
||||
};
|
||||
}
|
||||
|
||||
virtual ~nsXBLAttributeEntry() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
||||
@ -159,27 +168,38 @@ public:
|
||||
nsCOMPtr<nsIContent> mInsertionParent;
|
||||
nsCOMPtr<nsIContent> mDefaultContent;
|
||||
PRUint32 mInsertionIndex;
|
||||
|
||||
static nsXBLInsertionPointEntry*
|
||||
Create(nsIContent* aParent) {
|
||||
void* place = nsXBLPrototypeBinding::kInsPool.Alloc(sizeof(nsXBLInsertionPointEntry));
|
||||
return place ? ::new (place) nsXBLInsertionPointEntry(aParent) : nsnull;
|
||||
}
|
||||
|
||||
static void
|
||||
Destroy(nsXBLInsertionPointEntry* aSelf) {
|
||||
aSelf->~nsXBLInsertionPointEntry();
|
||||
nsXBLPrototypeBinding::kInsPool.Free(aSelf, sizeof(*aSelf));
|
||||
}
|
||||
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize);
|
||||
}
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize);
|
||||
}
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
nsXBLInsertionPointEntry(nsIContent* aParent) {
|
||||
NS_INIT_REFCNT();
|
||||
mInsertionIndex = 0;
|
||||
mInsertionParent = aParent;
|
||||
};
|
||||
|
||||
virtual ~nsXBLInsertionPointEntry() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLInsertionPointEntry, nsIXBLInsertionPointEntry)
|
||||
NS_IMPL_ADDREF(nsXBLInsertionPointEntry)
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(nsXBLInsertionPointEntry, Destroy(this))
|
||||
NS_IMPL_QUERY_INTERFACE1(nsXBLInsertionPointEntry, nsIXBLInsertionPointEntry)
|
||||
|
||||
// =============================================================================
|
||||
|
||||
@ -1107,7 +1127,7 @@ nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||
}
|
||||
|
||||
// Create an XBL attribute entry.
|
||||
nsXBLAttributeEntry* xblAttr = new (kAttrPool) nsXBLAttributeEntry(atom, attribute, aElement);
|
||||
nsXBLAttributeEntry* xblAttr = nsXBLAttributeEntry::Create(atom, attribute, aElement);
|
||||
|
||||
// Now we should see if some element within our anonymous
|
||||
// content is already observing this attribute.
|
||||
@ -1173,7 +1193,7 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
|
||||
child->GetParent(*getter_AddRefs(parent));
|
||||
|
||||
// Create an XBL insertion point entry.
|
||||
nsXBLInsertionPointEntry* xblIns = new (kInsPool) nsXBLInsertionPointEntry(parent);
|
||||
nsXBLInsertionPointEntry* xblIns = nsXBLInsertionPointEntry::Create(parent);
|
||||
|
||||
nsAutoString includes;
|
||||
child->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
|
||||
|
||||
@ -97,39 +97,22 @@ static PRBool IsResourceURI(nsIURI* aURI)
|
||||
}
|
||||
|
||||
// Individual binding requests.
|
||||
struct nsXBLBindingRequest
|
||||
class nsXBLBindingRequest
|
||||
{
|
||||
public:
|
||||
nsCString mBindingURL;
|
||||
nsCOMPtr<nsIContent> mBoundElement;
|
||||
|
||||
nsXBLBindingRequest(const nsCString& aURL, nsIContent* aBoundElement)
|
||||
{
|
||||
mBindingURL = aURL;
|
||||
mBoundElement = aBoundElement;
|
||||
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
nsServiceManager::GetService("@mozilla.org/xbl;1",
|
||||
NS_GET_IID(nsIXBLService),
|
||||
(nsISupports**) &gXBLService);
|
||||
}
|
||||
static nsXBLBindingRequest*
|
||||
Create(nsFixedSizeAllocator& aPool, const nsCString& aURL, nsIContent* aBoundElement) {
|
||||
void* place = aPool.Alloc(sizeof(nsXBLBindingRequest));
|
||||
return place ? ::new (place) nsXBLBindingRequest(aURL, aBoundElement) : nsnull;
|
||||
}
|
||||
|
||||
~nsXBLBindingRequest()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
nsServiceManager::ReleaseService("@mozilla.org/xbl;1", gXBLService);
|
||||
gXBLService = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize);
|
||||
}
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize);
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, nsXBLBindingRequest* aRequest) {
|
||||
aRequest->~nsXBLBindingRequest();
|
||||
aPool.Free(aRequest, sizeof(*aRequest));
|
||||
}
|
||||
|
||||
void DocumentLoaded(nsIDocument* aBindingDoc)
|
||||
@ -166,6 +149,35 @@ struct nsXBLBindingRequest
|
||||
|
||||
static nsIXBLService* gXBLService;
|
||||
static int gRefCnt;
|
||||
|
||||
protected:
|
||||
nsXBLBindingRequest(const nsCString& aURL, nsIContent* aBoundElement)
|
||||
{
|
||||
mBindingURL = aURL;
|
||||
mBoundElement = aBoundElement;
|
||||
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
nsServiceManager::GetService("@mozilla.org/xbl;1",
|
||||
NS_GET_IID(nsIXBLService),
|
||||
(nsISupports**) &gXBLService);
|
||||
}
|
||||
}
|
||||
|
||||
~nsXBLBindingRequest()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
nsServiceManager::ReleaseService("@mozilla.org/xbl;1", gXBLService);
|
||||
gXBLService = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
};
|
||||
|
||||
static const size_t kBucketSizes[] = {
|
||||
@ -198,13 +210,15 @@ public:
|
||||
static nsIXULPrototypeCache* gXULCache;
|
||||
static PRInt32 gRefCnt;
|
||||
|
||||
nsXBLStreamListener(nsIStreamListener* aInner, nsIDocument* aDocument, nsIDocument* aBindingDocument);
|
||||
nsXBLStreamListener(nsXBLService* aXBLService, nsIStreamListener* aInner, nsIDocument* aDocument, nsIDocument* aBindingDocument);
|
||||
virtual ~nsXBLStreamListener();
|
||||
|
||||
void AddRequest(nsXBLBindingRequest* aRequest) { mBindingRequests.AppendElement(aRequest); };
|
||||
PRBool HasRequest(const nsCString& aURI, nsIContent* aBoundElement);
|
||||
|
||||
private:
|
||||
nsXBLService* mXBLService; // [WEAK]
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mInner;
|
||||
nsVoidArray mBindingRequests;
|
||||
|
||||
@ -218,11 +232,13 @@ PRInt32 nsXBLStreamListener::gRefCnt = 0;
|
||||
/* Implementation file */
|
||||
NS_IMPL_ISUPPORTS4(nsXBLStreamListener, nsIStreamListener, nsIStreamObserver, nsIDOMLoadListener, nsIDOMEventListener)
|
||||
|
||||
nsXBLStreamListener::nsXBLStreamListener(nsIStreamListener* aInner, nsIDocument* aDocument,
|
||||
nsXBLStreamListener::nsXBLStreamListener(nsXBLService* aXBLService,
|
||||
nsIStreamListener* aInner, nsIDocument* aDocument,
|
||||
nsIDocument* aBindingDocument)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
mXBLService = aXBLService;
|
||||
mInner = aInner;
|
||||
mDocument = getter_AddRefs(NS_GetWeakReference(aDocument));
|
||||
mBindingDocument = aBindingDocument;
|
||||
@ -290,7 +306,7 @@ nsXBLStreamListener::OnStopRequest(nsIRequest* request, nsISupports* aCtxt, nsre
|
||||
PRUint32 count = mBindingRequests.Count();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsXBLBindingRequest* req = (nsXBLBindingRequest*)mBindingRequests.ElementAt(i);
|
||||
delete req;
|
||||
nsXBLBindingRequest::Destroy(mXBLService->mPool, req);
|
||||
}
|
||||
|
||||
mDocument = nsnull;
|
||||
@ -404,7 +420,7 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsXBLBindingRequest* req = (nsXBLBindingRequest*)mBindingRequests.ElementAt(i);
|
||||
delete req;
|
||||
nsXBLBindingRequest::Destroy(mXBLService->mPool, req);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(mBindingDocument));
|
||||
@ -1122,7 +1138,7 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
|
||||
bindingURI += "#";
|
||||
bindingURI += aRef;
|
||||
if (!xblListener->HasRequest(bindingURI, aBoundElement)) {
|
||||
nsXBLBindingRequest* req = new (mPool) nsXBLBindingRequest(bindingURI, aBoundElement);
|
||||
nsXBLBindingRequest* req = nsXBLBindingRequest::Create(mPool, bindingURI, aBoundElement);
|
||||
xblListener->AddRequest(req);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -1225,7 +1241,7 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
|
||||
|
||||
if (!aForceSyncLoad) {
|
||||
// We can be asynchronous
|
||||
nsXBLStreamListener* xblListener = new nsXBLStreamListener(listener, aBoundDocument, doc);
|
||||
nsXBLStreamListener* xblListener = new nsXBLStreamListener(this, listener, aBoundDocument, doc);
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
rec->AddEventListener(NS_ConvertASCIItoUCS2("load"), (nsIDOMLoadListener*)xblListener, PR_FALSE);
|
||||
@ -1241,7 +1257,7 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
|
||||
nsCAutoString bindingURI(uri);
|
||||
bindingURI += "#";
|
||||
bindingURI += aRef;
|
||||
nsXBLBindingRequest* req = new (mPool) nsXBLBindingRequest(bindingURI, aBoundElement);
|
||||
nsXBLBindingRequest* req = nsXBLBindingRequest::Create(mPool, bindingURI, aBoundElement);
|
||||
xblListener->AddRequest(req);
|
||||
|
||||
// Now kick off the async read.
|
||||
|
||||
@ -65,8 +65,9 @@ static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey)
|
||||
|
||||
static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag)
|
||||
{
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
if (aFlag == HT_FREE_ENTRY)
|
||||
nsFixedSizeAllocator::Free(aEntry, sizeof(PLHashEntry));
|
||||
pool->Free(aEntry, sizeof(PLHashEntry));
|
||||
}
|
||||
|
||||
PLHashAllocOps nsElementMap::gAllocOps = {
|
||||
@ -115,7 +116,7 @@ nsElementMap::~nsElementMap()
|
||||
MOZ_COUNT_DTOR(nsElementMap);
|
||||
|
||||
if (mMap) {
|
||||
PL_HashTableEnumerateEntries(mMap, ReleaseContentList, nsnull);
|
||||
PL_HashTableEnumerateEntries(mMap, ReleaseContentList, this);
|
||||
PL_HashTableDestroy(mMap);
|
||||
}
|
||||
|
||||
@ -127,6 +128,8 @@ nsElementMap::~nsElementMap()
|
||||
PRIntn
|
||||
nsElementMap::ReleaseContentList(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosure)
|
||||
{
|
||||
nsElementMap* self = NS_STATIC_CAST(nsElementMap*, aClosure);
|
||||
|
||||
PRUnichar* id =
|
||||
NS_REINTERPRET_CAST(PRUnichar*, NS_CONST_CAST(void*, aHashEntry->key));
|
||||
|
||||
@ -138,7 +141,7 @@ nsElementMap::ReleaseContentList(PLHashEntry* aHashEntry, PRIntn aIndex, void* a
|
||||
while (head) {
|
||||
ContentListItem* doomed = head;
|
||||
head = head->mNext;
|
||||
delete doomed;
|
||||
ContentListItem::Destroy(self->mPool, doomed);
|
||||
}
|
||||
|
||||
return HT_ENUMERATE_NEXT;
|
||||
@ -159,7 +162,7 @@ nsElementMap::Add(const nsAReadableString& aID, nsIContent* aContent)
|
||||
NS_STATIC_CAST(ContentListItem*, PL_HashTableLookup(mMap, id));
|
||||
|
||||
if (! head) {
|
||||
head = new (mPool) ContentListItem(aContent);
|
||||
head = ContentListItem::Create(mPool, aContent);
|
||||
if (! head)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -211,7 +214,7 @@ nsElementMap::Add(const nsAReadableString& aID, nsIContent* aContent)
|
||||
head = head->mNext;
|
||||
}
|
||||
|
||||
head->mNext = new (mPool) ContentListItem(aContent);
|
||||
head->mNext = ContentListItem::Create(mPool, aContent);
|
||||
if (! head->mNext)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -302,14 +305,14 @@ nsElementMap::Remove(const nsAReadableString& aID, nsIContent* aContent)
|
||||
PL_HashTableRawRemove(mMap, hep, *hep);
|
||||
nsMemory::Free(key);
|
||||
}
|
||||
delete head;
|
||||
ContentListItem::Destroy(mPool, head);
|
||||
}
|
||||
else {
|
||||
ContentListItem* item = head->mNext;
|
||||
while (item) {
|
||||
if (item->mContent.get() == aContent) {
|
||||
head->mNext = item->mNext;
|
||||
delete item;
|
||||
ContentListItem::Destroy(mPool, item);
|
||||
break;
|
||||
}
|
||||
head = item;
|
||||
@ -365,7 +368,7 @@ nsElementMap::FindFirst(const nsAReadableString& aID, nsIContent** aResult)
|
||||
nsresult
|
||||
nsElementMap::Enumerate(nsElementMapEnumerator aEnumerator, void* aClosure)
|
||||
{
|
||||
EnumerateClosure closure = { aEnumerator, aClosure };
|
||||
EnumerateClosure closure = { this, aEnumerator, aClosure };
|
||||
PL_HashTableEnumerateEntries(mMap, EnumerateImpl, &closure);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -398,7 +401,7 @@ nsElementMap::EnumerateImpl(PLHashEntry* aHashEntry, PRIntn aIndex, void* aClosu
|
||||
if (result == HT_ENUMERATE_REMOVE) {
|
||||
// If the user wants to remove the current, then deal.
|
||||
*link = item;
|
||||
delete current;
|
||||
ContentListItem::Destroy(closure->mSelf->mPool, current);
|
||||
|
||||
if ((! *link) && (link == NS_REINTERPRET_CAST(ContentListItem**, &aHashEntry->value))) {
|
||||
// It's the last content node that was mapped to this
|
||||
|
||||
@ -65,22 +65,31 @@ protected:
|
||||
|
||||
class ContentListItem {
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
ContentListItem(nsIContent* aContent) : mNext(nsnull), mContent(aContent) {
|
||||
MOZ_COUNT_CTOR(nsElementMap::ContentListItem);
|
||||
}
|
||||
|
||||
~ContentListItem() {
|
||||
MOZ_COUNT_DTOR(nsElementMap::ContentListItem);
|
||||
}
|
||||
|
||||
ContentListItem* mNext;
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
|
||||
static ContentListItem*
|
||||
Create(nsFixedSizeAllocator& aPool, nsIContent* aContent) {
|
||||
void* bytes = aPool.Alloc(sizeof(ContentListItem));
|
||||
return bytes ? new (bytes) ContentListItem(aContent) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, ContentListItem* aItem) {
|
||||
delete aItem;
|
||||
aPool.Free(aItem, sizeof(*aItem)); }
|
||||
|
||||
protected:
|
||||
static void* operator new(size_t aSize, void* aPtr) {
|
||||
return aPtr; }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
/* do nothing; memory free()'d in Destroy() */ }
|
||||
|
||||
ContentListItem(nsIContent* aContent) : mNext(nsnull), mContent(aContent) {
|
||||
MOZ_COUNT_CTOR(nsElementMap::ContentListItem); }
|
||||
|
||||
~ContentListItem() {
|
||||
MOZ_COUNT_DTOR(nsElementMap::ContentListItem); }
|
||||
};
|
||||
|
||||
static PLHashNumber PR_CALLBACK
|
||||
@ -117,6 +126,7 @@ public:
|
||||
|
||||
private:
|
||||
struct EnumerateClosure {
|
||||
nsElementMap* mSelf;
|
||||
nsElementMapEnumerator mEnumerator;
|
||||
void* mClosure;
|
||||
};
|
||||
|
||||
@ -41,7 +41,9 @@ nsClusterKeySet::nsClusterKeySet()
|
||||
|
||||
mPool.Init("nsClusterKeySet", kBucketSizes, kNumBuckets, kInitialPoolSize);
|
||||
|
||||
mTable = PL_NewHashTable(kInitialEntries, nsClusterKey::HashClusterKey, nsClusterKey::CompareClusterKeys,
|
||||
mTable = PL_NewHashTable(kInitialEntries,
|
||||
nsClusterKey::HashClusterKey,
|
||||
nsClusterKey::CompareClusterKeys,
|
||||
PL_CompareValues, &gAllocOps, &mPool);
|
||||
|
||||
MOZ_COUNT_CTOR(nsClusterKeySet);
|
||||
|
||||
@ -37,13 +37,13 @@ public:
|
||||
|
||||
protected:
|
||||
class Entry {
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Entry() { MOZ_COUNT_CTOR(nsClusterKeySet::Entry); }
|
||||
|
||||
Entry(const nsClusterKey& aKey) : mKey(aKey) {
|
||||
@ -51,10 +51,20 @@ protected:
|
||||
|
||||
~Entry() { MOZ_COUNT_DTOR(nsClusterKeySet::Entry); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
nsClusterKey mKey;
|
||||
Entry* mPrev;
|
||||
Entry* mNext;
|
||||
static Entry*
|
||||
Create(nsFixedSizeAllocator& aPool, const nsClusterKey& aKey) {
|
||||
void* place = aPool.Alloc(sizeof(Entry));
|
||||
return place ? ::new (place) Entry(aKey) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Entry* aEntry) {
|
||||
aEntry->~Entry();
|
||||
aPool.Free(aEntry, sizeof(*aEntry)); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
nsClusterKey mKey;
|
||||
Entry* mPrev;
|
||||
Entry* mNext;
|
||||
};
|
||||
|
||||
PLHashTable* mTable;
|
||||
@ -120,12 +130,13 @@ protected:
|
||||
static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
const nsClusterKey* key = NS_STATIC_CAST(const nsClusterKey*, aKey);
|
||||
Entry* entry = new (*pool) Entry(*key);
|
||||
Entry* entry = Entry::Create(*pool, *key);
|
||||
return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
|
||||
|
||||
static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
if (aFlag == HT_FREE_ENTRY)
|
||||
delete NS_REINTERPRET_CAST(Entry*, aEntry); }
|
||||
Entry::Destroy(*pool, NS_REINTERPRET_CAST(Entry*, aEntry)); }
|
||||
};
|
||||
|
||||
#endif // nsClusterKeySet_h__
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "nsConflictSet.h"
|
||||
#include "nsTemplateRule.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModule* nsConflictSet::gLog;
|
||||
@ -52,8 +53,6 @@ nsConflictSet::Init()
|
||||
sizeof(ClusterEntry),
|
||||
sizeof(SupportEntry),
|
||||
sizeof(BindingEntry),
|
||||
nsTemplateMatchSet::kEntrySize,
|
||||
nsTemplateMatchSet::kIndexSize
|
||||
};
|
||||
|
||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t);
|
||||
@ -115,10 +114,10 @@ nsConflictSet::Add(nsTemplateMatch* aMatch)
|
||||
PLHashNumber hash = key.Hash();
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mClusters, hash, &key);
|
||||
|
||||
nsTemplateMatchSet* set;
|
||||
MatchCluster* cluster;
|
||||
|
||||
if (hep && *hep) {
|
||||
set = NS_STATIC_CAST(nsTemplateMatchSet*, (*hep)->value);
|
||||
cluster = NS_REINTERPRET_CAST(MatchCluster*, (*hep)->value);
|
||||
}
|
||||
else {
|
||||
PLHashEntry* he = PL_HashTableRawAdd(mClusters, hep, hash, &key, nsnull);
|
||||
@ -132,14 +131,12 @@ nsConflictSet::Add(nsTemplateMatch* aMatch)
|
||||
// than the value on the stack). Do the same for its
|
||||
// value.
|
||||
entry->mHashEntry.key = &entry->mKey;
|
||||
entry->mHashEntry.value = &entry->mMatchSet;
|
||||
|
||||
set = &entry->mMatchSet;
|
||||
entry->mHashEntry.value = cluster = &entry->mCluster;
|
||||
}
|
||||
|
||||
if (! set->Contains(*aMatch)) {
|
||||
set->Add(mPool, aMatch);
|
||||
}
|
||||
nsTemplateMatchRefSet& set = cluster->mMatches;
|
||||
if (! set.Contains(aMatch))
|
||||
set.Add(aMatch);
|
||||
}
|
||||
|
||||
|
||||
@ -150,10 +147,10 @@ nsConflictSet::Add(nsTemplateMatch* aMatch)
|
||||
PLHashNumber hash = element->Hash();
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mSupport, hash, element.operator->());
|
||||
|
||||
nsTemplateMatchSet* set;
|
||||
nsTemplateMatchRefSet* set;
|
||||
|
||||
if (hep && *hep) {
|
||||
set = NS_STATIC_CAST(nsTemplateMatchSet*, (*hep)->value);
|
||||
set = NS_STATIC_CAST(nsTemplateMatchRefSet*, (*hep)->value);
|
||||
}
|
||||
else {
|
||||
PLHashEntry* he = PL_HashTableRawAdd(mSupport, hep, hash, element.operator->(), nsnull);
|
||||
@ -169,8 +166,9 @@ nsConflictSet::Add(nsTemplateMatch* aMatch)
|
||||
set = &entry->mMatchSet;
|
||||
}
|
||||
|
||||
if (! set->Contains(*aMatch)) {
|
||||
set->Add(mPool, aMatch);
|
||||
if (! set->Contains(aMatch)) {
|
||||
set->Add(aMatch);
|
||||
aMatch->AddRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -184,26 +182,52 @@ nsConflictSet::Add(nsTemplateMatch* aMatch)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsConflictSet::GetMatchesForClusterKey(const nsClusterKey& aKey, const nsTemplateMatchSet** aMatchSet)
|
||||
nsConflictSet::MatchCluster*
|
||||
nsConflictSet::GetMatchesForClusterKey(const nsClusterKey& aKey)
|
||||
{
|
||||
// Retrieve all the matches in a cluster
|
||||
*aMatchSet = NS_STATIC_CAST(nsTemplateMatchSet*, PL_HashTableLookup(mClusters, &aKey));
|
||||
return NS_STATIC_CAST(MatchCluster*, PL_HashTableLookup(mClusters, &aKey));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsConflictSet::GetMatchesWithBindingDependency(nsIRDFResource* aResource, const nsTemplateMatchSet** aMatchSet)
|
||||
nsTemplateMatch*
|
||||
nsConflictSet::GetMatchWithHighestPriority(const MatchCluster* aMatchCluster) const
|
||||
{
|
||||
// Find the rule with the "highest priority"; i.e., the rule with
|
||||
// the lowest value for GetPriority().
|
||||
//
|
||||
// XXX if people start writing more than a few matches, we should
|
||||
// rewrite this to maintain the matches in sorted order, and then
|
||||
// just pluck the match off the top of the list.
|
||||
nsTemplateMatch* result = nsnull;
|
||||
PRInt32 max = PRInt32(PR_BIT(31) - 1);
|
||||
|
||||
const nsTemplateMatchRefSet& set = aMatchCluster->mMatches;
|
||||
nsTemplateMatchRefSet::ConstIterator last = set.Last();
|
||||
|
||||
for (nsTemplateMatchRefSet::ConstIterator match = set.First(); match != last; ++match) {
|
||||
PRInt32 priority = match->mRule->GetPriority();
|
||||
if (priority < max) {
|
||||
result = NS_CONST_CAST(nsTemplateMatch*, match.operator->());
|
||||
max = priority;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsTemplateMatchRefSet*
|
||||
nsConflictSet::GetMatchesWithBindingDependency(nsIRDFResource* aResource)
|
||||
{
|
||||
// Retrieve all the matches whose bindings depend on the specified resource
|
||||
*aMatchSet = NS_STATIC_CAST(nsTemplateMatchSet*, PL_HashTableLookup(mBindingDependencies, aResource));
|
||||
return NS_STATIC_CAST(nsTemplateMatchRefSet*, PL_HashTableLookup(mBindingDependencies, aResource));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsConflictSet::Remove(const MemoryElement& aMemoryElement,
|
||||
nsTemplateMatchSet& aNewMatches,
|
||||
nsTemplateMatchSet& aRetractedMatches)
|
||||
nsTemplateMatchSet& aNewMatches,
|
||||
nsTemplateMatchSet& aRetractedMatches)
|
||||
{
|
||||
// Use the memory-element-to-match map to figure out what matches
|
||||
// will be affected.
|
||||
@ -213,14 +237,16 @@ nsConflictSet::Remove(const MemoryElement& aMemoryElement,
|
||||
return;
|
||||
|
||||
// 'set' gets the set of all matches containing the first binding.
|
||||
nsTemplateMatchSet* set = NS_STATIC_CAST(nsTemplateMatchSet*, (*hep)->value);
|
||||
nsTemplateMatchRefSet* set =
|
||||
NS_STATIC_CAST(nsTemplateMatchRefSet*, (*hep)->value);
|
||||
|
||||
// We'll iterate through these matches, only paying attention to
|
||||
// matches that strictly contain the MemoryElement we're about to
|
||||
// remove.
|
||||
for (nsTemplateMatchSet::Iterator match = set->First(); match != set->Last(); ++match) {
|
||||
nsTemplateMatchRefSet::ConstIterator last = set->Last();
|
||||
for (nsTemplateMatchRefSet::ConstIterator match = set->First(); match != last; ++match) {
|
||||
// Note the retraction, so we can compute new matches, later.
|
||||
aRetractedMatches.Add(mPool, match.operator->());
|
||||
aRetractedMatches.Add(match.operator->());
|
||||
|
||||
// Keep the bindings table in sync, as well. Since this match
|
||||
// is getting nuked, we need to nuke its bindings as well.
|
||||
@ -244,10 +270,10 @@ nsConflictSet::AddBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aRe
|
||||
PLHashNumber hash = HashBindingElement(aResource);
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mBindingDependencies, hash, aResource);
|
||||
|
||||
nsTemplateMatchSet* set;
|
||||
nsTemplateMatchRefSet* set;
|
||||
|
||||
if (hep && *hep) {
|
||||
set = NS_STATIC_CAST(nsTemplateMatchSet*, (*hep)->value);
|
||||
set = NS_STATIC_CAST(nsTemplateMatchRefSet*, (*hep)->value);
|
||||
}
|
||||
else {
|
||||
PLHashEntry* he = PL_HashTableRawAdd(mBindingDependencies, hep, hash, aResource, nsnull);
|
||||
@ -261,9 +287,8 @@ nsConflictSet::AddBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aRe
|
||||
|
||||
}
|
||||
|
||||
if (! set->Contains(*aMatch)) {
|
||||
set->Add(mPool, aMatch);
|
||||
}
|
||||
if (! set->Contains(aMatch))
|
||||
set->Add(aMatch);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -276,26 +301,28 @@ nsConflictSet::RemoveBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource*
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mBindingDependencies, hash, aResource);
|
||||
|
||||
if (hep && *hep) {
|
||||
nsTemplateMatchSet* set = NS_STATIC_CAST(nsTemplateMatchSet*, (*hep)->value);
|
||||
nsTemplateMatchRefSet* set = NS_STATIC_CAST(nsTemplateMatchRefSet*, (*hep)->value);
|
||||
|
||||
set->Remove(aMatch);
|
||||
|
||||
if (set->Empty()) {
|
||||
if (set->Empty())
|
||||
PL_HashTableRawRemove(mBindingDependencies, hep, *hep);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsConflictSet::ComputeNewMatches(nsTemplateMatchSet& aNewMatches, nsTemplateMatchSet& aRetractedMatches)
|
||||
nsConflictSet::ComputeNewMatches(nsTemplateMatchSet& aNewMatches,
|
||||
nsTemplateMatchSet& aRetractedMatches)
|
||||
{
|
||||
// Given a set of just-retracted matches, compute the set of new
|
||||
// matches that have been revealed, updating the key-to-match map
|
||||
// as we go.
|
||||
nsTemplateMatchSet::ConstIterator last = aRetractedMatches.Last();
|
||||
for (nsTemplateMatchSet::ConstIterator retraction = aRetractedMatches.First(); retraction != last; ++retraction) {
|
||||
for (nsTemplateMatchSet::ConstIterator retraction = aRetractedMatches.First();
|
||||
retraction != last;
|
||||
++retraction) {
|
||||
nsClusterKey key(retraction->mInstantiation, retraction->mRule);
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mClusters, key.Hash(), &key);
|
||||
|
||||
@ -305,26 +332,27 @@ nsConflictSet::ComputeNewMatches(nsTemplateMatchSet& aNewMatches, nsTemplateMatc
|
||||
if (!hep || !*hep)
|
||||
continue;
|
||||
|
||||
nsTemplateMatchSet* set = NS_STATIC_CAST(nsTemplateMatchSet*, (*hep)->value);
|
||||
MatchCluster* cluster = NS_REINTERPRET_CAST(MatchCluster*, (*hep)->value);
|
||||
nsTemplateMatchRefSet& set = cluster->mMatches;
|
||||
|
||||
for (nsTemplateMatchSet::Iterator match = set->First(); match != set->Last(); ++match) {
|
||||
nsTemplateMatchRefSet::ConstIterator last = set.Last();
|
||||
for (nsTemplateMatchRefSet::ConstIterator match = set.First(); match != last; ++match) {
|
||||
if (match->mRule == retraction->mRule) {
|
||||
set->Erase(match--);
|
||||
set.Remove(match.operator->()); // N.B., iterator no longer valid!
|
||||
|
||||
// See if we've revealed another rule that's applicable
|
||||
nsTemplateMatch* newmatch =
|
||||
set->FindMatchWithHighestPriority();
|
||||
GetMatchWithHighestPriority(cluster);
|
||||
|
||||
if (newmatch)
|
||||
aNewMatches.Add(mPool, newmatch);
|
||||
aNewMatches.Add(newmatch);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (set->Empty()) {
|
||||
if (set.Empty())
|
||||
PL_HashTableRawRemove(mClusters, hep, *hep);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -358,3 +386,23 @@ nsConflictSet::CompareMemoryElements(const void* aLeft, const void* aRight)
|
||||
|
||||
return *left == *right;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
|
||||
void
|
||||
nsConflictSet::SupportEntry::Destroy(nsFixedSizeAllocator& aPool, SupportEntry* aEntry)
|
||||
{
|
||||
// We need to Release() the matches here, because this is where
|
||||
// we've got access to the pool from which they were
|
||||
// allocated. Since SupportEntry's dtor is protected, nobody else
|
||||
// can be creating SupportEntry objects (e.g., on the stack).
|
||||
nsTemplateMatchRefSet::ConstIterator last = aEntry->mMatchSet.Last();
|
||||
for (nsTemplateMatchRefSet::ConstIterator iter = aEntry->mMatchSet.First();
|
||||
iter != last;
|
||||
++iter)
|
||||
iter->Release(aPool);
|
||||
|
||||
aEntry->~SupportEntry();
|
||||
aPool.Free(aEntry, sizeof(*aEntry));
|
||||
}
|
||||
|
||||
@ -31,25 +31,100 @@
|
||||
#include "nsIRDFResource.h"
|
||||
|
||||
/**
|
||||
* Maintains the set of active matches, and the stuff that the
|
||||
* matches depend on.
|
||||
* Maintains the set of active matches, and the stuff that the matches
|
||||
* depend on. An entity-relationship diagram of the situation might
|
||||
* look something like this:
|
||||
*
|
||||
* nsIRDFResource objects
|
||||
* (mBindingDependencies)
|
||||
* |
|
||||
* | [1]
|
||||
* |
|
||||
* [2] ^ [3]
|
||||
* Match ``clusters'' ---< nsTemplateMatch >--- MemoryElement objects
|
||||
* (mClusters) objects (mSupport)
|
||||
*
|
||||
* [1] Each match object may ``depend'' on one or more RDF resources;
|
||||
* that is, if an assertion about a resource changes, will the
|
||||
* match's bindings need to be updated? By maintaing a map from
|
||||
* nsIRDFResource objects to match objects, we can quickly
|
||||
* determine which matches will be affected when the datasource
|
||||
* notifies us of new assertions about a resource.
|
||||
*
|
||||
* The AddBindingDependency() and RemoveBindingDependency()
|
||||
* methods are used to add and remove dependencies from an
|
||||
* nsIRDFResource object to a match. The
|
||||
* GetMatchesWithBindingDependency() method is used to retrieve
|
||||
* the matches that depend upon a particular nsIRDFResource
|
||||
* object.
|
||||
*
|
||||
* [2] Each match is a ``grouped' by into a cluster for conflict
|
||||
* resolution. If the template has more than one rule, then it's
|
||||
* possible that more than one of the rules may match. If that's
|
||||
* the case, we need to choose amongst the matched rules to select
|
||||
* which one gets ``activated''. By maintaining a map from cluster
|
||||
* ``key'' (really just a <container, member> tuple) to the set of
|
||||
* matches that are active for that key, we can quickly select
|
||||
* amongst the matches to determine which one should be activated.
|
||||
*
|
||||
* When a match is first added to the conflict set using the Add()
|
||||
* method, it is automatically placed in the appropriate
|
||||
* group. The GetMatchesForClusterKey() method is used to retrieve
|
||||
* all the active matches in a match cluster; the
|
||||
* GetMatchWithHighestPriority() method is used to select among
|
||||
* these to determine which match should be activated.
|
||||
*
|
||||
* [3] Each match is ``supported'' by one or more MemoryElement
|
||||
* objects. These objects represent the values that were bound to
|
||||
* variables in the match's rule's conditions. If one of these
|
||||
* MemoryElements is removed, then the match is no longer
|
||||
* valid. We maintain a mapping from memory elements to the
|
||||
* matches that they support so that we can quickly determine
|
||||
* which matches will be affected by the removal of a memory
|
||||
* element object.
|
||||
*
|
||||
* When a match is first added to the conflict set using the Add()
|
||||
* method, the memory element dependencies are automatically
|
||||
* computed. The Remove() method is used to notify the conflict
|
||||
* set that a memory element has been removed; the method computes
|
||||
* the matches that have been ``retracted'' because the memory
|
||||
* element is gone, as well as any new matches that may have
|
||||
* ``fired'' because they were blocked by the presence of the
|
||||
* memory element.
|
||||
*/
|
||||
class nsConflictSet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A ``cluster'' of matches, all with the same nsClusterKey (that
|
||||
* is, matches with the same <container, member> tuple).
|
||||
*/
|
||||
class MatchCluster {
|
||||
public:
|
||||
MatchCluster() : mLastMatch(nsnull) {}
|
||||
|
||||
nsTemplateMatchRefSet mMatches;
|
||||
nsTemplateMatch* mLastMatch;
|
||||
};
|
||||
|
||||
nsConflictSet()
|
||||
: mClusters(nsnull),
|
||||
mSupport(nsnull),
|
||||
mBindingDependencies(nsnull) { Init(); }
|
||||
mBindingDependencies(nsnull) {
|
||||
MOZ_COUNT_CTOR(nsConflictSet);
|
||||
Init(); }
|
||||
|
||||
~nsConflictSet() { Destroy(); }
|
||||
~nsConflictSet() {
|
||||
MOZ_COUNT_DTOR(nsConflictSet);
|
||||
Destroy(); }
|
||||
|
||||
/**
|
||||
* Add a match to the conflict set.
|
||||
* @param aMatch the match to add to the conflict set
|
||||
* @return NS_OK if no errors occurred
|
||||
*/
|
||||
nsresult Add(nsTemplateMatch* aMatch);
|
||||
nsresult
|
||||
Add(nsTemplateMatch* aMatch);
|
||||
|
||||
/**
|
||||
* Given a cluster key, which is a container-member pair, return the
|
||||
@ -60,7 +135,16 @@ public:
|
||||
* @param aMatchSet the set of matches that are currently active
|
||||
* for the key.
|
||||
*/
|
||||
void GetMatchesForClusterKey(const nsClusterKey& aKey, const nsTemplateMatchSet** aMatchSet);
|
||||
MatchCluster*
|
||||
GetMatchesForClusterKey(const nsClusterKey& aKey);
|
||||
|
||||
/**
|
||||
* Retrieve the match from the set with the ``highest priority''
|
||||
* (that is, the lowest value returned by
|
||||
* nsTemplateMatch::GetPriority()).
|
||||
*/
|
||||
nsTemplateMatch*
|
||||
GetMatchWithHighestPriority(const MatchCluster* aMatchCluster) const;
|
||||
|
||||
/**
|
||||
* Given a "source" in the RDF graph, return the set of matches
|
||||
@ -68,7 +152,8 @@ public:
|
||||
* @param aSource an RDF resource that is a "source" in the graph.
|
||||
* @param aMatchSet the set of matches that depend on aSource.
|
||||
*/
|
||||
void GetMatchesWithBindingDependency(nsIRDFResource* aSource, const nsTemplateMatchSet** aMatchSet);
|
||||
const nsTemplateMatchRefSet*
|
||||
GetMatchesWithBindingDependency(nsIRDFResource* aSource);
|
||||
|
||||
/**
|
||||
* Remove a memory element from the conflict set. This may
|
||||
@ -80,13 +165,22 @@ public:
|
||||
* @param aRetractedMatches matches whose validity depended
|
||||
* on aMemoryElement and have been retracted.
|
||||
*/
|
||||
void Remove(const MemoryElement& aMemoryElement,
|
||||
nsTemplateMatchSet& aNewMatches,
|
||||
nsTemplateMatchSet& aRetractedMatches);
|
||||
void
|
||||
Remove(const MemoryElement& aMemoryElement,
|
||||
nsTemplateMatchSet& aNewMatches,
|
||||
nsTemplateMatchSet& aRetractedMatches);
|
||||
|
||||
nsresult AddBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aResource);
|
||||
/**
|
||||
* Add a binding dependency for aMatch on aResource.
|
||||
*/
|
||||
nsresult
|
||||
AddBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aResource);
|
||||
|
||||
nsresult RemoveBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aResource);
|
||||
/**
|
||||
* Remove the binding dependency on aResource from aMatch.
|
||||
*/
|
||||
nsresult
|
||||
RemoveBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aResource);
|
||||
|
||||
/**
|
||||
* Remove all match support information currently stored in the conflict
|
||||
@ -104,7 +198,9 @@ protected:
|
||||
nsresult Init();
|
||||
nsresult Destroy();
|
||||
|
||||
nsresult ComputeNewMatches(nsTemplateMatchSet& aNewMatches, nsTemplateMatchSet& aRetractedMatches);
|
||||
nsresult
|
||||
ComputeNewMatches(nsTemplateMatchSet& aNewMatches,
|
||||
nsTemplateMatchSet& aRetractedMatches);
|
||||
|
||||
/**
|
||||
* "Clusters" of matched rules for the same <content, member>
|
||||
@ -115,19 +211,29 @@ protected:
|
||||
PLHashTable* mClusters;
|
||||
|
||||
class ClusterEntry {
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
ClusterEntry() { MOZ_COUNT_CTOR(nsConflictSet::ClusterEntry); }
|
||||
~ClusterEntry() { MOZ_COUNT_DTOR(nsConflictSet::ClusterEntry); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
nsClusterKey mKey;
|
||||
nsTemplateMatchSet mMatchSet;
|
||||
static ClusterEntry*
|
||||
Create(nsFixedSizeAllocator& aPool) {
|
||||
void* place = aPool.Alloc(sizeof(ClusterEntry));
|
||||
return place ? ::new (place) ClusterEntry() : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, ClusterEntry* aEntry) {
|
||||
aEntry->~ClusterEntry();
|
||||
aPool.Free(aEntry, sizeof(*aEntry)); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
nsClusterKey mKey;
|
||||
MatchCluster mCluster;
|
||||
};
|
||||
|
||||
static PLHashAllocOps gClusterAllocOps;
|
||||
@ -141,7 +247,7 @@ protected:
|
||||
static PLHashEntry* PR_CALLBACK AllocClusterEntry(void* aPool, const void* aKey) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
|
||||
ClusterEntry* entry = new (*pool) ClusterEntry();
|
||||
ClusterEntry* entry = ClusterEntry::Create(*pool);
|
||||
if (! entry)
|
||||
return nsnull;
|
||||
|
||||
@ -149,24 +255,26 @@ protected:
|
||||
return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
|
||||
|
||||
static void PR_CALLBACK FreeClusterEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
if (aFlag == HT_FREE_ENTRY)
|
||||
delete NS_REINTERPRET_CAST(ClusterEntry*, aHashEntry); }
|
||||
ClusterEntry::Destroy(*pool, NS_REINTERPRET_CAST(ClusterEntry*, aHashEntry)); }
|
||||
|
||||
/**
|
||||
* Maps a MemoryElement to the nsTemplateMatch objects that it
|
||||
* supports. This map allows us to efficiently remove rules from
|
||||
* the conflict set when a MemoryElement is removed.
|
||||
* supports. This map allows us to efficiently remove matches from
|
||||
* the conflict set when a MemoryElement is removed. Conceptually,
|
||||
* a support element is what ``owns'' the match.
|
||||
*/
|
||||
PLHashTable* mSupport;
|
||||
|
||||
class SupportEntry {
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
protected:
|
||||
SupportEntry() : mElement(nsnull)
|
||||
{ MOZ_COUNT_CTOR(nsConflictSet::SupportEntry); }
|
||||
|
||||
@ -174,9 +282,18 @@ protected:
|
||||
delete mElement;
|
||||
MOZ_COUNT_DTOR(nsConflictSet::SupportEntry); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
MemoryElement* mElement;
|
||||
nsTemplateMatchSet mMatchSet;
|
||||
public:
|
||||
static SupportEntry*
|
||||
Create(nsFixedSizeAllocator& aPool) {
|
||||
void* place = aPool.Alloc(sizeof(SupportEntry));
|
||||
return place ? ::new (place) SupportEntry() : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, SupportEntry* aEntry);
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
MemoryElement* mElement;
|
||||
nsTemplateMatchRefSet mMatchSet;
|
||||
};
|
||||
|
||||
static PLHashAllocOps gSupportAllocOps;
|
||||
@ -190,7 +307,7 @@ protected:
|
||||
static PLHashEntry* PR_CALLBACK AllocSupportEntry(void* aPool, const void* aKey) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
|
||||
SupportEntry* entry = new (*pool) SupportEntry();
|
||||
SupportEntry* entry = SupportEntry::Create(*pool);
|
||||
if (! entry)
|
||||
return nsnull;
|
||||
|
||||
@ -200,8 +317,9 @@ protected:
|
||||
return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
|
||||
|
||||
static void PR_CALLBACK FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
if (aFlag == HT_FREE_ENTRY)
|
||||
delete NS_REINTERPRET_CAST(SupportEntry*, aHashEntry); }
|
||||
SupportEntry::Destroy(*pool, NS_REINTERPRET_CAST(SupportEntry*, aHashEntry)); }
|
||||
|
||||
static PLHashNumber PR_CALLBACK HashMemoryElement(const void* aBinding);
|
||||
static PRIntn PR_CALLBACK CompareMemoryElements(const void* aLeft, const void* aRight);
|
||||
@ -215,21 +333,31 @@ protected:
|
||||
PLHashTable* mBindingDependencies;
|
||||
|
||||
class BindingEntry {
|
||||
protected:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
BindingEntry()
|
||||
{ MOZ_COUNT_CTOR(nsConflictSet::BindingEntry); }
|
||||
|
||||
~BindingEntry()
|
||||
{ MOZ_COUNT_DTOR(nsConflictSet::BindingEntry); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
nsTemplateMatchSet mMatchSet;
|
||||
static BindingEntry*
|
||||
Create(nsFixedSizeAllocator& aPool) {
|
||||
void* place = aPool.Alloc(sizeof(BindingEntry));
|
||||
return place ? ::new (place) BindingEntry() : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, BindingEntry* aEntry) {
|
||||
aEntry->~BindingEntry();
|
||||
aPool.Free(aEntry, sizeof(*aEntry)); }
|
||||
|
||||
PLHashEntry mHashEntry;
|
||||
nsTemplateMatchRefSet mMatchSet;
|
||||
};
|
||||
|
||||
static PLHashAllocOps gBindingAllocOps;
|
||||
@ -243,7 +371,7 @@ protected:
|
||||
static PLHashEntry* PR_CALLBACK AllocBindingEntry(void* aPool, const void* aKey) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
|
||||
BindingEntry* entry = new (*pool) BindingEntry();
|
||||
BindingEntry* entry = BindingEntry::Create(*pool);
|
||||
if (! entry)
|
||||
return nsnull;
|
||||
|
||||
@ -256,7 +384,8 @@ protected:
|
||||
if (aFlag == HT_FREE_ENTRY) {
|
||||
nsIRDFResource* key = NS_STATIC_CAST(nsIRDFResource*, NS_CONST_CAST(void*, aHashEntry->key));
|
||||
NS_RELEASE(key);
|
||||
delete NS_REINTERPRET_CAST(BindingEntry*, aHashEntry);
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
BindingEntry::Destroy(*pool, NS_REINTERPRET_CAST(BindingEntry*, aHashEntry));
|
||||
} }
|
||||
|
||||
static PLHashNumber PR_CALLBACK HashBindingElement(const void* aSupport) {
|
||||
|
||||
@ -24,58 +24,39 @@
|
||||
#include "nsContentSupportMap.h"
|
||||
#include "nsIXULContent.h"
|
||||
|
||||
PLHashAllocOps nsContentSupportMap::gAllocOps = {
|
||||
AllocTable, FreeTable, AllocEntry, FreeEntry };
|
||||
PLDHashTableOps nsContentSupportMap::gOps = {
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashGetKeyStub,
|
||||
PL_DHashVoidPtrKeyStub,
|
||||
PL_DHashMatchEntryStub,
|
||||
PL_DHashMoveEntryStub,
|
||||
ClearEntry,
|
||||
PL_DHashFinalizeStub
|
||||
};
|
||||
|
||||
void PR_CALLBACK
|
||||
nsContentSupportMap::ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr)
|
||||
{
|
||||
PL_DHashClearEntryStub(aTable, aHdr);
|
||||
}
|
||||
|
||||
void
|
||||
nsContentSupportMap::Init()
|
||||
{
|
||||
static const size_t kBucketSizes[] = { sizeof(Entry) };
|
||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t);
|
||||
|
||||
// Per news://news.mozilla.org/39BEC105.5090206%40netscape.com
|
||||
static const PRInt32 kInitialSize = 256;
|
||||
|
||||
mPool.Init("nsContentSupportMap", kBucketSizes, kNumBuckets, kInitialSize);
|
||||
|
||||
static const PRInt32 kInitialEntries = 8; // XXX arbitrary
|
||||
|
||||
mMap = PL_NewHashTable(kInitialEntries,
|
||||
HashPointer,
|
||||
PL_CompareValues,
|
||||
PL_CompareValues,
|
||||
&gAllocOps,
|
||||
&mPool);
|
||||
PL_DHashTableInit(&mMap, &gOps, nsnull, sizeof(Entry), PL_DHASH_MIN_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
nsContentSupportMap::Finish()
|
||||
{
|
||||
PL_HashTableDestroy(mMap);
|
||||
PL_DHashTableFinish(&mMap);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSupportMap::Put(nsIContent* aElement, nsTemplateMatch* aMatch)
|
||||
{
|
||||
PLHashEntry* he = PL_HashTableAdd(mMap, aElement, nsnull);
|
||||
if (! he)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// "Fix up" the entry's value to refer to the mMatch that's built
|
||||
// in to the Entry object.
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, he);
|
||||
entry->mHashEntry.value = &entry->mMatch;
|
||||
entry->mMatch = aMatch;
|
||||
aMatch->AddRef();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsContentSupportMap::Remove(nsIContent* aElement)
|
||||
{
|
||||
PL_HashTableRemove(mMap, aElement);
|
||||
PL_DHashTableOperate(&mMap, aElement, PL_DHASH_REMOVE);
|
||||
|
||||
PRInt32 count;
|
||||
|
||||
@ -101,13 +82,3 @@ nsContentSupportMap::Remove(nsIContent* aElement)
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsContentSupportMap::Get(nsIContent* aElement, nsTemplateMatch** aMatch)
|
||||
{
|
||||
nsTemplateMatch** match = NS_STATIC_CAST(nsTemplateMatch**, PL_HashTableLookup(mMap, aElement));
|
||||
if (! match)
|
||||
return PR_FALSE;
|
||||
|
||||
*aMatch = *match;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#ifndef nsContentSupportMap_h__
|
||||
#define nsContentSupportMap_h__
|
||||
|
||||
#include "plhash.h"
|
||||
#include "pldhash.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsTemplateMatch.h"
|
||||
|
||||
@ -43,57 +43,46 @@ public:
|
||||
nsContentSupportMap() { Init(); }
|
||||
~nsContentSupportMap() { Finish(); }
|
||||
|
||||
nsresult Put(nsIContent* aElement, nsTemplateMatch* aMatch);
|
||||
PRBool Get(nsIContent* aElement, nsTemplateMatch** aMatch);
|
||||
nsresult Put(nsIContent* aElement, nsTemplateMatch* aMatch) {
|
||||
PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mMap, aElement, PL_DHASH_ADD);
|
||||
if (!hdr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, hdr);
|
||||
NS_ASSERTION(entry->mMatch == nsnull, "over-writing entry");
|
||||
entry->mContent = aElement;
|
||||
entry->mMatch = aMatch;
|
||||
return NS_OK; }
|
||||
|
||||
PRBool Get(nsIContent* aElement, nsTemplateMatch** aMatch) {
|
||||
PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mMap, aElement, PL_DHASH_LOOKUP);
|
||||
if (PL_DHASH_ENTRY_IS_FREE(hdr))
|
||||
return PR_FALSE;
|
||||
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, hdr);
|
||||
*aMatch = entry->mMatch;
|
||||
return PR_TRUE; }
|
||||
|
||||
nsresult Remove(nsIContent* aElement);
|
||||
|
||||
void Clear() { Finish(); Init(); }
|
||||
|
||||
protected:
|
||||
PLHashTable* mMap;
|
||||
nsFixedSizeAllocator mPool;
|
||||
PLDHashTable mMap;
|
||||
|
||||
void Init();
|
||||
void Finish();
|
||||
|
||||
struct Entry {
|
||||
PLHashEntry mHashEntry;
|
||||
PLDHashEntryHdr mHdr;
|
||||
nsIContent* mContent;
|
||||
nsTemplateMatch* mMatch;
|
||||
};
|
||||
|
||||
static PLHashAllocOps gAllocOps;
|
||||
|
||||
static void* PR_CALLBACK
|
||||
AllocTable(void* aPool, PRSize aSize) {
|
||||
return new char[aSize]; };
|
||||
static PLDHashTableOps gOps;
|
||||
|
||||
static void PR_CALLBACK
|
||||
FreeTable(void* aPool, void* aItem) {
|
||||
delete[] NS_STATIC_CAST(char*, aItem); }
|
||||
|
||||
static PLHashEntry* PR_CALLBACK
|
||||
AllocEntry(void* aPool, const void* aKey) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
|
||||
Entry* entry = NS_STATIC_CAST(Entry*, pool->Alloc(sizeof(Entry)));
|
||||
if (! entry)
|
||||
return nsnull;
|
||||
|
||||
return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
|
||||
|
||||
static void PR_CALLBACK
|
||||
FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) {
|
||||
if (aFlag == HT_FREE_ENTRY) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry);
|
||||
|
||||
if (entry->mMatch)
|
||||
entry->mMatch->Release();
|
||||
|
||||
nsFixedSizeAllocator::Free(entry, sizeof(Entry));
|
||||
} }
|
||||
|
||||
static PLHashNumber PR_CALLBACK
|
||||
HashPointer(const void* aKey) {
|
||||
return PLHashNumber(aKey) >> 3; }
|
||||
ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -131,8 +131,9 @@ nsContentTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void*
|
||||
}
|
||||
|
||||
if (consistent) {
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_ICONTENT(contentValue));
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_ICONTENT(contentValue));
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -166,8 +167,8 @@ nsContentTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void*
|
||||
Instantiation newinst = *inst;
|
||||
newinst.AddAssignment(mIdVariable, Value(resource.get()));
|
||||
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(content);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(), content);
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -211,7 +212,8 @@ nsContentTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void*
|
||||
Instantiation newinst = *inst;
|
||||
newinst.AddAssignment(mContentVariable, Value(content.get()));
|
||||
|
||||
Element* element = new (mConflictSet.GetPool()) Element(content);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(), content);
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -47,19 +47,29 @@ public:
|
||||
GetAncestorVariables(VariableSet& aVariables) const;
|
||||
|
||||
class Element : public MemoryElement {
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Element(nsIContent* aContent)
|
||||
: mContent(aContent) {
|
||||
MOZ_COUNT_CTOR(nsContentTestNode::Element); }
|
||||
|
||||
virtual ~Element() { MOZ_COUNT_DTOR(nsContentTestNode::Element); }
|
||||
|
||||
static Element*
|
||||
Create(nsFixedSizeAllocator& aPool, nsIContent* aContent) {
|
||||
void* place = aPool.Alloc(sizeof(Element));
|
||||
return place ? ::new (place) Element(aContent) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Element* aElement) {
|
||||
aElement->~Element();
|
||||
aPool.Free(aElement, sizeof(*aElement)); }
|
||||
|
||||
virtual const char* Type() const {
|
||||
return "nsContentTestNode::Element"; }
|
||||
|
||||
@ -74,8 +84,7 @@ public:
|
||||
return PR_FALSE; }
|
||||
|
||||
virtual MemoryElement* Clone(void* aPool) const {
|
||||
return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool))
|
||||
Element(mContent); }
|
||||
return Create(*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool), mContent); }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
|
||||
@ -62,17 +62,22 @@ nsInstantiationNode::Propogate(const InstantiationSet& aInstantiations, void* aC
|
||||
for (InstantiationSet::ConstIterator inst = aInstantiations.First(); inst != last; ++inst) {
|
||||
nsAssignmentSet assignments = inst->mAssignments;
|
||||
|
||||
nsTemplateMatch* match = new (mConflictSet.GetPool()) nsTemplateMatch(mRule, *inst, assignments);
|
||||
nsTemplateMatch* match =
|
||||
nsTemplateMatch::Create(mConflictSet.GetPool(), mRule, *inst, assignments);
|
||||
|
||||
if (! match)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Temporarily AddRef() to keep the match alive.
|
||||
match->AddRef();
|
||||
|
||||
mRule->InitBindings(mConflictSet, match);
|
||||
|
||||
mConflictSet.Add(match);
|
||||
|
||||
// Give back our "local" reference. The conflict set will have
|
||||
// taken what it needs.
|
||||
match->Release();
|
||||
match->Release(mConflictSet.GetPool());
|
||||
|
||||
newkeys->Add(nsClusterKey(*inst, mRule));
|
||||
}
|
||||
|
||||
@ -75,8 +75,8 @@ nsOutlinerRowTestNode::FilterInstantiations(InstantiationSet& aInstantiations, v
|
||||
(mRows.Find(mConflictSet, container) != mRows.Last())) {
|
||||
|
||||
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG, (" => passed"));
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(container);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(), container);
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -47,19 +47,29 @@ public:
|
||||
GetAncestorVariables(VariableSet& aVariables) const;
|
||||
|
||||
class Element : public MemoryElement {
|
||||
protected:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) { }
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Element(nsIRDFResource* aResource)
|
||||
: mResource(aResource) {
|
||||
MOZ_COUNT_CTOR(nsOutlinerRowTestNode::Element); }
|
||||
|
||||
virtual ~Element() { MOZ_COUNT_DTOR(nsOutlinerRowTestNode::Element); }
|
||||
|
||||
static Element*
|
||||
Create(nsFixedSizeAllocator& aPool, nsIRDFResource* aResource) {
|
||||
void* place = aPool.Alloc(sizeof(Element));
|
||||
return place ? ::new (place) Element(aResource) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Element* aElement) {
|
||||
aElement->~Element();
|
||||
aPool.Free(aElement, sizeof(*aElement)); }
|
||||
|
||||
virtual const char* Type() const {
|
||||
return "nsOutlinerRowTestNode::Element"; }
|
||||
|
||||
@ -74,8 +84,7 @@ public:
|
||||
return PR_FALSE; }
|
||||
|
||||
virtual MemoryElement* Clone(void* aPool) const {
|
||||
return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool))
|
||||
Element(mResource); }
|
||||
return Create(*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool), mResource); }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIRDFResource> mResource;
|
||||
|
||||
@ -172,9 +172,10 @@ nsRDFConInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations
|
||||
(empty == mEmpty) ? "consistent" : "inconsistent"));
|
||||
|
||||
if (empty == mEmpty) {
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(value),
|
||||
mContainer, mEmpty);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(value),
|
||||
mContainer, mEmpty);
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -233,8 +234,10 @@ nsRDFConInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations
|
||||
(container == mContainer) ? "consistent" : "inconsistent"));
|
||||
|
||||
if (container == mContainer) {
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(value), mContainer, mEmpty);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(value),
|
||||
mContainer, mEmpty);
|
||||
|
||||
|
||||
if (! element)
|
||||
|
||||
@ -67,13 +67,13 @@ public:
|
||||
|
||||
|
||||
class Element : public MemoryElement {
|
||||
protected:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Element(nsIRDFResource* aContainer,
|
||||
Test aContainerTest,
|
||||
Test aEmptyTest)
|
||||
@ -84,6 +84,17 @@ public:
|
||||
|
||||
virtual ~Element() { MOZ_COUNT_DTOR(nsRDFConInstanceTestNode::Element); }
|
||||
|
||||
static Element*
|
||||
Create(nsFixedSizeAllocator& aPool, nsIRDFResource* aContainer,
|
||||
Test aContainerTest, Test aEmptyTest) {
|
||||
void* place = aPool.Alloc(sizeof(Element));
|
||||
return place ? ::new (place) Element(aContainer, aContainerTest, aEmptyTest) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Element* aElement) {
|
||||
aElement->~Element();
|
||||
aPool.Free(aElement, sizeof(*aElement)); }
|
||||
|
||||
virtual const char* Type() const {
|
||||
return "nsRDFConInstanceTestNode::Element"; }
|
||||
|
||||
@ -102,8 +113,8 @@ public:
|
||||
return PR_FALSE; }
|
||||
|
||||
virtual MemoryElement* Clone(void* aPool) const {
|
||||
return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool))
|
||||
Element(mContainer, mContainerTest, mEmptyTest); }
|
||||
return Create(*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool),
|
||||
mContainer, mContainerTest, mEmptyTest); }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIRDFResource> mContainer;
|
||||
|
||||
@ -183,9 +183,10 @@ nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
|
||||
|
||||
if (isconsistent) {
|
||||
// Add a memory element to our set-of-support.
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(containerValue),
|
||||
VALUE_TO_IRDFNODE(memberValue));
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(containerValue),
|
||||
VALUE_TO_IRDFNODE(memberValue));
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -238,8 +239,10 @@ nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
|
||||
Instantiation newinst = *inst;
|
||||
newinst.AddAssignment(mMemberVariable, Value(node.get()));
|
||||
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(containerValue), node);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(containerValue),
|
||||
node);
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -329,8 +332,10 @@ nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
|
||||
Instantiation newinst = *inst;
|
||||
newinst.AddAssignment(mContainerVariable, Value(source.get()));
|
||||
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(source, VALUE_TO_IRDFNODE(memberValue));
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
source,
|
||||
VALUE_TO_IRDFNODE(memberValue));
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -424,14 +429,14 @@ nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations,
|
||||
|
||||
Element* element;
|
||||
if (hasContainerBinding) {
|
||||
element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(containerValue),
|
||||
VALUE_TO_IRDFNODE(value));
|
||||
element = Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(containerValue),
|
||||
VALUE_TO_IRDFNODE(value));
|
||||
}
|
||||
else {
|
||||
element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(value),
|
||||
VALUE_TO_IRDFNODE(memberValue));
|
||||
element = Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(value),
|
||||
VALUE_TO_IRDFNODE(memberValue));
|
||||
}
|
||||
|
||||
if (! element)
|
||||
|
||||
@ -63,13 +63,13 @@ public:
|
||||
nsTemplateMatchSet& aRetractions) const;
|
||||
|
||||
class Element : public MemoryElement {
|
||||
protected:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Element(nsIRDFResource* aContainer,
|
||||
nsIRDFNode* aMember)
|
||||
: mContainer(aContainer),
|
||||
@ -78,6 +78,18 @@ public:
|
||||
|
||||
virtual ~Element() { MOZ_COUNT_DTOR(nsRDFConMemberTestNode::Element); }
|
||||
|
||||
static Element*
|
||||
Create(nsFixedSizeAllocator& aPool,
|
||||
nsIRDFResource* aContainer,
|
||||
nsIRDFNode* aMember) {
|
||||
void* place = aPool.Alloc(sizeof(Element));
|
||||
return place ? ::new (place) Element(aContainer, aMember) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Element* aElement) {
|
||||
aElement->~Element();
|
||||
aPool.Free(aElement, sizeof(*aElement)); }
|
||||
|
||||
virtual const char* Type() const {
|
||||
return "nsRDFConMemberTestNode::Element"; }
|
||||
|
||||
@ -93,8 +105,8 @@ public:
|
||||
return PR_FALSE; }
|
||||
|
||||
virtual MemoryElement* Clone(void* aPool) const {
|
||||
return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool))
|
||||
Element(mContainer, mMember); }
|
||||
return Create(*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool),
|
||||
mContainer, mMember); }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIRDFResource> mContainer;
|
||||
|
||||
@ -187,10 +187,11 @@ nsRDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations, v
|
||||
|
||||
if (hasAssertion) {
|
||||
// it's consistent.
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(sourceValue),
|
||||
mProperty,
|
||||
VALUE_TO_IRDFNODE(targetValue));
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(sourceValue),
|
||||
mProperty,
|
||||
VALUE_TO_IRDFNODE(targetValue));
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -286,10 +287,11 @@ nsRDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations, v
|
||||
Instantiation newinst = *inst;
|
||||
newinst.AddAssignment(variable, value);
|
||||
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(VALUE_TO_IRDFRESOURCE(sourceValue),
|
||||
mProperty,
|
||||
VALUE_TO_IRDFNODE(targetValue));
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(),
|
||||
VALUE_TO_IRDFRESOURCE(sourceValue),
|
||||
mProperty,
|
||||
VALUE_TO_IRDFNODE(targetValue));
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -82,13 +82,13 @@ public:
|
||||
|
||||
|
||||
class Element : public MemoryElement {
|
||||
protected:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Element(nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget)
|
||||
@ -99,6 +99,19 @@ public:
|
||||
|
||||
virtual ~Element() { MOZ_COUNT_DTOR(nsRDFPropertyTestNode::Element); }
|
||||
|
||||
static Element*
|
||||
Create(nsFixedSizeAllocator& aPool,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget) {
|
||||
void* place = aPool.Alloc(sizeof(Element));
|
||||
return place ? ::new (place) Element(aSource, aProperty, aTarget) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Element* aElement) {
|
||||
aElement->~Element();
|
||||
aPool.Free(aElement, sizeof(*aElement)); }
|
||||
|
||||
virtual const char* Type() const {
|
||||
return "nsRDFPropertyTestNode::Element"; }
|
||||
|
||||
@ -117,8 +130,8 @@ public:
|
||||
return PR_FALSE; }
|
||||
|
||||
virtual MemoryElement* Clone(void* aPool) const {
|
||||
return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool))
|
||||
Element(mSource, mProperty, mTarget); }
|
||||
return Create(*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool),
|
||||
mSource, mProperty, mTarget); }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIRDFResource> mSource;
|
||||
|
||||
@ -79,20 +79,6 @@ ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
|
||||
PL_DHashClearEntryStub(aTable, aEntry);
|
||||
}
|
||||
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
RemoveEach(PLDHashTable* aTable, PLDHashEntryHdr* aEntry, PRUint32 aNumber, void* aArg)
|
||||
{
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
static void PR_CALLBACK
|
||||
FinalizeTable(PLDHashTable* aTable)
|
||||
{
|
||||
PL_DHashTableEnumerate(aTable, RemoveEach, nsnull);
|
||||
PL_DHashFinalizeStub(aTable);
|
||||
}
|
||||
|
||||
PLDHashTableOps nsRuleNetwork::gOps = {
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
@ -101,7 +87,7 @@ PLDHashTableOps nsRuleNetwork::gOps = {
|
||||
MatchEntry,
|
||||
PL_DHashMoveEntryStub,
|
||||
ClearEntry,
|
||||
FinalizeTable
|
||||
PL_DHashFinalizeStub
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsResourceSet.h"
|
||||
#include "nsRuleNetwork.h"
|
||||
#include <new>
|
||||
|
||||
/**
|
||||
* A "match" is a fully instantiated rule; that is, a complete and
|
||||
@ -42,24 +43,36 @@ class nsConflictSet;
|
||||
class nsTemplateRule;
|
||||
|
||||
class nsTemplateMatch {
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
void* operator new(size_t) { return 0; }
|
||||
void operator delete(void*, size_t) {}
|
||||
|
||||
protected:
|
||||
PRInt32 mRefCnt;
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
nsTemplateMatch(const nsTemplateRule* aRule,
|
||||
const Instantiation& aInstantiation,
|
||||
const nsAssignmentSet& aAssignments)
|
||||
: mRefCnt(1),
|
||||
const Instantiation& aInstantiation,
|
||||
const nsAssignmentSet& aAssignments)
|
||||
: mRefCnt(0),
|
||||
mRule(aRule),
|
||||
mInstantiation(aInstantiation),
|
||||
mAssignments(aAssignments)
|
||||
{ MOZ_COUNT_CTOR(nsTemplateMatch); }
|
||||
mAssignments(aAssignments) {}
|
||||
|
||||
public:
|
||||
static nsTemplateMatch*
|
||||
Create(nsFixedSizeAllocator& aPool,
|
||||
const nsTemplateRule* aRule,
|
||||
const Instantiation& aInstantiation,
|
||||
const nsAssignmentSet& aAssignments) {
|
||||
void* place = aPool.Alloc(sizeof(nsTemplateMatch));
|
||||
return place ? ::new (place) nsTemplateMatch(aRule, aInstantiation, aAssignments) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, nsTemplateMatch* aMatch) {
|
||||
aMatch->~nsTemplateMatch();
|
||||
aPool.Free(aMatch, sizeof(*aMatch)); }
|
||||
|
||||
PRBool operator==(const nsTemplateMatch& aMatch) const {
|
||||
return mRule == aMatch.mRule && mInstantiation == aMatch.mInstantiation; }
|
||||
@ -104,17 +117,19 @@ public:
|
||||
*/
|
||||
nsResourceSet mBindingDependencies;
|
||||
|
||||
PRInt32 AddRef() { return ++mRefCnt; }
|
||||
PRInt32 AddRef() {
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "nsTemplateMatch", sizeof(*this));
|
||||
return mRefCnt; }
|
||||
|
||||
PRInt32 Release() {
|
||||
PRInt32 Release(nsFixedSizeAllocator& aPool) {
|
||||
NS_PRECONDITION(mRefCnt > 0, "bad refcnt");
|
||||
PRInt32 refcnt = --mRefCnt;
|
||||
if (refcnt == 0) delete this;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "nsTemplateMatch");
|
||||
if (refcnt == 0)
|
||||
Destroy(aPool, this);
|
||||
return refcnt; }
|
||||
|
||||
protected:
|
||||
~nsTemplateMatch() { MOZ_COUNT_DTOR(nsTemplateMatch); }
|
||||
|
||||
private:
|
||||
nsTemplateMatch(const nsTemplateMatch& aMatch); // not to be implemented
|
||||
void operator=(const nsTemplateMatch& aMatch); // not to be implemented
|
||||
|
||||
@ -24,174 +24,326 @@
|
||||
#include "nsTemplateMatchSet.h"
|
||||
#include "nsTemplateRule.h"
|
||||
|
||||
PLHashAllocOps nsTemplateMatchSet::gAllocOps = {
|
||||
AllocTable, FreeTable, AllocEntry, FreeEntry };
|
||||
|
||||
|
||||
nsTemplateMatchSet::nsTemplateMatchSet()
|
||||
: mMatches(nsnull), mCount(0), mLastMatch(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsTemplateMatchSet);
|
||||
mHead.mNext = mHead.mPrev = &mHead;
|
||||
}
|
||||
|
||||
#ifdef NEED_CPP_UNUSED_IMPLEMENTATIONS
|
||||
nsTemplateMatchSet::nsTemplateMatchSet(const nsTemplateMatchSet& aMatchSet) {}
|
||||
void nsTemplateMatchSet::operator=(const nsTemplateMatchSet& aMatchSet) {}
|
||||
#ifdef DEBUG_waterson
|
||||
#define NSTEMPLATEMATCHREFSET_METER // collect stats about match set sizes
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsTemplateMatchSet
|
||||
//
|
||||
|
||||
nsTemplateMatchSet::~nsTemplateMatchSet()
|
||||
{
|
||||
if (mMatches) {
|
||||
PL_HashTableDestroy(mMatches);
|
||||
mMatches = nsnull;
|
||||
while (mHead) {
|
||||
Element* doomed = mHead;
|
||||
mHead = mHead->mNext;
|
||||
doomed->mMatch->Release(mPool);
|
||||
delete doomed;
|
||||
}
|
||||
|
||||
Clear();
|
||||
MOZ_COUNT_DTOR(nsTemplateMatchSet);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsTemplateMatchRefSet
|
||||
//
|
||||
|
||||
nsTemplateMatchSet::Iterator
|
||||
nsTemplateMatchSet::Insert(nsFixedSizeAllocator& aPool, Iterator aIterator, nsTemplateMatch* aMatch)
|
||||
PLDHashTableOps nsTemplateMatchRefSet::gOps = {
|
||||
PL_DHashAllocTable,
|
||||
PL_DHashFreeTable,
|
||||
PL_DHashGetKeyStub,
|
||||
HashEntry,
|
||||
MatchEntry,
|
||||
PL_DHashMoveEntryStub,
|
||||
PL_DHashClearEntryStub,
|
||||
PL_DHashFinalizeStub
|
||||
};
|
||||
|
||||
PLDHashNumber PR_CALLBACK
|
||||
nsTemplateMatchRefSet::HashEntry(PLDHashTable* aTable, const void* aKey)
|
||||
{
|
||||
if (++mCount > kHashTableThreshold && !mMatches) {
|
||||
// If we've exceeded a high-water mark, then hash everything.
|
||||
mMatches = PL_NewHashTable(2 * kHashTableThreshold,
|
||||
HashMatch,
|
||||
CompareMatches,
|
||||
PL_CompareValues,
|
||||
&gAllocOps,
|
||||
&aPool);
|
||||
|
||||
Iterator last = Last();
|
||||
for (Iterator match = First(); match != last; ++match) {
|
||||
// The sole purpose of the hashtable is to make
|
||||
// determining nsTemplateMatchSet membership an O(1)
|
||||
// operation. Since the linked list is maintaining
|
||||
// storage, we can use a pointer to the nsTemplateMatch object
|
||||
// (obtained from the iterator) as the key. We'll just
|
||||
// stuff something non-zero into the table as a value.
|
||||
PL_HashTableAdd(mMatches, match.operator->(), match.mCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
List* newelement = new (aPool) List();
|
||||
if (newelement) {
|
||||
newelement->mMatch = aMatch;
|
||||
aMatch->AddRef();
|
||||
|
||||
aIterator.mCurrent->mPrev->mNext = newelement;
|
||||
|
||||
newelement->mNext = aIterator.mCurrent;
|
||||
newelement->mPrev = aIterator.mCurrent->mPrev;
|
||||
|
||||
aIterator.mCurrent->mPrev = newelement;
|
||||
|
||||
if (mMatches)
|
||||
PL_HashTableAdd(mMatches, newelement->mMatch, newelement);
|
||||
}
|
||||
return aIterator;
|
||||
const nsTemplateMatch* match = NS_STATIC_CAST(const nsTemplateMatch*, aKey);
|
||||
return PLDHashNumber(Instantiation::Hash(&(match->mInstantiation)))
|
||||
^ (PLDHashNumber(match->mRule) >> 2);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsTemplateMatchSet::CopyInto(nsTemplateMatchSet& aMatchSet, nsFixedSizeAllocator& aPool) const
|
||||
PRBool PR_CALLBACK
|
||||
nsTemplateMatchRefSet::MatchEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aHdr, const void* aKey)
|
||||
{
|
||||
aMatchSet.Clear();
|
||||
for (nsTemplateMatchSet::ConstIterator match = First(); match != Last(); ++match)
|
||||
aMatchSet.Add(aPool, NS_CONST_CAST(nsTemplateMatch*, match.operator->()));
|
||||
const Entry* entry = NS_REINTERPRET_CAST(const Entry*, aHdr);
|
||||
const nsTemplateMatch* left = entry->mMatch;
|
||||
const nsTemplateMatch* right = NS_STATIC_CAST(const nsTemplateMatch*, aKey);
|
||||
return *left == *right;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#ifdef NSTEMPLATEMATCHREFSET_METER
|
||||
#include "nsVoidArray.h"
|
||||
static PRInt32 gCount;
|
||||
static nsVoidArray gCountDistribution;
|
||||
#endif
|
||||
|
||||
void
|
||||
nsTemplateMatchRefSet::Init()
|
||||
{
|
||||
#ifdef NSTEMPLATEMATCHREFSET_METER
|
||||
++gCount;
|
||||
#endif
|
||||
mInlineMatches.mCount = 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsTemplateMatchSet::Clear()
|
||||
nsTemplateMatchRefSet::Finish()
|
||||
{
|
||||
Iterator match = First();
|
||||
while (match != Last())
|
||||
Erase(match++);
|
||||
}
|
||||
#ifdef NSTEMPLATEMATCHREFSET_METER
|
||||
{
|
||||
PRInt32 entries = mInlineMatches.mCount <= kMaxInlineMatches
|
||||
? PRInt32(mInlineMatches.mCount)
|
||||
: mTable.entryCount;
|
||||
|
||||
nsTemplateMatchSet::ConstIterator
|
||||
nsTemplateMatchSet::Find(const nsTemplateMatch& aMatch) const
|
||||
{
|
||||
if (mMatches) {
|
||||
List* list = NS_STATIC_CAST(List*, PL_HashTableLookup(mMatches, &aMatch));
|
||||
if (list)
|
||||
return ConstIterator(list);
|
||||
}
|
||||
else {
|
||||
ConstIterator last = Last();
|
||||
for (ConstIterator i = First(); i != last; ++i) {
|
||||
if (*i == aMatch)
|
||||
return i;
|
||||
PRInt32 count = PRInt32(gCountDistribution[entries]);
|
||||
gCountDistribution.ReplaceElementAt((void*) ++count, entries);
|
||||
|
||||
--gCount;
|
||||
if (gCount == 0) {
|
||||
printf("nsTemplateMatchRefSet distribution\n");
|
||||
for (PRInt32 i = gCountDistribution.Count() - 1; i >= 0; --i)
|
||||
printf("%d: %d\n", i, gCountDistribution[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return Last();
|
||||
}
|
||||
if (mInlineMatches.mCount > kMaxInlineMatches)
|
||||
// It's a hashtable, so finish the table properly
|
||||
PL_DHashTableFinish(&mTable);
|
||||
|
||||
nsTemplateMatchSet::Iterator
|
||||
nsTemplateMatchSet::Find(const nsTemplateMatch& aMatch)
|
||||
{
|
||||
if (mMatches) {
|
||||
List* list = NS_STATIC_CAST(List*, PL_HashTableLookup(mMatches, &aMatch));
|
||||
if (list)
|
||||
return Iterator(list);
|
||||
}
|
||||
else {
|
||||
Iterator last = Last();
|
||||
for (Iterator i = First(); i != last; ++i) {
|
||||
if (*i == aMatch)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return Last();
|
||||
}
|
||||
|
||||
nsTemplateMatch*
|
||||
nsTemplateMatchSet::FindMatchWithHighestPriority() const
|
||||
{
|
||||
// Find the rule with the "highest priority"; i.e., the rule with
|
||||
// the lowest value for GetPriority().
|
||||
nsTemplateMatch* result = nsnull;
|
||||
PRInt32 max = ~(1 << 31); // XXXwaterson portable?
|
||||
for (ConstIterator match = First(); match != Last(); ++match) {
|
||||
PRInt32 priority = match->mRule->GetPriority();
|
||||
if (priority < max) {
|
||||
result = NS_CONST_CAST(nsTemplateMatch*, match.operator->());
|
||||
max = priority;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsTemplateMatchSet::Iterator
|
||||
nsTemplateMatchSet::Erase(Iterator aIterator)
|
||||
{
|
||||
Iterator result = aIterator;
|
||||
|
||||
--mCount;
|
||||
|
||||
if (mMatches)
|
||||
PL_HashTableRemove(mMatches, aIterator.operator->());
|
||||
|
||||
++result;
|
||||
aIterator.mCurrent->mNext->mPrev = aIterator.mCurrent->mPrev;
|
||||
aIterator.mCurrent->mPrev->mNext = aIterator.mCurrent->mNext;
|
||||
|
||||
aIterator->Release();
|
||||
delete aIterator.mCurrent;
|
||||
return result;
|
||||
mInlineMatches.mCount = 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsTemplateMatchSet::Remove(nsTemplateMatch* aMatch)
|
||||
nsTemplateMatchRefSet::CopyFrom(const nsTemplateMatchRefSet& aSet)
|
||||
{
|
||||
Iterator doomed = Find(*aMatch);
|
||||
if (doomed != Last())
|
||||
Erase(doomed);
|
||||
ConstIterator last = aSet.Last();
|
||||
for (ConstIterator iter = aSet.First(); iter != last; ++iter)
|
||||
Add(iter.operator->());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTemplateMatchRefSet::Empty() const
|
||||
{
|
||||
PRUint32 count = mInlineMatches.mCount;
|
||||
if (count <= kMaxInlineMatches)
|
||||
return count == 0;
|
||||
|
||||
return mTable.entryCount == 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTemplateMatchRefSet::Contains(const nsTemplateMatch* aMatch) const
|
||||
{
|
||||
PRUint32 count = mInlineMatches.mCount;
|
||||
if (count <= kMaxInlineMatches) {
|
||||
while (PRInt32(--count) >= 0) {
|
||||
if (*(mInlineMatches.mEntries[count]) == *aMatch)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PLDHashEntryHdr* hdr =
|
||||
PL_DHashTableOperate(NS_CONST_CAST(PLDHashTable*, &mTable), aMatch,
|
||||
PL_DHASH_LOOKUP);
|
||||
|
||||
return PL_DHASH_ENTRY_IS_BUSY(hdr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTemplateMatchRefSet::Add(const nsTemplateMatch* aMatch)
|
||||
{
|
||||
// Cast away const, we assume shared ownership.
|
||||
nsTemplateMatch* match = NS_CONST_CAST(nsTemplateMatch*, aMatch);
|
||||
|
||||
PRUint32 count = mInlineMatches.mCount;
|
||||
if (count < kMaxInlineMatches) {
|
||||
// There's still room in the inline matches.
|
||||
|
||||
// Check for duplicates
|
||||
for (PRInt32 i = PRInt32(count) - 1; i >= 0; --i) {
|
||||
if (*(mInlineMatches.mEntries[i]) == *aMatch)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Nope. Add it!
|
||||
mInlineMatches.mEntries[count] = match;
|
||||
|
||||
++mInlineMatches.mCount;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (count == kMaxInlineMatches) {
|
||||
// No room left in inline matches. Fault, and convert to
|
||||
// hashtable.
|
||||
nsTemplateMatch* temp[kMaxInlineMatches];
|
||||
PRInt32 i;
|
||||
|
||||
// Copy pointers to a safe place
|
||||
for (i = count - 1; i >= 0; --i)
|
||||
temp[i] = mInlineMatches.mEntries[i];
|
||||
|
||||
// Clobber the union; we'll treat it as a hashtable now.
|
||||
PL_DHashTableInit(&mTable, &gOps, nsnull, sizeof(Entry), PL_DHASH_MIN_SIZE);
|
||||
|
||||
// Now that we've table-ized this thing, mCount better be a
|
||||
// big freaking number, since it's sharing space with a
|
||||
// pointer to the PLDHashTable's ops.
|
||||
NS_ASSERTION(mInlineMatches.mCount > kMaxInlineMatches,
|
||||
"wow, I thought it'd be bigger than _that_");
|
||||
|
||||
// Copy the pointers into the hashtable.
|
||||
for (i = count - 1; i >= 0; --i)
|
||||
AddToTable(temp[i]);
|
||||
}
|
||||
|
||||
return AddToTable(match);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTemplateMatchRefSet::AddToTable(nsTemplateMatch* aMatch)
|
||||
{
|
||||
PLDHashEntryHdr* hdr =
|
||||
PL_DHashTableOperate(&mTable, aMatch, PL_DHASH_ADD);
|
||||
|
||||
if (hdr) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, hdr);
|
||||
|
||||
if (! entry->mMatch) {
|
||||
entry->mMatch = aMatch;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTemplateMatchRefSet::Remove(const nsTemplateMatch* aMatch)
|
||||
{
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
PRUint32 count = mInlineMatches.mCount;
|
||||
if (count <= kMaxInlineMatches) {
|
||||
nsTemplateMatch** last;
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsTemplateMatch** entry = &mInlineMatches.mEntries[i];
|
||||
nsTemplateMatch* match = *entry;
|
||||
|
||||
if (*match == *aMatch) {
|
||||
found = PR_TRUE;
|
||||
}
|
||||
else if (found)
|
||||
*last = match;
|
||||
|
||||
last = entry;
|
||||
}
|
||||
|
||||
if (found)
|
||||
--mInlineMatches.mCount;
|
||||
}
|
||||
else {
|
||||
PLDHashEntryHdr* hdr =
|
||||
PL_DHashTableOperate(&mTable, aMatch, PL_DHASH_LOOKUP);
|
||||
|
||||
found = PL_DHASH_ENTRY_IS_BUSY(hdr);
|
||||
|
||||
if (found)
|
||||
// Remove the match. N.B., we never demote back to a list.
|
||||
PL_DHashTableOperate(&mTable, aMatch, PL_DHASH_REMOVE);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// ConstIterator
|
||||
//
|
||||
|
||||
#define ENTRY_IS_LIVE(entry) (PL_DHASH_ENTRY_IS_BUSY(&((entry)->mHdr)) && (entry)->mMatch)
|
||||
|
||||
nsTemplateMatchRefSet::ConstIterator
|
||||
nsTemplateMatchRefSet::First() const
|
||||
{
|
||||
if (mInlineMatches.mCount <= kMaxInlineMatches)
|
||||
return ConstIterator(this, NS_CONST_CAST(nsTemplateMatch**, mInlineMatches.mEntries));
|
||||
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, mTable.entryStore);
|
||||
Entry* limit = entry + PR_BIT(mTable.sizeLog2);
|
||||
for ( ; entry < limit; ++entry) {
|
||||
if (ENTRY_IS_LIVE(entry))
|
||||
break;
|
||||
}
|
||||
|
||||
return ConstIterator(this, entry);
|
||||
}
|
||||
|
||||
nsTemplateMatchRefSet::ConstIterator
|
||||
nsTemplateMatchRefSet::Last() const
|
||||
{
|
||||
PRUint32 count = mInlineMatches.mCount;
|
||||
if (count <= kMaxInlineMatches) {
|
||||
nsTemplateMatch** first = NS_CONST_CAST(nsTemplateMatch**, mInlineMatches.mEntries);
|
||||
nsTemplateMatch** limit = first + count;
|
||||
return ConstIterator(this, limit);
|
||||
}
|
||||
|
||||
Entry* limit = NS_REINTERPRET_CAST(Entry*, mTable.entryStore);
|
||||
limit += PR_BIT(mTable.sizeLog2);
|
||||
return ConstIterator(this, limit);
|
||||
}
|
||||
|
||||
void
|
||||
nsTemplateMatchRefSet::ConstIterator::Next()
|
||||
{
|
||||
if (mSet->mInlineMatches.mCount <= kMaxInlineMatches)
|
||||
++mInlineEntry;
|
||||
else {
|
||||
const PLDHashTable& table = mSet->mTable;
|
||||
Entry* limit = NS_REINTERPRET_CAST(Entry*, table.entryStore);
|
||||
limit += PR_BIT(table.sizeLog2);
|
||||
while (++mTableEntry < limit) {
|
||||
if (ENTRY_IS_LIVE(mTableEntry))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTemplateMatchRefSet::ConstIterator::Prev()
|
||||
{
|
||||
if (mSet->mInlineMatches.mCount <= kMaxInlineMatches)
|
||||
--mInlineEntry;
|
||||
else {
|
||||
const PLDHashTable& table = mSet->mTable;
|
||||
Entry* limit = NS_REINTERPRET_CAST(Entry*, table.entryStore);
|
||||
while (--mTableEntry > limit) {
|
||||
if (ENTRY_IS_LIVE(mTableEntry))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTemplateMatchRefSet::ConstIterator::operator==(const ConstIterator& aConstIterator) const
|
||||
{
|
||||
if (mSet != aConstIterator.mSet)
|
||||
return PR_FALSE;
|
||||
|
||||
PRUint32 count = mSet->mInlineMatches.mCount;
|
||||
if (count <= kMaxInlineMatches)
|
||||
return mInlineEntry == aConstIterator.mInlineEntry;
|
||||
|
||||
return mTableEntry == aConstIterator.mTableEntry;
|
||||
}
|
||||
|
||||
@ -27,204 +27,306 @@
|
||||
#include "nsRuleNetwork.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsTemplateMatch.h"
|
||||
#include "plhash.h"
|
||||
#include "pldhash.h"
|
||||
|
||||
/**
|
||||
* A collection of unique nsTemplateMatch objects.
|
||||
*/
|
||||
class nsTemplateMatchSet
|
||||
{
|
||||
class nsTemplateMatchSet {
|
||||
public:
|
||||
class ConstIterator;
|
||||
friend class ConstIterator;
|
||||
|
||||
class Iterator;
|
||||
friend class Iterator;
|
||||
|
||||
nsTemplateMatchSet();
|
||||
~nsTemplateMatchSet();
|
||||
|
||||
private:
|
||||
nsTemplateMatchSet(const nsTemplateMatchSet& aMatchSet); // XXX not to be implemented
|
||||
void operator=(const nsTemplateMatchSet& aMatchSet); // XXX not to be implemented
|
||||
friend class ConstIterator; // so it can see Element
|
||||
|
||||
protected:
|
||||
struct List {
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aPool) {
|
||||
return aPool.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
class Element {
|
||||
public:
|
||||
Element(nsTemplateMatch* aMatch)
|
||||
: mMatch(aMatch), mNext(nsnull) {}
|
||||
|
||||
nsTemplateMatch* mMatch;
|
||||
List* mNext;
|
||||
List* mPrev;
|
||||
Element* mNext;
|
||||
};
|
||||
|
||||
List mHead;
|
||||
|
||||
// Lazily created when we pass a size threshold.
|
||||
PLHashTable* mMatches;
|
||||
PRInt32 mCount;
|
||||
|
||||
const nsTemplateMatch* mLastMatch;
|
||||
|
||||
static PLHashNumber PR_CALLBACK HashMatch(const void* aMatch) {
|
||||
const nsTemplateMatch* match = NS_STATIC_CAST(const nsTemplateMatch*, aMatch);
|
||||
return Instantiation::Hash(&match->mInstantiation) ^ (PLHashNumber(match->mRule) >> 2); }
|
||||
|
||||
static PRIntn PR_CALLBACK CompareMatches(const void* aLeft, const void* aRight) {
|
||||
const nsTemplateMatch* left = NS_STATIC_CAST(const nsTemplateMatch*, aLeft);
|
||||
const nsTemplateMatch* right = NS_STATIC_CAST(const nsTemplateMatch*, aRight);
|
||||
return *left == *right; }
|
||||
|
||||
enum { kHashTableThreshold = 8 };
|
||||
|
||||
static PLHashAllocOps gAllocOps;
|
||||
|
||||
static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize) {
|
||||
return new char[aSize]; }
|
||||
|
||||
static void PR_CALLBACK FreeTable(void* aPool, void* aItem) {
|
||||
delete[] NS_STATIC_CAST(char*, aItem); }
|
||||
|
||||
static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) {
|
||||
nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
|
||||
PLHashEntry* entry = NS_STATIC_CAST(PLHashEntry*, pool->Alloc(sizeof(PLHashEntry)));
|
||||
return entry; }
|
||||
|
||||
static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) {
|
||||
if (aFlag == HT_FREE_ENTRY)
|
||||
nsFixedSizeAllocator::Free(aEntry, sizeof(PLHashEntry)); }
|
||||
nsFixedSizeAllocator& mPool;
|
||||
Element* mHead;
|
||||
|
||||
public:
|
||||
// Used to initialize the nsFixedSizeAllocator that's used to pool
|
||||
// entries.
|
||||
enum {
|
||||
kEntrySize = sizeof(List),
|
||||
kIndexSize = sizeof(PLHashEntry)
|
||||
};
|
||||
nsTemplateMatchSet(nsFixedSizeAllocator& aPool)
|
||||
: mPool(aPool), mHead(nsnull) { MOZ_COUNT_CTOR(nsTemplateMatchSet); }
|
||||
|
||||
~nsTemplateMatchSet();
|
||||
|
||||
class ConstIterator {
|
||||
protected:
|
||||
friend class Iterator; // XXXwaterson so broken.
|
||||
List* mCurrent;
|
||||
friend class nsTemplateMatchSet;
|
||||
|
||||
Element* mCurrent;
|
||||
|
||||
ConstIterator(Element* aElement)
|
||||
: mCurrent(aElement) {}
|
||||
|
||||
public:
|
||||
ConstIterator() : mCurrent(nsnull) {}
|
||||
|
||||
ConstIterator(List* aCurrent) : mCurrent(aCurrent) {}
|
||||
ConstIterator(const ConstIterator& aIterator)
|
||||
: mCurrent(aIterator.mCurrent) {}
|
||||
|
||||
ConstIterator(const ConstIterator& aConstIterator)
|
||||
: mCurrent(aConstIterator.mCurrent) {}
|
||||
|
||||
ConstIterator& operator=(const ConstIterator& aConstIterator) {
|
||||
mCurrent = aConstIterator.mCurrent;
|
||||
ConstIterator&
|
||||
operator=(const ConstIterator& aIterator) {
|
||||
mCurrent = aIterator.mCurrent;
|
||||
return *this; }
|
||||
|
||||
ConstIterator& operator++() {
|
||||
ConstIterator&
|
||||
operator++() {
|
||||
mCurrent = mCurrent->mNext;
|
||||
return *this; }
|
||||
return *this; };
|
||||
|
||||
ConstIterator operator++(int) {
|
||||
ConstIterator result(*this);
|
||||
ConstIterator
|
||||
operator++(int) {
|
||||
ConstIterator tmp(*this);
|
||||
mCurrent = mCurrent->mNext;
|
||||
return result; }
|
||||
|
||||
ConstIterator& operator--() {
|
||||
mCurrent = mCurrent->mPrev;
|
||||
return *this; }
|
||||
|
||||
ConstIterator operator--(int) {
|
||||
ConstIterator result(*this);
|
||||
mCurrent = mCurrent->mPrev;
|
||||
return result; }
|
||||
|
||||
const nsTemplateMatch& operator*() const {
|
||||
return *mCurrent->mMatch; }
|
||||
|
||||
const nsTemplateMatch* operator->() const {
|
||||
return mCurrent->mMatch; }
|
||||
|
||||
PRBool operator==(const ConstIterator& aConstIterator) const {
|
||||
return mCurrent == aConstIterator.mCurrent; }
|
||||
|
||||
PRBool operator!=(const ConstIterator& aConstIterator) const {
|
||||
return mCurrent != aConstIterator.mCurrent; }
|
||||
};
|
||||
|
||||
ConstIterator First() const { return ConstIterator(mHead.mNext); }
|
||||
ConstIterator Last() const { return ConstIterator(NS_CONST_CAST(List*, &mHead)); }
|
||||
|
||||
class Iterator : public ConstIterator {
|
||||
public:
|
||||
Iterator() {}
|
||||
|
||||
Iterator(List* aCurrent) : ConstIterator(aCurrent) {}
|
||||
|
||||
Iterator& operator++() {
|
||||
mCurrent = mCurrent->mNext;
|
||||
return *this; }
|
||||
|
||||
Iterator operator++(int) {
|
||||
Iterator result(*this);
|
||||
mCurrent = mCurrent->mNext;
|
||||
return result; }
|
||||
|
||||
Iterator& operator--() {
|
||||
mCurrent = mCurrent->mPrev;
|
||||
return *this; }
|
||||
|
||||
Iterator operator--(int) {
|
||||
Iterator result(*this);
|
||||
mCurrent = mCurrent->mPrev;
|
||||
return result; }
|
||||
return tmp; }
|
||||
|
||||
nsTemplateMatch& operator*() const {
|
||||
return *mCurrent->mMatch; }
|
||||
return *(mCurrent->mMatch); }
|
||||
|
||||
nsTemplateMatch* operator->() const {
|
||||
return mCurrent->mMatch; }
|
||||
|
||||
PRBool operator==(const ConstIterator& aConstIterator) const {
|
||||
return mCurrent == aConstIterator.mCurrent; }
|
||||
PRBool
|
||||
operator==(const ConstIterator& aIterator) const {
|
||||
return mCurrent == aIterator.mCurrent; }
|
||||
|
||||
PRBool operator!=(const ConstIterator& aConstIterator) const {
|
||||
return mCurrent != aConstIterator.mCurrent; }
|
||||
|
||||
friend class nsTemplateMatchSet;
|
||||
PRBool
|
||||
operator!=(const ConstIterator& aIterator) const {
|
||||
return !aIterator.operator==(*this); }
|
||||
};
|
||||
|
||||
Iterator First() { return Iterator(mHead.mNext); }
|
||||
Iterator Last() { return Iterator(&mHead); }
|
||||
ConstIterator First() const { return ConstIterator(mHead); }
|
||||
|
||||
PRBool Empty() const { return First() == Last(); }
|
||||
ConstIterator Last() const { return ConstIterator(nsnull); }
|
||||
|
||||
PRInt32 Count() const { return mCount; }
|
||||
void
|
||||
Add(nsTemplateMatch* aMatch) {
|
||||
Element* element = new Element(aMatch);
|
||||
if (element) {
|
||||
aMatch->AddRef();
|
||||
element->mMatch = aMatch;
|
||||
element->mNext = mHead;
|
||||
mHead = element;
|
||||
} }
|
||||
};
|
||||
|
||||
ConstIterator Find(const nsTemplateMatch& aMatch) const;
|
||||
Iterator Find(const nsTemplateMatch& aMatch);
|
||||
/**
|
||||
* A set of references nsTemplateMatch objects.
|
||||
*/
|
||||
class nsTemplateMatchRefSet
|
||||
{
|
||||
public:
|
||||
nsTemplateMatchRefSet() {
|
||||
MOZ_COUNT_CTOR(nsTemplateMatchRefSet);
|
||||
Init(); }
|
||||
|
||||
PRBool Contains(const nsTemplateMatch& aMatch) const {
|
||||
return Find(aMatch) != Last(); }
|
||||
nsTemplateMatchRefSet(const nsTemplateMatchRefSet& aMatchSet) {
|
||||
MOZ_COUNT_CTOR(nsTemplateMatchRefSet);
|
||||
Init();
|
||||
CopyFrom(aMatchSet); }
|
||||
|
||||
nsTemplateMatch* FindMatchWithHighestPriority() const;
|
||||
nsTemplateMatchRefSet&
|
||||
operator=(const nsTemplateMatchRefSet& aMatchSet) {
|
||||
Finish();
|
||||
Init();
|
||||
CopyFrom(aMatchSet);
|
||||
return *this; }
|
||||
|
||||
const nsTemplateMatch* GetLastMatch() const { return mLastMatch; }
|
||||
void SetLastMatch(const nsTemplateMatch* aMatch) { mLastMatch = aMatch; }
|
||||
~nsTemplateMatchRefSet() {
|
||||
Finish();
|
||||
MOZ_COUNT_DTOR(nsTemplateMatchRefSet); }
|
||||
|
||||
Iterator Insert(nsFixedSizeAllocator& aPool, Iterator aIterator, nsTemplateMatch* aMatch);
|
||||
protected:
|
||||
/**
|
||||
* Initialize the set. Must be called before the set is used, or
|
||||
* after Finish().
|
||||
*/
|
||||
void Init();
|
||||
|
||||
Iterator Add(nsFixedSizeAllocator& aPool, nsTemplateMatch* aMatch) {
|
||||
return Insert(aPool, Last(), aMatch); }
|
||||
/**
|
||||
* Finish the set, releasing all matches. This must be called to
|
||||
* properly release matches in the set. Yeah, yeah, this sucks.
|
||||
*/
|
||||
void Finish();
|
||||
|
||||
nsresult CopyInto(nsTemplateMatchSet& aMatchSet, nsFixedSizeAllocator& aPool) const;
|
||||
/**
|
||||
* Copy the set's contents from another match set
|
||||
*/
|
||||
void CopyFrom(const nsTemplateMatchRefSet& aMatchSet);
|
||||
|
||||
void Clear();
|
||||
/**
|
||||
* Helper routine that adds the match to the hashtable
|
||||
*/
|
||||
PRBool AddToTable(nsTemplateMatch* aMatch);
|
||||
|
||||
Iterator Erase(Iterator aIterator);
|
||||
/**
|
||||
* Hashtable entry; holds weak reference to a match object.
|
||||
*/
|
||||
struct Entry {
|
||||
PLDHashEntryHdr mHdr;
|
||||
nsTemplateMatch* mMatch;
|
||||
};
|
||||
|
||||
void Remove(nsTemplateMatch* aMatch);
|
||||
enum { kMaxInlineMatches = (sizeof(PLDHashTable) / sizeof(void*)) - 1 };
|
||||
|
||||
struct InlineMatches;
|
||||
friend struct InlineMatches;
|
||||
|
||||
/**
|
||||
* If the set is currently
|
||||
*/
|
||||
struct InlineMatches {
|
||||
PRUint32 mCount;
|
||||
nsTemplateMatch* mEntries[kMaxInlineMatches];
|
||||
};
|
||||
|
||||
/**
|
||||
* The set is implemented as a dual datastructure. It is initially
|
||||
* a simple array that holds storage for kMaxInlineMatches
|
||||
* elements. Once that capacity is exceeded, the storage is
|
||||
* re-used for a PLDHashTable header. The hashtable allocates its
|
||||
* entries from the normal malloc() heap.
|
||||
*
|
||||
* the InlineMatches structure is implemented such that its mCount
|
||||
* variable overlaps with the PLDHashTable's `ops' member (which
|
||||
* is a pointer to the hashtable's callback table). On a 32-bit
|
||||
* architecture, we're safe assuming that the value for `ops' will
|
||||
* be larger than kMaxInlineMatches when treated as an unsigned
|
||||
* integer. And we'd have to get pretty unlucky on a 64-bit
|
||||
* system for us to get screwed, I think.
|
||||
*
|
||||
* Instrumentation (#define NSTEMPLATEMATCHSET_METER) shows that
|
||||
* almost all of the match sets contain fewer than seven elements.
|
||||
*/
|
||||
union {
|
||||
PLDHashTable mTable;
|
||||
InlineMatches mInlineMatches;
|
||||
};
|
||||
|
||||
static PLDHashTableOps gOps;
|
||||
|
||||
static PLDHashNumber PR_CALLBACK
|
||||
HashEntry(PLDHashTable* aTable, const void* aKey);
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
MatchEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aHdr, const void* aKey);
|
||||
|
||||
public:
|
||||
class ConstIterator;
|
||||
friend class ConstIterator;
|
||||
|
||||
/**
|
||||
* An iterator that can be used to enumerate the contents of the
|
||||
* set
|
||||
*/
|
||||
class ConstIterator {
|
||||
protected:
|
||||
friend class nsTemplateMatchRefSet;
|
||||
|
||||
void Next();
|
||||
void Prev();
|
||||
|
||||
ConstIterator(const nsTemplateMatchRefSet* aSet, Entry* aTableEntry)
|
||||
: mSet(aSet), mTableEntry(aTableEntry) {}
|
||||
|
||||
ConstIterator(const nsTemplateMatchRefSet* aSet, nsTemplateMatch** aInlineEntry)
|
||||
: mSet(aSet), mInlineEntry(aInlineEntry) {}
|
||||
|
||||
const nsTemplateMatchRefSet* mSet;
|
||||
union {
|
||||
Entry* mTableEntry;
|
||||
nsTemplateMatch** mInlineEntry;
|
||||
};
|
||||
|
||||
nsTemplateMatch* get() const {
|
||||
return mSet->mInlineMatches.mCount > PRUint32(kMaxInlineMatches)
|
||||
? mTableEntry->mMatch
|
||||
: *mInlineEntry; }
|
||||
|
||||
public:
|
||||
ConstIterator() : mSet(nsnull), mTableEntry(nsnull) {}
|
||||
|
||||
ConstIterator(const ConstIterator& aConstIterator)
|
||||
: mSet(aConstIterator.mSet),
|
||||
mTableEntry(aConstIterator.mTableEntry) {}
|
||||
|
||||
ConstIterator& operator=(const ConstIterator& aConstIterator) {
|
||||
mSet = aConstIterator.mSet;
|
||||
mTableEntry = aConstIterator.mTableEntry;
|
||||
return *this; }
|
||||
|
||||
ConstIterator& operator++() {
|
||||
Next();
|
||||
return *this; }
|
||||
|
||||
ConstIterator operator++(int) {
|
||||
ConstIterator result(*this);
|
||||
Next();
|
||||
return result; }
|
||||
|
||||
ConstIterator& operator--() {
|
||||
Prev();
|
||||
return *this; }
|
||||
|
||||
ConstIterator operator--(int) {
|
||||
ConstIterator result(*this);
|
||||
Prev();
|
||||
return result; }
|
||||
|
||||
/*const*/ nsTemplateMatch& operator*() const {
|
||||
return *get(); }
|
||||
|
||||
/*const*/ nsTemplateMatch* operator->() const {
|
||||
return get(); }
|
||||
|
||||
PRBool operator==(const ConstIterator& aConstIterator) const;
|
||||
|
||||
PRBool operator!=(const ConstIterator& aConstIterator) const {
|
||||
return ! aConstIterator.operator==(*this); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve an iterator that refers to the first element of the
|
||||
* set
|
||||
*/
|
||||
ConstIterator First() const;
|
||||
|
||||
/**
|
||||
* Retrieve an iterator that refers to ``one past'' the last
|
||||
* element of the set
|
||||
*/
|
||||
ConstIterator Last() const;
|
||||
|
||||
/**
|
||||
* Return PR_TRUE if the set is empty
|
||||
*/
|
||||
PRBool Empty() const;
|
||||
|
||||
/**
|
||||
* Return PR_TRUE if the set contains aMatch
|
||||
*/
|
||||
PRBool Contains(const nsTemplateMatch* aMatch) const;
|
||||
|
||||
/**
|
||||
* Add a match to the set. The set does *not* assume ownership of
|
||||
* the match object: it only holds a weak reference. Duplicate
|
||||
* matches are not added.
|
||||
*
|
||||
* @return PR_TRUE if the match was added to the set; PR_FALSE if it
|
||||
* already existed (or could not be added for some other reason)
|
||||
*/
|
||||
PRBool Add(const nsTemplateMatch* aMatch);
|
||||
|
||||
/**
|
||||
* Remove a match from the set.
|
||||
* @return PR_TRUE if the match was removed from the set; PR_FALSE
|
||||
* if the match was not present in the set.
|
||||
*/
|
||||
PRBool Remove(const nsTemplateMatch* aMatch);
|
||||
};
|
||||
|
||||
#endif // nsTemplateMatchSet_h__
|
||||
|
||||
@ -75,8 +75,8 @@ nsOutlinerRowTestNode::FilterInstantiations(InstantiationSet& aInstantiations, v
|
||||
(mRows.Find(mConflictSet, container) != mRows.Last())) {
|
||||
|
||||
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG, (" => passed"));
|
||||
Element* element = new (mConflictSet.GetPool())
|
||||
Element(container);
|
||||
Element* element =
|
||||
Element::Create(mConflictSet.GetPool(), container);
|
||||
|
||||
if (! element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -47,19 +47,29 @@ public:
|
||||
GetAncestorVariables(VariableSet& aVariables) const;
|
||||
|
||||
class Element : public MemoryElement {
|
||||
protected:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) { }
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
Element(nsIRDFResource* aResource)
|
||||
: mResource(aResource) {
|
||||
MOZ_COUNT_CTOR(nsOutlinerRowTestNode::Element); }
|
||||
|
||||
virtual ~Element() { MOZ_COUNT_DTOR(nsOutlinerRowTestNode::Element); }
|
||||
|
||||
static Element*
|
||||
Create(nsFixedSizeAllocator& aPool, nsIRDFResource* aResource) {
|
||||
void* place = aPool.Alloc(sizeof(Element));
|
||||
return place ? ::new (place) Element(aResource) : nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aPool, Element* aElement) {
|
||||
aElement->~Element();
|
||||
aPool.Free(aElement, sizeof(*aElement)); }
|
||||
|
||||
virtual const char* Type() const {
|
||||
return "nsOutlinerRowTestNode::Element"; }
|
||||
|
||||
@ -74,8 +84,7 @@ public:
|
||||
return PR_FALSE; }
|
||||
|
||||
virtual MemoryElement* Clone(void* aPool) const {
|
||||
return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool))
|
||||
Element(mResource); }
|
||||
return Create(*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool), mResource); }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIRDFResource> mResource;
|
||||
|
||||
@ -1263,14 +1263,14 @@ nsXULContentBuilder::CreateContainerContents(nsIContent* aElement,
|
||||
// Iterate through newly added keys to determine which rules fired
|
||||
nsClusterKeySet::ConstIterator last = newkeys.Last();
|
||||
for (nsClusterKeySet::ConstIterator key = newkeys.First(); key != last; ++key) {
|
||||
const nsTemplateMatchSet* matches;
|
||||
mConflictSet.GetMatchesForClusterKey(*key, &matches);
|
||||
nsConflictSet::MatchCluster* matches =
|
||||
mConflictSet.GetMatchesForClusterKey(*key);
|
||||
|
||||
if (! matches)
|
||||
continue;
|
||||
|
||||
nsTemplateMatch* match =
|
||||
matches->FindMatchWithHighestPriority();
|
||||
mConflictSet.GetMatchWithHighestPriority(matches);
|
||||
|
||||
NS_ASSERTION(match != nsnull, "no best match in match set");
|
||||
if (! match)
|
||||
@ -1286,7 +1286,7 @@ nsXULContentBuilder::CreateContainerContents(nsIContent* aElement,
|
||||
aContainer, aNewIndexInContainer);
|
||||
|
||||
// Remember this as the "last" match
|
||||
NS_CONST_CAST(nsTemplateMatchSet*, matches)->SetLastMatch(match);
|
||||
matches->mLastMatch = match;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1470,7 +1470,8 @@ nsXULContentBuilder::RemoveGeneratedContent(nsIContent* aElement)
|
||||
|
||||
// Remove element from the conflict set.
|
||||
// XXXwaterson should this be moved into NoteGeneratedSubtreeRemoved?
|
||||
nsTemplateMatchSet firings, retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
mConflictSet.Remove(nsContentTestNode::Element(child), firings, retractions);
|
||||
|
||||
// Remove this and any children from the content support map.
|
||||
@ -2087,7 +2088,8 @@ nsXULContentBuilder::CloseContainer(nsIContent* aElement)
|
||||
|
||||
// Remove any instantiations involving this element from the
|
||||
// conflict set.
|
||||
nsTemplateMatchSet firings, retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
mConflictSet.Remove(nsContentTestNode::Element(aElement), firings, retractions);
|
||||
}
|
||||
|
||||
|
||||
@ -1106,14 +1106,7 @@ nsXULOutlinerBuilder::TokenizeProperties(const nsAReadableString& aString,
|
||||
if (iter == first)
|
||||
break;
|
||||
|
||||
|
||||
#if 1 // XXX until bug 55143 is fixed, we need to copy so the string
|
||||
// is zero-terminated
|
||||
nsAutoString s(Substring(first, iter));
|
||||
nsCOMPtr<nsIAtom> atom = dont_AddRef(NS_NewAtom(s));
|
||||
#else
|
||||
nsCOMPtr<nsIAtom> atom = dont_AddRef(NS_NewAtom(Substring(first, iter)));
|
||||
#endif
|
||||
aProperties->AppendElement(atom);
|
||||
} while (iter != end);
|
||||
|
||||
@ -1188,14 +1181,14 @@ nsXULOutlinerBuilder::OpenSubtreeOf(nsOutlinerRows::Subtree* aSubtree,
|
||||
// Iterate through newly added keys to determine which rules fired
|
||||
nsClusterKeySet::ConstIterator last = newkeys.Last();
|
||||
for (nsClusterKeySet::ConstIterator key = newkeys.First(); key != last; ++key) {
|
||||
const nsTemplateMatchSet* matches;
|
||||
mConflictSet.GetMatchesForClusterKey(*key, &matches);
|
||||
nsConflictSet::MatchCluster* matches =
|
||||
mConflictSet.GetMatchesForClusterKey(*key);
|
||||
|
||||
if (! matches)
|
||||
continue;
|
||||
|
||||
nsTemplateMatch* match =
|
||||
matches->FindMatchWithHighestPriority();
|
||||
mConflictSet.GetMatchWithHighestPriority(matches);
|
||||
|
||||
NS_ASSERTION(match != nsnull, "no best match in match set");
|
||||
if (! match)
|
||||
@ -1205,7 +1198,7 @@ nsXULOutlinerBuilder::OpenSubtreeOf(nsOutlinerRows::Subtree* aSubtree,
|
||||
mRows.InsertRowAt(match, aSubtree, count);
|
||||
|
||||
// Remember this as the "last" match
|
||||
NS_CONST_CAST(nsTemplateMatchSet*, matches)->SetLastMatch(match);
|
||||
matches->mLastMatch = match;
|
||||
|
||||
// If this is open, then remember it so we can recursively add
|
||||
// *its* rows to the tree.
|
||||
@ -1260,13 +1253,14 @@ nsXULOutlinerBuilder::CloseContainer(PRInt32 aIndex, nsIRDFResource* aContainer)
|
||||
if (aIndex < 0 || aIndex >= mRows.Count())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsTemplateMatchSet firings, retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
mConflictSet.Remove(nsOutlinerRowTestNode::Element(aContainer), firings, retractions);
|
||||
|
||||
{
|
||||
// Clean up the conflict set
|
||||
nsTemplateMatchSet::Iterator last = retractions.Last();
|
||||
nsTemplateMatchSet::Iterator iter;
|
||||
nsTemplateMatchSet::ConstIterator last = retractions.Last();
|
||||
nsTemplateMatchSet::ConstIterator iter;
|
||||
|
||||
for (iter = retractions.First(); iter != last; ++iter) {
|
||||
Value val;
|
||||
@ -1301,11 +1295,12 @@ nsXULOutlinerBuilder::RemoveMatchesFor(nsIRDFResource* aContainer)
|
||||
if (! aContainer)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsTemplateMatchSet firings, retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
mConflictSet.Remove(nsOutlinerRowTestNode::Element(aContainer), firings, retractions);
|
||||
|
||||
nsTemplateMatchSet::Iterator last = retractions.Last();
|
||||
nsTemplateMatchSet::Iterator iter;
|
||||
nsTemplateMatchSet::ConstIterator last = retractions.Last();
|
||||
nsTemplateMatchSet::ConstIterator iter;
|
||||
|
||||
for (iter = retractions.First(); iter != last; ++iter) {
|
||||
Value val;
|
||||
|
||||
@ -514,15 +514,15 @@ nsXULTemplateBuilder::FireNewlyMatchedRules(const nsClusterKeySet& aNewKeys)
|
||||
// to track those?
|
||||
nsClusterKeySet::ConstIterator last = aNewKeys.Last();
|
||||
for (nsClusterKeySet::ConstIterator key = aNewKeys.First(); key != last; ++key) {
|
||||
const nsTemplateMatchSet* matches;
|
||||
mConflictSet.GetMatchesForClusterKey(*key, &matches);
|
||||
nsConflictSet::MatchCluster* matches =
|
||||
mConflictSet.GetMatchesForClusterKey(*key);
|
||||
|
||||
NS_ASSERTION(matches != nsnull, "no matched rules for new key");
|
||||
if (! matches)
|
||||
continue;
|
||||
|
||||
nsTemplateMatch* bestmatch =
|
||||
matches->FindMatchWithHighestPriority();
|
||||
mConflictSet.GetMatchWithHighestPriority(matches);
|
||||
|
||||
NS_ASSERTION(bestmatch != nsnull, "no matches in match set");
|
||||
if (! bestmatch)
|
||||
@ -530,12 +530,12 @@ nsXULTemplateBuilder::FireNewlyMatchedRules(const nsClusterKeySet& aNewKeys)
|
||||
|
||||
// If the new "bestmatch" is different from the last match,
|
||||
// then we need to yank some content out and rebuild it.
|
||||
const nsTemplateMatch* lastmatch = matches->GetLastMatch();
|
||||
const nsTemplateMatch* lastmatch = matches->mLastMatch;
|
||||
if (bestmatch != lastmatch) {
|
||||
ReplaceMatch(VALUE_TO_IRDFRESOURCE(key->mMemberValue), lastmatch, bestmatch);
|
||||
|
||||
// Remember the best match as the new "last" match
|
||||
NS_CONST_CAST(nsTemplateMatchSet*, matches)->SetLastMatch(bestmatch);
|
||||
matches->mLastMatch = bestmatch;
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,13 +587,13 @@ nsXULTemplateBuilder::Retract(nsIRDFResource* aSource,
|
||||
for (NodeSet::ConstIterator node = mRDFTests.First(); node != lastnode; ++node) {
|
||||
const nsRDFTestNode* rdftestnode = NS_STATIC_CAST(const nsRDFTestNode*, *node);
|
||||
|
||||
nsTemplateMatchSet firings;
|
||||
nsTemplateMatchSet retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
rdftestnode->Retract(aSource, aProperty, aTarget, firings, retractions);
|
||||
|
||||
{
|
||||
nsTemplateMatchSet::Iterator last = retractions.Last();
|
||||
for (nsTemplateMatchSet::Iterator match = retractions.First(); match != last; ++match) {
|
||||
nsTemplateMatchSet::ConstIterator last = retractions.Last();
|
||||
for (nsTemplateMatchSet::ConstIterator match = retractions.First(); match != last; ++match) {
|
||||
Value memberval;
|
||||
match->mAssignments.GetAssignmentFor(match->mRule->GetMemberVariable(), &memberval);
|
||||
|
||||
@ -1243,27 +1243,19 @@ nsXULTemplateBuilder::SynchronizeAll(nsIRDFResource* aSource,
|
||||
|
||||
// Get all the matches whose assignments are currently supported
|
||||
// by aSource and aProperty: we'll need to recompute them.
|
||||
const nsTemplateMatchSet* matches;
|
||||
mConflictSet.GetMatchesWithBindingDependency(aSource, &matches);
|
||||
const nsTemplateMatchRefSet* matches =
|
||||
mConflictSet.GetMatchesWithBindingDependency(aSource);
|
||||
|
||||
if (! matches || matches->Empty())
|
||||
return NS_OK;
|
||||
|
||||
// Since we'll actually be manipulating the match set as we
|
||||
// iterate through it, we need to copy it into our own private
|
||||
// area before performing the iteration.
|
||||
static const size_t kBucketSizes[] = { nsTemplateMatchSet::kEntrySize, nsTemplateMatchSet::kIndexSize };
|
||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t);
|
||||
nsTemplateMatchRefSet copy = *matches;
|
||||
|
||||
// Per news://news.mozilla.org/39BEC105.5090206%40netscape.com
|
||||
static const PRInt32 kPoolSize = 256;
|
||||
|
||||
nsFixedSizeAllocator pool;
|
||||
pool.Init("nsXULTemplateBuilder::SynchronizeAll", kBucketSizes, kNumBuckets, kPoolSize);
|
||||
|
||||
nsTemplateMatchSet copy;
|
||||
matches->CopyInto(copy, pool);
|
||||
|
||||
for (nsTemplateMatchSet::Iterator match = copy.First(); match != copy.Last(); ++match) {
|
||||
nsTemplateMatchRefSet::ConstIterator last = copy.Last();
|
||||
for (nsTemplateMatchRefSet::ConstIterator match = copy.First(); match != last; ++match) {
|
||||
const nsTemplateRule* rule = match->mRule;
|
||||
|
||||
// Recompute the assignments. This will replace aOldTarget with
|
||||
|
||||
@ -1106,14 +1106,7 @@ nsXULOutlinerBuilder::TokenizeProperties(const nsAReadableString& aString,
|
||||
if (iter == first)
|
||||
break;
|
||||
|
||||
|
||||
#if 1 // XXX until bug 55143 is fixed, we need to copy so the string
|
||||
// is zero-terminated
|
||||
nsAutoString s(Substring(first, iter));
|
||||
nsCOMPtr<nsIAtom> atom = dont_AddRef(NS_NewAtom(s));
|
||||
#else
|
||||
nsCOMPtr<nsIAtom> atom = dont_AddRef(NS_NewAtom(Substring(first, iter)));
|
||||
#endif
|
||||
aProperties->AppendElement(atom);
|
||||
} while (iter != end);
|
||||
|
||||
@ -1188,14 +1181,14 @@ nsXULOutlinerBuilder::OpenSubtreeOf(nsOutlinerRows::Subtree* aSubtree,
|
||||
// Iterate through newly added keys to determine which rules fired
|
||||
nsClusterKeySet::ConstIterator last = newkeys.Last();
|
||||
for (nsClusterKeySet::ConstIterator key = newkeys.First(); key != last; ++key) {
|
||||
const nsTemplateMatchSet* matches;
|
||||
mConflictSet.GetMatchesForClusterKey(*key, &matches);
|
||||
nsConflictSet::MatchCluster* matches =
|
||||
mConflictSet.GetMatchesForClusterKey(*key);
|
||||
|
||||
if (! matches)
|
||||
continue;
|
||||
|
||||
nsTemplateMatch* match =
|
||||
matches->FindMatchWithHighestPriority();
|
||||
mConflictSet.GetMatchWithHighestPriority(matches);
|
||||
|
||||
NS_ASSERTION(match != nsnull, "no best match in match set");
|
||||
if (! match)
|
||||
@ -1205,7 +1198,7 @@ nsXULOutlinerBuilder::OpenSubtreeOf(nsOutlinerRows::Subtree* aSubtree,
|
||||
mRows.InsertRowAt(match, aSubtree, count);
|
||||
|
||||
// Remember this as the "last" match
|
||||
NS_CONST_CAST(nsTemplateMatchSet*, matches)->SetLastMatch(match);
|
||||
matches->mLastMatch = match;
|
||||
|
||||
// If this is open, then remember it so we can recursively add
|
||||
// *its* rows to the tree.
|
||||
@ -1260,13 +1253,14 @@ nsXULOutlinerBuilder::CloseContainer(PRInt32 aIndex, nsIRDFResource* aContainer)
|
||||
if (aIndex < 0 || aIndex >= mRows.Count())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsTemplateMatchSet firings, retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
mConflictSet.Remove(nsOutlinerRowTestNode::Element(aContainer), firings, retractions);
|
||||
|
||||
{
|
||||
// Clean up the conflict set
|
||||
nsTemplateMatchSet::Iterator last = retractions.Last();
|
||||
nsTemplateMatchSet::Iterator iter;
|
||||
nsTemplateMatchSet::ConstIterator last = retractions.Last();
|
||||
nsTemplateMatchSet::ConstIterator iter;
|
||||
|
||||
for (iter = retractions.First(); iter != last; ++iter) {
|
||||
Value val;
|
||||
@ -1301,11 +1295,12 @@ nsXULOutlinerBuilder::RemoveMatchesFor(nsIRDFResource* aContainer)
|
||||
if (! aContainer)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsTemplateMatchSet firings, retractions;
|
||||
nsTemplateMatchSet firings(mConflictSet.GetPool());
|
||||
nsTemplateMatchSet retractions(mConflictSet.GetPool());
|
||||
mConflictSet.Remove(nsOutlinerRowTestNode::Element(aContainer), firings, retractions);
|
||||
|
||||
nsTemplateMatchSet::Iterator last = retractions.Last();
|
||||
nsTemplateMatchSet::Iterator iter;
|
||||
nsTemplateMatchSet::ConstIterator last = retractions.Last();
|
||||
nsTemplateMatchSet::ConstIterator iter;
|
||||
|
||||
for (iter = retractions.First(); iter != last; ++iter) {
|
||||
Value val;
|
||||
|
||||
@ -196,8 +196,8 @@ void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) {
|
||||
PRInt32 theIndex=0;
|
||||
|
||||
for(theIndex=0;theIndex<theCount;theIndex++) {
|
||||
nsIParserNode* node=aNodeStack->NodeAt(theIndex);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=aNodeStack->NodeAt(theIndex);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -587,12 +587,12 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
while(mBodyContext->GetCount() > 0) {
|
||||
|
||||
nsEntryStack *theChildStyles=0;
|
||||
nsIParserNode* theNode=mBodyContext->Pop(theChildStyles);
|
||||
nsCParserNode* theNode=mBodyContext->Pop(theChildStyles);
|
||||
if(theNode) {
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -637,7 +637,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)mMisplacedContent.Pop())) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
|
||||
if(mDTDDebug) {
|
||||
@ -726,7 +726,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
mSkipTarget=eHTMLTag_unknown; //stop skipping.
|
||||
//mTokenizer->PushTokenFront(aToken); //push the end token...
|
||||
execSkipContent=PR_TRUE;
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
}
|
||||
@ -741,7 +741,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
if(theType!=eToken_attribute) {
|
||||
aToken->AppendSource(mScratch);
|
||||
}
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
@ -889,7 +889,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
mDTDState=result;
|
||||
@ -937,7 +937,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
|
||||
if(eToken_newline==theType){
|
||||
mLineNumber++;
|
||||
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
|
||||
IF_FREE(theNextToken); // fix for Bug 29379
|
||||
IF_FREE(theNextToken, mTokenAllocator); // fix for Bug 29379
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
@ -1019,7 +1019,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
|
||||
CToken *theEndToken=mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag);
|
||||
if(theEndToken) {
|
||||
result=HandleEndToken(theEndToken);
|
||||
IF_FREE(theEndToken);
|
||||
IF_FREE(theEndToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1172,7 +1172,7 @@ enum eProcessRule {eNormalOp,eLetInlineContainBlock};
|
||||
* @param aNode -- CParserNode representing this start token
|
||||
* @return PR_TRUE if all went well; PR_FALSE if error occured
|
||||
*/
|
||||
nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode) {
|
||||
nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsCParserNode *aNode) {
|
||||
NS_PRECONDITION(0!=aToken,kNullToken);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -1607,7 +1607,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
@ -1724,7 +1724,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
result=NS_OK;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1850,7 +1850,7 @@ static void StripWSFollowingTag(eHTMLTags aChildTag,nsITokenizer* aTokenizer,nsT
|
||||
case eToken_newline: aNewlineCount++;
|
||||
case eToken_whitespace:
|
||||
theToken=aTokenizer->PopToken();
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, aTokenAllocator);
|
||||
theToken=aTokenizer->PeekToken();
|
||||
break;
|
||||
default:
|
||||
@ -2039,9 +2039,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
nsEntryStack* theChildStyleStack=0;
|
||||
|
||||
for(i=0; i<(theTagCount - theTopIndex); i++) {
|
||||
nsIParserNode* node=mBodyContext->Pop(theChildStyleStack);
|
||||
nsCParserNode* node=mBodyContext->Pop(theChildStyleStack);
|
||||
mTempContext->Push(node);
|
||||
NS_IF_RELEASE(node); //release the popped node since push will addref for us.
|
||||
IF_FREE(node, &mNodeAllocator); //release the popped node since push will addref for us.
|
||||
}
|
||||
|
||||
// Now flush out all the bad contents.
|
||||
@ -2068,7 +2068,7 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
PRInt32 theIndex=mBodyContext->LastOf(theTag);
|
||||
|
||||
if(theIndex!=kNotFound && theIndex<=mBodyContext->mContextTopIndex) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -2082,9 +2082,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
// Bad-contents were successfully processed. Now, itz time to get
|
||||
// back to the original body context state.
|
||||
for(PRInt32 k=0; k<(theTagCount - theTopIndex); k++) {
|
||||
nsIParserNode* node=mTempContext->Pop(theChildStyleStack);
|
||||
nsCParserNode* node=mTempContext->Pop(theChildStyleStack);
|
||||
mBodyContext->Push(node);
|
||||
NS_IF_RELEASE(node);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
|
||||
STOP_TIMER()
|
||||
@ -2135,7 +2135,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
|
||||
if(CanOmit(theParentTag,eHTMLTag_entity,theParentContains)) {
|
||||
@ -2148,7 +2148,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
#endif
|
||||
result=AddLeaf(theNode);
|
||||
}
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2172,7 +2172,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
const nsAReadableString& theComment = theToken->GetStringValue();
|
||||
mLineNumber += CountCharInReadable(theComment, PRUnichar(kNewLine));
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
@ -2184,7 +2184,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2248,7 +2248,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
@ -2260,7 +2260,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2298,7 +2298,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
docTypeStr.Cut(0,2); // Now remove "<!" from the begining
|
||||
theToken->SetStringValue(docTypeStr);
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
|
||||
STOP_TIMER();
|
||||
@ -2321,7 +2321,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
|
||||
result = (mSink)? mSink->AddDocTypeDecl(*theNode,theMode):NS_OK;
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2431,7 +2431,7 @@ nsresult CNavDTD::CollectSkippedContent(nsIParserNode& aNode,PRInt32 &aCount) {
|
||||
}
|
||||
else theNextToken->AppendSource(*theNode->mSkippedContent);
|
||||
}
|
||||
IF_FREE(theNextToken);
|
||||
IF_FREE(theNextToken, mTokenAllocator);
|
||||
}
|
||||
|
||||
// if the string contained CRs (hence is either CR, or CRLF terminated)
|
||||
@ -2899,8 +2899,8 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
|
||||
}
|
||||
else {
|
||||
//if the node tag can't contain the child tag, then remove the child tag from the style stack
|
||||
nsIParserNode* node=theStack->Remove(sindex,theNodeTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=theStack->Remove(sindex,theNodeTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
theEntry--; //back up by one
|
||||
}
|
||||
} //if
|
||||
@ -2967,8 +2967,8 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
if(mFlags & NS_PARSER_FLAG_ENABLE_RESIDUAL_STYLE) {
|
||||
#ifdef ENABLE_RESIDUALSTYLE
|
||||
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
|
||||
nsIParserNode* node=mBodyContext->PopStyle(aTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(aTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
#endif
|
||||
} //if
|
||||
@ -2984,7 +2984,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
* @update gess4/22/98
|
||||
* @param aNode -- next node to be added to model
|
||||
*/
|
||||
nsresult CNavDTD::OpenHTML(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenHTML(const nsCParserNode *aNode){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
STOP_TIMER();
|
||||
@ -3084,7 +3084,7 @@ nsresult CNavDTD::CloseHead(const nsIParserNode *aNode){
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult CNavDTD::OpenBody(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenBody(const nsCParserNode *aNode){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -3209,7 +3209,7 @@ nsresult CNavDTD::CloseForm(const nsIParserNode *aNode){
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenMap(const nsCParserNode *aNode){
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenMap(), this=%p\n", this));
|
||||
@ -3260,7 +3260,7 @@ nsresult CNavDTD::CloseMap(const nsIParserNode *aNode){
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult CNavDTD::OpenFrameset(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenFrameset(const nsCParserNode *aNode){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
mFlags |= NS_PARSER_FLAG_HAD_FRAMESET;
|
||||
@ -3308,7 +3308,7 @@ nsresult CNavDTD::CloseFrameset(const nsIParserNode *aNode){
|
||||
* @param aNode - The noscript node
|
||||
* return NS_OK if succeeded else ERROR
|
||||
*/
|
||||
nsresult CNavDTD::OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack) {
|
||||
nsresult CNavDTD::OpenNoscript(const nsCParserNode *aNode,nsEntryStack* aStyleStack) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mSink) {
|
||||
@ -3381,7 +3381,7 @@ nsresult CNavDTD::CloseNoscript(const nsIParserNode *aNode) {
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult
|
||||
CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack){
|
||||
CNavDTD::OpenContainer(const nsCParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -3505,7 +3505,7 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult
|
||||
CNavDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag){
|
||||
CNavDTD::CloseContainer(const nsCParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag){
|
||||
nsresult result=NS_OK;
|
||||
eHTMLTags nodeType=(eHTMLTags)aNode->GetNodeType();
|
||||
|
||||
@ -3587,7 +3587,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
|
||||
nsEntryStack *theChildStyleStack=0;
|
||||
eHTMLTags theTag=mBodyContext->Last();
|
||||
nsCParserNode *theNode=NS_STATIC_CAST(nsCParserNode*,mBodyContext->Pop(theChildStyleStack));
|
||||
nsCParserNode *theNode=mBodyContext->Pop(theChildStyleStack);
|
||||
|
||||
if(theNode) {
|
||||
result=CloseContainer(theNode,aTarget,aClosedByStartTag);
|
||||
@ -3634,8 +3634,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
//here's a case we missed: <a><div>text<a>text</a></div>
|
||||
//The <div> pushes the 1st <a> onto the rs-stack, then the 2nd <a>
|
||||
//pops the 1st <a> from the rs-stack altogether.
|
||||
nsIParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
|
||||
|
||||
@ -3680,8 +3680,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
// This fixes bug 30885 and 29626
|
||||
// Make sure that the node, which is about to
|
||||
// get released does not stay on the style stack...
|
||||
nsIParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
mBodyContext->PushStyles(theChildStyleStack);
|
||||
}
|
||||
@ -3705,8 +3705,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
//style tag that got onto that tag stack from a stylestack somewhere.
|
||||
//Pop it from the stylestack if the target is also a style tag.
|
||||
if(theTargetTagIsStyle) {
|
||||
nsIParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3723,7 +3723,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
}
|
||||
}
|
||||
#endif
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
}//if theNode
|
||||
}
|
||||
|
||||
|
||||
@ -401,7 +401,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @return error code representing construction state; usually 0.
|
||||
*/
|
||||
nsresult HandleStartToken(CToken* aToken);
|
||||
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode);
|
||||
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsCParserNode *aNode);
|
||||
nsresult HandleEndToken(CToken* aToken);
|
||||
nsresult HandleEntityToken(CToken* aToken);
|
||||
nsresult HandleCommentToken(CToken* aToken);
|
||||
@ -424,14 +424,14 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @param node to be opened in content sink.
|
||||
* @return error code representing error condition-- usually 0.
|
||||
*/
|
||||
nsresult OpenHTML(const nsIParserNode *aNode);
|
||||
nsresult OpenHTML(const nsCParserNode *aNode);
|
||||
nsresult OpenHead(const nsIParserNode *aNode);
|
||||
nsresult OpenBody(const nsIParserNode *aNode);
|
||||
nsresult OpenBody(const nsCParserNode *aNode);
|
||||
nsresult OpenForm(const nsIParserNode *aNode);
|
||||
nsresult OpenMap(const nsIParserNode *aNode);
|
||||
nsresult OpenFrameset(const nsIParserNode *aNode);
|
||||
nsresult OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack=0);
|
||||
nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack=0);
|
||||
nsresult OpenMap(const nsCParserNode *aNode);
|
||||
nsresult OpenFrameset(const nsCParserNode *aNode);
|
||||
nsresult OpenNoscript(const nsCParserNode *aNode,nsEntryStack* aStyleStack=0);
|
||||
nsresult OpenContainer(const nsCParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack=0);
|
||||
|
||||
/**
|
||||
* The next set of methods close the given HTML element.
|
||||
@ -454,7 +454,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @update gess5/11/98
|
||||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag);
|
||||
nsresult CloseContainer(const nsCParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag);
|
||||
nsresult CloseContainersTo(eHTMLTags aTag,PRBool aClosedByStartTag);
|
||||
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aClosedByStartTag);
|
||||
|
||||
|
||||
@ -463,7 +463,7 @@ nsresult COtherDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPar
|
||||
while(theIndex>0) {
|
||||
eHTMLTags theParent= mBodyContext->TagAt(--theIndex);
|
||||
CElement *theElement=gElementTable->mElements[theParent];
|
||||
nsIParserNode *theNode=mBodyContext->PeekNode();
|
||||
nsCParserNode *theNode=mBodyContext->PeekNode();
|
||||
theElement->HandleEndToken(theNode,theChild,mBodyContext,mSink);
|
||||
theChild=theParent;
|
||||
}
|
||||
@ -489,7 +489,7 @@ nsresult COtherDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPar
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -546,7 +546,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
mDTDState=result;
|
||||
@ -701,7 +701,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsresult result=NS_OK;
|
||||
nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
if(theNode) {
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
@ -743,7 +743,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
} //if
|
||||
}//if
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, mNodeAllocator);
|
||||
}
|
||||
else result=NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -788,10 +788,10 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
|
||||
}
|
||||
CElement* theElement=gElementTable->mElements[theParent];
|
||||
if(theElement) {
|
||||
nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
if(theNode) {
|
||||
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, mNodeAllocator);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -211,19 +211,19 @@ public:
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink);
|
||||
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink);
|
||||
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink);
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink);
|
||||
|
||||
virtual nsresult HandleMisplacedStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleMisplacedStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual PRInt32 FindAutoCloseTargetForEndTag(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink, PRInt32& anIndex) {
|
||||
virtual PRInt32 FindAutoCloseTargetForEndTag(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink, PRInt32& anIndex) {
|
||||
PRInt32 result=-1;
|
||||
|
||||
if(mTag!=aTag) {
|
||||
@ -288,7 +288,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
|
||||
aContext->Push(aNode);
|
||||
|
||||
@ -300,7 +300,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
OpenContext(aNode,aTag,aContext,aSink);
|
||||
return OpenContainer(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
@ -315,22 +315,22 @@ public:
|
||||
/**********************************************************
|
||||
this gets called to close a tag in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult CloseContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsEntryStack *theStack=0;
|
||||
nsIParserNode *theNode=aContext->Pop(theStack);
|
||||
nsCParserNode *theNode=aContext->Pop(theStack);
|
||||
|
||||
CElement *theElement=(aTag==mTag) ? this : GetElement(aTag);
|
||||
result=theElement->NotifyClose(theNode,aTag,aContext,aSink);
|
||||
|
||||
NS_IF_RELEASE(aNode);
|
||||
IF_FREE(aNode, aContext->mNodeAllocator);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
this gets called to close a tag in the sink and in the context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult CloseContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag!=aTag) {
|
||||
CElement *theElement=GetElement(aTag);
|
||||
@ -762,7 +762,7 @@ public:
|
||||
/**********************************************************
|
||||
Table handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
@ -808,7 +808,7 @@ public:
|
||||
if(aContext->mTableStates) {
|
||||
if(aContext->mTableStates->CanOpenTBody()) {
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
|
||||
nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
|
||||
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
|
||||
}
|
||||
@ -831,7 +831,7 @@ public:
|
||||
/**********************************************************
|
||||
Table handles the closing of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aContext->HasOpenContainer(aTag)) {
|
||||
@ -981,7 +981,7 @@ public:
|
||||
/**********************************************************
|
||||
handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -992,7 +992,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
CElement::OpenContext(aNode,aTag,aContext,aSink);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -1013,7 +1013,7 @@ public:
|
||||
/**********************************************************
|
||||
handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
return CElement::HandleEndToken(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
|
||||
@ -1262,7 +1262,7 @@ public:
|
||||
/**********************************************************
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult NotifyClose(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
@ -1358,7 +1358,7 @@ public:
|
||||
/**********************************************************
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult NotifyClose(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
@ -1397,7 +1397,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
OpenContext(aNode,aTag,aContext,aSink);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1418,7 +1418,7 @@ public:
|
||||
/**********************************************************
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult NotifyClose(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aContext->HasOpenContainer(eHTMLTag_body)) {
|
||||
@ -1464,7 +1464,7 @@ public:
|
||||
/**********************************************************
|
||||
Pre handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=CElement::HandleStartToken(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
@ -1473,7 +1473,7 @@ public:
|
||||
/**********************************************************
|
||||
Pre handles the closing of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=CElement::HandleEndToken(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
@ -1512,7 +1512,7 @@ public:
|
||||
/**********************************************************
|
||||
handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsIParserNode *theNode=aContext->PeekNode();
|
||||
if(theNode) {
|
||||
@ -1569,7 +1569,7 @@ public:
|
||||
/**********************************************************
|
||||
fieldset handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsIParserNode *theNode=aContext->PeekNode();
|
||||
if(theNode) {
|
||||
@ -1624,7 +1624,7 @@ public:
|
||||
/**********************************************************
|
||||
Toplevel handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -1643,7 +1643,7 @@ public:
|
||||
/**********************************************************
|
||||
TopLevel handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
@ -1728,7 +1728,7 @@ public:
|
||||
/**********************************************************
|
||||
HTML handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -1795,7 +1795,7 @@ public:
|
||||
//let's auto open the body
|
||||
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
|
||||
nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
|
||||
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
|
||||
@ -1816,7 +1816,7 @@ public:
|
||||
/**********************************************************
|
||||
HTML handles the closing of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
@ -1886,7 +1886,7 @@ public:
|
||||
}
|
||||
|
||||
//this gets called after each tag is opened in the given context
|
||||
virtual nsresult OpenContainer(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainer(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag==aTag) {
|
||||
// Close the head before opening a body.
|
||||
@ -1903,7 +1903,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"need a valid context");
|
||||
nsresult result=NS_OK;
|
||||
// Since BODY is optional, we might come across more than one BODY!.
|
||||
@ -1922,7 +1922,7 @@ public:
|
||||
/**********************************************************
|
||||
Body handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -1951,7 +1951,7 @@ public:
|
||||
Body doesnt really need to handle it's own kids, but it's
|
||||
a really convenient break point for debugging purposes.
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
switch(aTag) {
|
||||
case eHTMLTag_script:
|
||||
@ -2645,7 +2645,7 @@ nsresult CElement::WillHandleStartToken( CElement *anElement,
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
nsresult CElement::HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -2700,7 +2700,7 @@ nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
theParentTag=aContext->Last();
|
||||
theParent=gElementTable->mElements[theParentTag];
|
||||
|
||||
nsIParserNode *theNode=aContext->PeekNode(); //this will get popped later...
|
||||
nsCParserNode *theNode=aContext->PeekNode(); //this will get popped later...
|
||||
if(theParent->IsSinkContainer()) {
|
||||
CloseContainerInContext(theNode,theParentTag,aContext,aSink);
|
||||
}
|
||||
@ -2755,7 +2755,7 @@ nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
}
|
||||
|
||||
|
||||
nsresult CElement::HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult CElement::HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aContext->Last()==aTag) {
|
||||
|
||||
@ -123,7 +123,7 @@ void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
|
||||
*
|
||||
* @update gess 04/22/99
|
||||
*/
|
||||
void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
void nsEntryStack::Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(aNode) {
|
||||
|
||||
EnsureCapacityFor(mCount+1);
|
||||
@ -131,9 +131,9 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
|
||||
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[mCount].mNode=(nsIParserNode*)aNode;
|
||||
mEntries[mCount].mNode=NS_CONST_CAST(nsCParserNode*,aNode);
|
||||
|
||||
NS_ADDREF(mEntries[mCount].mNode);
|
||||
IF_HOLD(mEntries[mCount].mNode);
|
||||
|
||||
mEntries[mCount].mParent=aStyleStack;
|
||||
mEntries[mCount++].mStyles=0;
|
||||
@ -146,7 +146,7 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
*
|
||||
* @update gess 11/10/99
|
||||
*/
|
||||
void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
void nsEntryStack::PushFront(const nsCParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(aNode) {
|
||||
|
||||
if(mCount<mCapacity) {
|
||||
@ -161,9 +161,9 @@ void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStac
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
|
||||
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[0].mNode=(nsIParserNode*)aNode;
|
||||
mEntries[0].mNode=NS_CONST_CAST(nsCParserNode*,aNode);
|
||||
|
||||
NS_ADDREF(mEntries[0].mNode);
|
||||
IF_HOLD(mEntries[0].mNode);
|
||||
|
||||
mEntries[0].mParent=aStyleStack;
|
||||
mEntries[0].mStyles=0;
|
||||
@ -203,8 +203,8 @@ void nsEntryStack::Append(nsEntryStack *aStack) {
|
||||
* aTag: the id of the tag to be removed
|
||||
* @update gess 02/25/00
|
||||
*/
|
||||
nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
nsCParserNode* result=0;
|
||||
|
||||
if((0<mCount) && (anIndex<mCount)){
|
||||
result=mEntries[anIndex].mNode;
|
||||
@ -246,9 +246,9 @@ nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
*/
|
||||
nsIParserNode* nsEntryStack::Pop(void) {
|
||||
nsCParserNode* nsEntryStack::Pop(void) {
|
||||
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
if(0<mCount) {
|
||||
result=mEntries[--mCount].mNode;
|
||||
@ -297,8 +297,8 @@ eHTMLTags nsEntryStack::First() const {
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
*/
|
||||
nsIParserNode* nsEntryStack::NodeAt(PRInt32 anIndex) const {
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* nsEntryStack::NodeAt(PRInt32 anIndex) const {
|
||||
nsCParserNode* result=0;
|
||||
if((0<mCount) && (anIndex<mCount)) {
|
||||
result=mEntries[anIndex].mNode;
|
||||
}
|
||||
@ -885,7 +885,7 @@ PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
void nsDTDContext::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
void nsDTDContext::Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(aNode) {
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
@ -894,7 +894,7 @@ void nsDTDContext::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(size< eMaxTags)
|
||||
mXTags[size]=theTag;
|
||||
#endif
|
||||
mStack.Push((nsIParserNode*)aNode,aStyleStack);
|
||||
mStack.Push(aNode,aStyleStack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,10 +902,10 @@ void nsDTDContext::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
* @update gess 11/11/99,
|
||||
* harishd 04/04/99
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
nsCParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
|
||||
PRInt32 theSize=mStack.mCount;
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
if(0<theSize) {
|
||||
|
||||
@ -932,7 +932,7 @@ nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
* @update harishd 04/07/00
|
||||
*/
|
||||
|
||||
nsIParserNode* nsDTDContext::Pop() {
|
||||
nsCParserNode* nsDTDContext::Pop() {
|
||||
nsEntryStack *theTempStyleStack=0; // This has no use here...
|
||||
return Pop(theTempStyleStack);
|
||||
}
|
||||
@ -992,7 +992,7 @@ nsEntryStack* nsDTDContext::GetStylesAt(PRInt32 anIndex) const {
|
||||
*
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
void nsDTDContext::PushStyle(const nsIParserNode* aNode){
|
||||
void nsDTDContext::PushStyle(const nsCParserNode* aNode){
|
||||
|
||||
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
|
||||
if(theEntry ) {
|
||||
@ -1045,8 +1045,8 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||
// If you're here it means that we have hit the rock bottom
|
||||
// ,of the stack, and there's no need to handle anymore styles.
|
||||
// Fix for bug 29048
|
||||
nsIParserNode* theNode=aStyles->Pop();
|
||||
NS_IF_RELEASE(theNode);
|
||||
nsCParserNode* theNode=aStyles->Pop();
|
||||
IF_HOLD(theNode);
|
||||
delete aStyles;
|
||||
aStyles=0;
|
||||
}
|
||||
@ -1058,8 +1058,8 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||
*
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::PopStyle(void){
|
||||
nsIParserNode *result=0;
|
||||
nsCParserNode* nsDTDContext::PopStyle(void){
|
||||
nsCParserNode *result=0;
|
||||
|
||||
nsTagEntry *theEntry=mStack.EntryAt(mStack.mCount-1);
|
||||
if(theEntry && (theEntry->mNode)) {
|
||||
@ -1076,10 +1076,10 @@ nsIParserNode* nsDTDContext::PopStyle(void){
|
||||
*
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
nsCParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
|
||||
PRInt32 theLevel=0;
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||
@ -1105,10 +1105,10 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
*
|
||||
* @update gess 01/26/00
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||
nsCParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||
|
||||
PRInt32 theLevel=0;
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||
@ -1337,7 +1337,7 @@ nsNodeAllocator::~nsNodeAllocator() {
|
||||
#endif
|
||||
}
|
||||
|
||||
nsIParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
|
||||
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
|
||||
nsCParserNode* result=0;
|
||||
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
@ -1352,18 +1352,18 @@ nsIParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,ns
|
||||
result->Init(aToken,aLineNumber,aTokenAllocator,this);
|
||||
}
|
||||
else{
|
||||
result=new nsCParserNode(aToken,aLineNumber,aTokenAllocator,this);
|
||||
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
|
||||
#ifdef DEBUG_TRACK_NODES
|
||||
mCount++;
|
||||
AddNode(NS_STATIC_CAST(nsCParserNode*,result));
|
||||
#endif
|
||||
NS_IF_ADDREF(result);
|
||||
IF_HOLD(result);
|
||||
}
|
||||
#else
|
||||
result=new(mNodePool) nsCParserNode(aToken,aLineNumber,aTokenAllocator);
|
||||
NS_IF_ADDREF(result);
|
||||
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
|
||||
IF_HOLD(result);
|
||||
#endif
|
||||
return NS_STATIC_CAST(nsIParserNode*,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#define IF_HOLD(_ptr) if(_ptr) { _ptr->AddRef(); }
|
||||
#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
|
||||
#define IF_FREE(_ptr, _allocator) if(_ptr) { _ptr->Release((_allocator)->GetArenaPool()); _ptr=0; } // recycles _ptr
|
||||
|
||||
class nsIParserNode;
|
||||
class nsCParserNode;
|
||||
@ -67,7 +67,7 @@ class nsEntryStack; //forware declare to make compilers happy.
|
||||
|
||||
struct nsTagEntry {
|
||||
eHTMLTags mTag; //for speedier access to tag id
|
||||
nsIParserNode* mNode;
|
||||
nsCParserNode* mNode;
|
||||
nsEntryStack* mParent;
|
||||
nsEntryStack* mStyles;
|
||||
};
|
||||
@ -78,12 +78,12 @@ public:
|
||||
~nsEntryStack();
|
||||
|
||||
void EnsureCapacityFor(PRInt32 aNewMax, PRInt32 aShiftOffset=0);
|
||||
void Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void PushFront(const nsCParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void Append(nsEntryStack *theStack);
|
||||
nsIParserNode* Pop(void);
|
||||
nsIParserNode* Remove(PRInt32 anIndex,eHTMLTags aTag);
|
||||
nsIParserNode* NodeAt(PRInt32 anIndex) const;
|
||||
nsCParserNode* Pop(void);
|
||||
nsCParserNode* Remove(PRInt32 anIndex,eHTMLTags aTag);
|
||||
nsCParserNode* NodeAt(PRInt32 anIndex) const;
|
||||
eHTMLTags First() const;
|
||||
eHTMLTags TagAt(PRInt32 anIndex) const;
|
||||
nsTagEntry* EntryAt(PRInt32 anIndex) const;
|
||||
@ -229,6 +229,8 @@ public:
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsAReadableString& aString);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag);
|
||||
|
||||
nsFixedSizeAllocator& GetArenaPool() { return mArenaPool; }
|
||||
|
||||
protected:
|
||||
nsFixedSizeAllocator mArenaPool;
|
||||
|
||||
@ -245,23 +247,30 @@ protected:
|
||||
that get created during the run of the system.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef HEAP_ALLOCATED_NODES
|
||||
class nsCParserNode;
|
||||
#endif
|
||||
|
||||
class nsNodeAllocator {
|
||||
public:
|
||||
|
||||
nsNodeAllocator();
|
||||
virtual ~nsNodeAllocator();
|
||||
virtual nsIParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
virtual nsCParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
|
||||
nsFixedSizeAllocator& GetArenaPool() { return mNodePool; }
|
||||
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
void Recycle(nsIParserNode* aNode) { mSharedNodes.Push(NS_STATIC_CAST(void*,aNode)); }
|
||||
void Recycle(nsCParserNode* aNode) { mSharedNodes.Push(NS_STATIC_CAST(void*,aNode)); }
|
||||
protected:
|
||||
nsDeque mSharedNodes;
|
||||
#ifdef DEBUG_TRACK_NODES
|
||||
PRInt32 mCount;
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsFixedSizeAllocator mNodePool;
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
@ -273,10 +282,10 @@ public:
|
||||
nsDTDContext();
|
||||
~nsDTDContext();
|
||||
|
||||
void Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
nsIParserNode* Pop(nsEntryStack*& aChildStack);
|
||||
nsIParserNode* Pop();
|
||||
nsIParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
|
||||
void Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
nsCParserNode* Pop(nsEntryStack*& aChildStack);
|
||||
nsCParserNode* Pop();
|
||||
nsCParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
|
||||
eHTMLTags First(void) const;
|
||||
eHTMLTags Last(void) const;
|
||||
nsTagEntry* LastEntry(void) const;
|
||||
@ -290,11 +299,11 @@ public:
|
||||
PRInt32 GetCount(void) {return mStack.mCount;}
|
||||
PRInt32 GetResidualStyleCount(void) {return mResidualStyleCount;}
|
||||
nsEntryStack* GetStylesAt(PRInt32 anIndex) const;
|
||||
void PushStyle(const nsIParserNode* aNode);
|
||||
void PushStyle(const nsCParserNode* aNode);
|
||||
void PushStyles(nsEntryStack *theStyles);
|
||||
nsIParserNode* PopStyle(void);
|
||||
nsIParserNode* PopStyle(eHTMLTags aTag);
|
||||
nsIParserNode* RemoveStyle(eHTMLTags aTag);
|
||||
nsCParserNode* PopStyle(void);
|
||||
nsCParserNode* PopStyle(eHTMLTags aTag);
|
||||
nsCParserNode* RemoveStyle(eHTMLTags aTag);
|
||||
|
||||
static void ReleaseGlobalObjects(void);
|
||||
|
||||
@ -342,10 +351,16 @@ public:
|
||||
Now define the token deallocator class...
|
||||
**************************************************************/
|
||||
class CTokenDeallocator: public nsDequeFunctor{
|
||||
protected:
|
||||
nsFixedSizeAllocator& mArenaPool;
|
||||
|
||||
public:
|
||||
CTokenDeallocator(nsFixedSizeAllocator& aArenaPool)
|
||||
: mArenaPool(aArenaPool) {}
|
||||
|
||||
virtual void* operator()(void* anObject) {
|
||||
CToken* aToken = (CToken*)anObject;
|
||||
delete aToken;
|
||||
CToken::Destroy(aToken, mArenaPool);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -234,7 +234,7 @@ NS_IMETHODIMP nsExpatDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
@ -133,7 +133,7 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
|
||||
*/
|
||||
nsHTMLTokenizer::~nsHTMLTokenizer(){
|
||||
if(mTokenDeque.GetSize()){
|
||||
CTokenDeallocator theDeallocator;
|
||||
CTokenDeallocator theDeallocator(mTokenAllocator->GetArenaPool());
|
||||
mTokenDeque.ForEach(theDeallocator);
|
||||
}
|
||||
}
|
||||
@ -149,7 +149,7 @@ void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,
|
||||
aDeque->Push(aToken);
|
||||
}
|
||||
else {
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, aTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -589,12 +589,12 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
AddToken((CToken*&)theToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
else {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){
|
||||
aToken->SetEmpty(PR_TRUE);
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result)
|
||||
result=NS_OK;
|
||||
}
|
||||
@ -728,7 +728,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
AddToken(endToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
else {
|
||||
IF_FREE(text);
|
||||
IF_FREE(text, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -742,11 +742,11 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
while(mTokenDeque.GetSize()>theDequeSize) {
|
||||
CToken* theToken=(CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
else IF_FREE(aToken);
|
||||
else IF_FREE(aToken, mTokenAllocator);
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
@ -900,7 +900,7 @@ nsresult nsHTMLTokenizer::ConsumeText(CToken*& aToken,nsScanner& aScanner){
|
||||
result=theToken->Consume(ch,aScanner,mParseMode);
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
if(0==theToken->GetTextLength()){
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
aToken = nsnull;
|
||||
}
|
||||
else result=NS_OK;
|
||||
|
||||
@ -114,6 +114,8 @@ protected:
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CStartToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CStartToken(eHTMLTags aTag=eHTMLTag_unknown);
|
||||
CStartToken(const nsAReadableString& aString);
|
||||
@ -168,6 +170,8 @@ class CStartToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CEndToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CEndToken(eHTMLTags aTag);
|
||||
CEndToken(const nsAReadableString& aString);
|
||||
@ -195,6 +199,8 @@ class CEndToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CCommentToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CCommentToken();
|
||||
CCommentToken(const nsAReadableString& aString);
|
||||
@ -217,6 +223,8 @@ class CCommentToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CEntityToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CEntityToken();
|
||||
CEntityToken(const nsAReadableString& aString);
|
||||
@ -244,6 +252,8 @@ class CEntityToken : public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CWhitespaceToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CWhitespaceToken();
|
||||
CWhitespaceToken(const nsAReadableString& aString);
|
||||
@ -264,6 +274,8 @@ class CWhitespaceToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CTextToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CTextToken();
|
||||
CTextToken(const nsAReadableString& aString);
|
||||
@ -291,6 +303,8 @@ class CTextToken: public CHTMLToken {
|
||||
* @update vidur 11/12/98
|
||||
*/
|
||||
class CCDATASectionToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CCDATASectionToken();
|
||||
CCDATASectionToken(const nsAReadableString& aString);
|
||||
@ -311,6 +325,8 @@ public:
|
||||
*
|
||||
*/
|
||||
class CMarkupDeclToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CMarkupDeclToken();
|
||||
CMarkupDeclToken(const nsAReadableString& aString);
|
||||
@ -333,6 +349,8 @@ protected:
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CAttributeToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CAttributeToken();
|
||||
CAttributeToken(const nsAReadableString& aString);
|
||||
@ -367,6 +385,8 @@ class CAttributeToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CNewlineToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CNewlineToken();
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
@ -389,6 +409,8 @@ class CNewlineToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CScriptToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CScriptToken();
|
||||
CScriptToken(const nsAReadableString& aString);
|
||||
@ -410,6 +432,8 @@ class CScriptToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CStyleToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CStyleToken();
|
||||
CStyleToken(const nsAReadableString& aString);
|
||||
@ -430,6 +454,8 @@ class CStyleToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CInstructionToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CInstructionToken();
|
||||
CInstructionToken(const nsAReadableString& aString);
|
||||
@ -443,6 +469,8 @@ class CInstructionToken: public CHTMLToken {
|
||||
};
|
||||
|
||||
class CErrorToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CErrorToken(nsParserError* aError=0);
|
||||
~CErrorToken();
|
||||
@ -469,6 +497,8 @@ protected:
|
||||
*/
|
||||
|
||||
class CDoctypeDeclToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CDoctypeDeclToken(eHTMLTags aTag=eHTMLTag_unknown);
|
||||
CDoctypeDeclToken(const nsAReadableString& aString,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
|
||||
@ -65,7 +65,7 @@ class CToken;
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class nsIParserNode : public nsISupports {
|
||||
class nsIParserNode { // XXX Should be nsAParserNode
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ const nsString& GetEmptyString() {
|
||||
*/
|
||||
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator):
|
||||
nsIParserNode() {
|
||||
NS_INIT_REFCNT();
|
||||
mRefCnt = 0;
|
||||
MOZ_COUNT_CTOR(nsCParserNode);
|
||||
|
||||
static int theNodeCount=0;
|
||||
@ -88,9 +88,6 @@ nsCParserNode::~nsCParserNode() {
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsCParserNode)
|
||||
NS_IMPL_RELEASE(nsCParserNode)
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
@ -105,7 +102,7 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
|
||||
if(mAttributes && (mAttributes->GetSize())) {
|
||||
CToken* theAttrToken=0;
|
||||
while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
|
||||
IF_FREE(theAttrToken);
|
||||
IF_FREE(theAttrToken, aTokenAllocator);
|
||||
}
|
||||
}
|
||||
mToken=aToken;
|
||||
@ -121,40 +118,6 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called as part of our COM-like interfaces.
|
||||
* Its purpose is to create an interface to parser object
|
||||
* of some type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param nsIID id of object to discover
|
||||
* @param aInstancePtr ptr to newly discovered interface
|
||||
* @return NS_xxx result code
|
||||
*/
|
||||
nsresult nsCParserNode::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
||||
*aInstancePtr = (nsIParserNode*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kIParserNodeIID)) { //do IParser base class...
|
||||
*aInstancePtr = (nsIParserNode*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kClassIID)) { //do this class...
|
||||
*aInstancePtr = (nsCParserNode*)(this);
|
||||
}
|
||||
else {
|
||||
*aInstancePtr=0;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Causes the given attribute to be added to internal
|
||||
* mAttributes list, and mAttributeCount to be incremented.
|
||||
@ -380,7 +343,7 @@ nsresult nsCParserNode::ReleaseAll() {
|
||||
if(mAttributes) {
|
||||
CToken* theAttrToken=0;
|
||||
while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
|
||||
IF_FREE(theAttrToken);
|
||||
IF_FREE(theAttrToken, mTokenAllocator);
|
||||
}
|
||||
delete mAttributes;
|
||||
mAttributes=0;
|
||||
@ -389,7 +352,7 @@ nsresult nsCParserNode::ReleaseAll() {
|
||||
delete mSkippedContent;
|
||||
mSkippedContent=0;
|
||||
}
|
||||
IF_FREE(mToken);
|
||||
IF_FREE(mToken, mTokenAllocator);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -50,40 +50,59 @@
|
||||
class nsTokenAllocator;
|
||||
|
||||
class nsCParserNode : public nsIParserNode {
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mRefCnt;
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
void AddRef()
|
||||
{
|
||||
++mRefCnt;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
void* operator new(size_t aSize) {
|
||||
return ::operator new(aSize);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
*
|
||||
* @update harishd 01/01/01
|
||||
* @param aSize -
|
||||
* @param aArena - Allocate memory from this pool.
|
||||
*/
|
||||
static void * operator new (size_t aSize, nsFixedSizeAllocator& anArena)
|
||||
void Release(nsFixedSizeAllocator& aPool)
|
||||
{
|
||||
return anArena.Alloc(aSize);
|
||||
if (--mRefCnt == 0)
|
||||
Destroy(this, aPool);
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update harishd 01/01/01
|
||||
* @param aPtr - The memory that should be recycled/freed.
|
||||
* @param aSize - The size of memory that needs to be freed.
|
||||
*/
|
||||
static void operator delete (void* aPtr,size_t aSize)
|
||||
{
|
||||
// NodeAllocator would take care of heap allocated nodes..
|
||||
|
||||
#ifndef HEAP_ALLOCATED_NODES
|
||||
nsFixedSizeAllocator::Free(aPtr,aSize);
|
||||
private:
|
||||
|
||||
/**
|
||||
* Hide operator new; clients should use Create() instead.
|
||||
*/
|
||||
static void* operator new(size_t) { return 0; }
|
||||
|
||||
/**
|
||||
* Hide operator delete; clients should use Destroy() instead.
|
||||
*/
|
||||
static void operator delete(void*,size_t) {}
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
static nsCParserNode* Create(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator)
|
||||
{
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
return new
|
||||
#else
|
||||
nsFixedSizeAllocator& pool = aNodeAllocator->GetArenaPool();
|
||||
void* place = pool.Alloc(sizeof(nsCParserNode));
|
||||
return ::new (place)
|
||||
#endif
|
||||
nsCParserNode(aToken, aLineNumber, aTokenAllocator, aNodeAllocator);
|
||||
}
|
||||
|
||||
static void Destroy(nsCParserNode* aNode, nsFixedSizeAllocator& aPool)
|
||||
{
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
delete aNode;
|
||||
#else
|
||||
aNode->~nsCParserNode();
|
||||
aPool.Free(aNode, sizeof(*aNode));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -248,7 +267,6 @@ class nsCParserNode : public nsIParserNode {
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
nsNodeAllocator* mNodeAllocator; // weak
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -33,6 +33,20 @@
|
||||
* of that particular token type gets detected in the
|
||||
* input stream.
|
||||
*
|
||||
* CToken objects that are allocated from the heap _must_ be allocated
|
||||
* using the nsTokenAllocator: the nsTokenAllocator object uses an
|
||||
* arena to manage the tokens.
|
||||
*
|
||||
* The nsTokenAllocator object's arena implementation requires
|
||||
* object size at destruction time to properly recycle the object;
|
||||
* therefore, CToken::operator delete() is not public. Instead,
|
||||
* heap-allocated tokens should be destroyed using the static
|
||||
* Destroy() method, which accepts a token and the arena from which
|
||||
* the token was allocated.
|
||||
*
|
||||
* Leaf classes (that are actually instantiated from the heap) must
|
||||
* implement the SizeOf() method, which Destroy() uses to determine
|
||||
* the size of the token in order to properly recycle it.
|
||||
*/
|
||||
|
||||
|
||||
@ -45,9 +59,8 @@
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
|
||||
|
||||
class nsScanner;
|
||||
|
||||
class nsTokenAllocator;
|
||||
|
||||
enum eContainerInfo {
|
||||
eWellFormed,
|
||||
@ -55,6 +68,14 @@ enum eContainerInfo {
|
||||
eFormUnknown
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement the SizeOf() method; leaf classes derived from CToken
|
||||
* must declare this.
|
||||
*/
|
||||
#define CTOKEN_IMPL_SIZEOF \
|
||||
protected: \
|
||||
virtual size_t SizeOf() const { return sizeof(*this); } \
|
||||
public:
|
||||
|
||||
/**
|
||||
* Token objects represent sequences of characters as they
|
||||
@ -70,27 +91,43 @@ class CToken {
|
||||
|
||||
enum eTokenOrigin {eSource,eResidualStyle};
|
||||
|
||||
protected:
|
||||
|
||||
// nsTokenAllocator should be the only class that tries to
|
||||
// allocate tokens from the heap.
|
||||
friend class nsTokenAllocator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aSize -
|
||||
* @param aArena - Allocate memory from this pool.
|
||||
*/
|
||||
static void * operator new (size_t aSize, nsFixedSizeAllocator& anArena)
|
||||
static void * operator new (size_t aSize,nsFixedSizeAllocator& anArena)
|
||||
{
|
||||
return anArena.Alloc(aSize);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aPtr - The memory that should be recycled/freed.
|
||||
* @param aSize - The size of memory that needs to be freed.
|
||||
* Hide operator delete; clients should use Destroy() instead.
|
||||
*/
|
||||
static void operator delete (void* aPtr,size_t aSize)
|
||||
static void operator delete (void*,size_t) {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* destructor
|
||||
* @update gess5/11/98
|
||||
*/
|
||||
virtual ~CToken();
|
||||
|
||||
/**
|
||||
* Destroy a token.
|
||||
*/
|
||||
static void Destroy(CToken* aToken,nsFixedSizeAllocator& aArenaPool)
|
||||
{
|
||||
nsFixedSizeAllocator::Free(aPtr,aSize);
|
||||
size_t sz = aToken->SizeOf();
|
||||
aToken->~CToken();
|
||||
aArenaPool.Free(aToken, sz);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,22 +140,17 @@ class CToken {
|
||||
* Free yourself if no one is holding you.
|
||||
* @update harishd 08/02/00
|
||||
*/
|
||||
void Release() {
|
||||
void Release(nsFixedSizeAllocator& aArenaPool) {
|
||||
if(--mUseCount==0)
|
||||
delete this;
|
||||
Destroy(this, aArenaPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* @update gess7/21/98
|
||||
*/
|
||||
CToken(PRInt32 aTag=0);
|
||||
|
||||
/**
|
||||
* destructor
|
||||
* @update gess5/11/98
|
||||
*/
|
||||
virtual ~CToken();
|
||||
|
||||
/**
|
||||
* Retrieve string value of the token
|
||||
* @update gess5/11/98
|
||||
@ -229,6 +261,10 @@ class CToken {
|
||||
PRInt32 mNewlineCount;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Returns the size of the token object.
|
||||
*/
|
||||
virtual size_t SizeOf() const = 0;
|
||||
|
||||
PRInt32 mTypeID;
|
||||
PRInt16 mAttrCount;
|
||||
|
||||
@ -534,7 +534,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
@ -258,7 +258,7 @@ NS_IMETHODIMP CWellFormedDTD::BuildModel(nsIParser* aParser,nsITokenizer* aToken
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else {
|
||||
// if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
@ -362,7 +362,7 @@ nsresult CWellFormedDTD::Terminate(nsIParser* aParser)
|
||||
if(theType==eToken_error) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
}
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
@ -717,7 +717,7 @@ nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
IF_FREE(token);
|
||||
IF_FREE(token, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@ -196,8 +196,8 @@ void CNavDTD::RecycleNodes(nsEntryStack *aNodeStack) {
|
||||
PRInt32 theIndex=0;
|
||||
|
||||
for(theIndex=0;theIndex<theCount;theIndex++) {
|
||||
nsIParserNode* node=aNodeStack->NodeAt(theIndex);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=aNodeStack->NodeAt(theIndex);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -587,12 +587,12 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
while(mBodyContext->GetCount() > 0) {
|
||||
|
||||
nsEntryStack *theChildStyles=0;
|
||||
nsIParserNode* theNode=mBodyContext->Pop(theChildStyles);
|
||||
nsCParserNode* theNode=mBodyContext->Pop(theChildStyles);
|
||||
if(theNode) {
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -637,7 +637,7 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParse
|
||||
|
||||
CToken* theToken=0;
|
||||
while((theToken=(CToken*)mMisplacedContent.Pop())) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
|
||||
if(mDTDDebug) {
|
||||
@ -726,7 +726,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
mSkipTarget=eHTMLTag_unknown; //stop skipping.
|
||||
//mTokenizer->PushTokenFront(aToken); //push the end token...
|
||||
execSkipContent=PR_TRUE;
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
}
|
||||
@ -741,7 +741,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
if(theType!=eToken_attribute) {
|
||||
aToken->AppendSource(mScratch);
|
||||
}
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
@ -889,7 +889,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
mDTDState=result;
|
||||
@ -937,7 +937,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
|
||||
if(eToken_newline==theType){
|
||||
mLineNumber++;
|
||||
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
|
||||
IF_FREE(theNextToken); // fix for Bug 29379
|
||||
IF_FREE(theNextToken, mTokenAllocator); // fix for Bug 29379
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
@ -1019,7 +1019,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
|
||||
CToken *theEndToken=mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag);
|
||||
if(theEndToken) {
|
||||
result=HandleEndToken(theEndToken);
|
||||
IF_FREE(theEndToken);
|
||||
IF_FREE(theEndToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1172,7 +1172,7 @@ enum eProcessRule {eNormalOp,eLetInlineContainBlock};
|
||||
* @param aNode -- CParserNode representing this start token
|
||||
* @return PR_TRUE if all went well; PR_FALSE if error occured
|
||||
*/
|
||||
nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode) {
|
||||
nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsCParserNode *aNode) {
|
||||
NS_PRECONDITION(0!=aToken,kNullToken);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -1607,7 +1607,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
PRInt16 attrCount=aToken->GetAttributeCount();
|
||||
@ -1724,7 +1724,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||
result=NS_OK;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1850,7 +1850,7 @@ static void StripWSFollowingTag(eHTMLTags aChildTag,nsITokenizer* aTokenizer,nsT
|
||||
case eToken_newline: aNewlineCount++;
|
||||
case eToken_whitespace:
|
||||
theToken=aTokenizer->PopToken();
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, aTokenAllocator);
|
||||
theToken=aTokenizer->PeekToken();
|
||||
break;
|
||||
default:
|
||||
@ -2039,9 +2039,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
nsEntryStack* theChildStyleStack=0;
|
||||
|
||||
for(i=0; i<(theTagCount - theTopIndex); i++) {
|
||||
nsIParserNode* node=mBodyContext->Pop(theChildStyleStack);
|
||||
nsCParserNode* node=mBodyContext->Pop(theChildStyleStack);
|
||||
mTempContext->Push(node);
|
||||
NS_IF_RELEASE(node); //release the popped node since push will addref for us.
|
||||
IF_FREE(node, &mNodeAllocator); //release the popped node since push will addref for us.
|
||||
}
|
||||
|
||||
// Now flush out all the bad contents.
|
||||
@ -2068,7 +2068,7 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
PRInt32 theIndex=mBodyContext->LastOf(theTag);
|
||||
|
||||
if(theIndex!=kNotFound && theIndex<=mBodyContext->mContextTopIndex) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -2082,9 +2082,9 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
||||
// Bad-contents were successfully processed. Now, itz time to get
|
||||
// back to the original body context state.
|
||||
for(PRInt32 k=0; k<(theTagCount - theTopIndex); k++) {
|
||||
nsIParserNode* node=mTempContext->Pop(theChildStyleStack);
|
||||
nsCParserNode* node=mTempContext->Pop(theChildStyleStack);
|
||||
mBodyContext->Push(node);
|
||||
NS_IF_RELEASE(node);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
|
||||
STOP_TIMER()
|
||||
@ -2135,7 +2135,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
|
||||
eHTMLTags theParentTag=mBodyContext->Last();
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
|
||||
if(CanOmit(theParentTag,eHTMLTag_entity,theParentContains)) {
|
||||
@ -2148,7 +2148,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
|
||||
#endif
|
||||
result=AddLeaf(theNode);
|
||||
}
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2172,7 +2172,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
const nsAReadableString& theComment = theToken->GetStringValue();
|
||||
mLineNumber += CountCharInReadable(theComment, PRUnichar(kNewLine));
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
@ -2184,7 +2184,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
|
||||
|
||||
result=(mSink) ? mSink->AddComment(*theNode) : NS_OK;
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2248,7 +2248,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
@ -2260,7 +2260,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
|
||||
|
||||
result=(mSink) ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2298,7 +2298,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
docTypeStr.Cut(0,2); // Now remove "<!" from the begining
|
||||
theToken->SetStringValue(docTypeStr);
|
||||
|
||||
nsIParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,0);
|
||||
if(theNode) {
|
||||
|
||||
STOP_TIMER();
|
||||
@ -2321,7 +2321,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
|
||||
|
||||
result = (mSink)? mSink->AddDocTypeDecl(*theNode,theMode):NS_OK;
|
||||
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
@ -2431,7 +2431,7 @@ nsresult CNavDTD::CollectSkippedContent(nsIParserNode& aNode,PRInt32 &aCount) {
|
||||
}
|
||||
else theNextToken->AppendSource(*theNode->mSkippedContent);
|
||||
}
|
||||
IF_FREE(theNextToken);
|
||||
IF_FREE(theNextToken, mTokenAllocator);
|
||||
}
|
||||
|
||||
// if the string contained CRs (hence is either CR, or CRLF terminated)
|
||||
@ -2899,8 +2899,8 @@ nsresult CNavDTD::OpenTransientStyles(eHTMLTags aChildTag){
|
||||
}
|
||||
else {
|
||||
//if the node tag can't contain the child tag, then remove the child tag from the style stack
|
||||
nsIParserNode* node=theStack->Remove(sindex,theNodeTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=theStack->Remove(sindex,theNodeTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
theEntry--; //back up by one
|
||||
}
|
||||
} //if
|
||||
@ -2967,8 +2967,8 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
if(mFlags & NS_PARSER_FLAG_ENABLE_RESIDUAL_STYLE) {
|
||||
#ifdef ENABLE_RESIDUALSTYLE
|
||||
if(nsHTMLElement::IsResidualStyleTag(aTag)) {
|
||||
nsIParserNode* node=mBodyContext->PopStyle(aTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(aTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
#endif
|
||||
} //if
|
||||
@ -2984,7 +2984,7 @@ nsresult CNavDTD::PopStyle(eHTMLTags aTag){
|
||||
* @update gess4/22/98
|
||||
* @param aNode -- next node to be added to model
|
||||
*/
|
||||
nsresult CNavDTD::OpenHTML(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenHTML(const nsCParserNode *aNode){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
STOP_TIMER();
|
||||
@ -3084,7 +3084,7 @@ nsresult CNavDTD::CloseHead(const nsIParserNode *aNode){
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult CNavDTD::OpenBody(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenBody(const nsCParserNode *aNode){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -3209,7 +3209,7 @@ nsresult CNavDTD::CloseForm(const nsIParserNode *aNode){
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult CNavDTD::OpenMap(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenMap(const nsCParserNode *aNode){
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenMap(), this=%p\n", this));
|
||||
@ -3260,7 +3260,7 @@ nsresult CNavDTD::CloseMap(const nsIParserNode *aNode){
|
||||
* @param aNode -- next node to be added to model
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult CNavDTD::OpenFrameset(const nsIParserNode *aNode){
|
||||
nsresult CNavDTD::OpenFrameset(const nsCParserNode *aNode){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
mFlags |= NS_PARSER_FLAG_HAD_FRAMESET;
|
||||
@ -3308,7 +3308,7 @@ nsresult CNavDTD::CloseFrameset(const nsIParserNode *aNode){
|
||||
* @param aNode - The noscript node
|
||||
* return NS_OK if succeeded else ERROR
|
||||
*/
|
||||
nsresult CNavDTD::OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack) {
|
||||
nsresult CNavDTD::OpenNoscript(const nsCParserNode *aNode,nsEntryStack* aStyleStack) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(mSink) {
|
||||
@ -3381,7 +3381,7 @@ nsresult CNavDTD::CloseNoscript(const nsIParserNode *aNode) {
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult
|
||||
CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack){
|
||||
CNavDTD::OpenContainer(const nsCParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack){
|
||||
NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -3505,7 +3505,7 @@ CNavDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedB
|
||||
* @return TRUE if ok, FALSE if error
|
||||
*/
|
||||
nsresult
|
||||
CNavDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag){
|
||||
CNavDTD::CloseContainer(const nsCParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag){
|
||||
nsresult result=NS_OK;
|
||||
eHTMLTags nodeType=(eHTMLTags)aNode->GetNodeType();
|
||||
|
||||
@ -3587,7 +3587,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
|
||||
nsEntryStack *theChildStyleStack=0;
|
||||
eHTMLTags theTag=mBodyContext->Last();
|
||||
nsCParserNode *theNode=NS_STATIC_CAST(nsCParserNode*,mBodyContext->Pop(theChildStyleStack));
|
||||
nsCParserNode *theNode=mBodyContext->Pop(theChildStyleStack);
|
||||
|
||||
if(theNode) {
|
||||
result=CloseContainer(theNode,aTarget,aClosedByStartTag);
|
||||
@ -3634,8 +3634,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
//here's a case we missed: <a><div>text<a>text</a></div>
|
||||
//The <div> pushes the 1st <a> onto the rs-stack, then the 2nd <a>
|
||||
//pops the 1st <a> from the rs-stack altogether.
|
||||
nsIParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
|
||||
|
||||
@ -3680,8 +3680,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
// This fixes bug 30885 and 29626
|
||||
// Make sure that the node, which is about to
|
||||
// get released does not stay on the style stack...
|
||||
nsIParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
mBodyContext->PushStyles(theChildStyleStack);
|
||||
}
|
||||
@ -3705,8 +3705,8 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
//style tag that got onto that tag stack from a stylestack somewhere.
|
||||
//Pop it from the stylestack if the target is also a style tag.
|
||||
if(theTargetTagIsStyle) {
|
||||
nsIParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
NS_IF_RELEASE(node);
|
||||
nsCParserNode* node=mBodyContext->PopStyle(theTag);
|
||||
IF_FREE(node, &mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3723,7 +3723,7 @@ nsresult CNavDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget, PRBool aC
|
||||
}
|
||||
}
|
||||
#endif
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, &mNodeAllocator);
|
||||
}//if theNode
|
||||
}
|
||||
|
||||
|
||||
@ -401,7 +401,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @return error code representing construction state; usually 0.
|
||||
*/
|
||||
nsresult HandleStartToken(CToken* aToken);
|
||||
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode);
|
||||
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsCParserNode *aNode);
|
||||
nsresult HandleEndToken(CToken* aToken);
|
||||
nsresult HandleEntityToken(CToken* aToken);
|
||||
nsresult HandleCommentToken(CToken* aToken);
|
||||
@ -424,14 +424,14 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @param node to be opened in content sink.
|
||||
* @return error code representing error condition-- usually 0.
|
||||
*/
|
||||
nsresult OpenHTML(const nsIParserNode *aNode);
|
||||
nsresult OpenHTML(const nsCParserNode *aNode);
|
||||
nsresult OpenHead(const nsIParserNode *aNode);
|
||||
nsresult OpenBody(const nsIParserNode *aNode);
|
||||
nsresult OpenBody(const nsCParserNode *aNode);
|
||||
nsresult OpenForm(const nsIParserNode *aNode);
|
||||
nsresult OpenMap(const nsIParserNode *aNode);
|
||||
nsresult OpenFrameset(const nsIParserNode *aNode);
|
||||
nsresult OpenNoscript(const nsIParserNode *aNode,nsEntryStack* aStyleStack=0);
|
||||
nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack=0);
|
||||
nsresult OpenMap(const nsCParserNode *aNode);
|
||||
nsresult OpenFrameset(const nsCParserNode *aNode);
|
||||
nsresult OpenNoscript(const nsCParserNode *aNode,nsEntryStack* aStyleStack=0);
|
||||
nsresult OpenContainer(const nsCParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,nsEntryStack* aStyleStack=0);
|
||||
|
||||
/**
|
||||
* The next set of methods close the given HTML element.
|
||||
@ -454,7 +454,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
|
||||
* @update gess5/11/98
|
||||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag);
|
||||
nsresult CloseContainer(const nsCParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag);
|
||||
nsresult CloseContainersTo(eHTMLTags aTag,PRBool aClosedByStartTag);
|
||||
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aClosedByStartTag);
|
||||
|
||||
|
||||
@ -463,7 +463,7 @@ nsresult COtherDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPar
|
||||
while(theIndex>0) {
|
||||
eHTMLTags theParent= mBodyContext->TagAt(--theIndex);
|
||||
CElement *theElement=gElementTable->mElements[theParent];
|
||||
nsIParserNode *theNode=mBodyContext->PeekNode();
|
||||
nsCParserNode *theNode=mBodyContext->PeekNode();
|
||||
theElement->HandleEndToken(theNode,theChild,mBodyContext,mSink);
|
||||
theChild=theParent;
|
||||
}
|
||||
@ -489,7 +489,7 @@ nsresult COtherDTD::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIPar
|
||||
if(theChildStyles) {
|
||||
delete theChildStyles;
|
||||
}
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, mNodeAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -546,7 +546,7 @@ nsresult COtherDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING)
|
||||
mDTDState=result;
|
||||
@ -701,7 +701,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
|
||||
//Begin by gathering up attributes...
|
||||
|
||||
nsresult result=NS_OK;
|
||||
nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
if(theNode) {
|
||||
|
||||
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
|
||||
@ -743,7 +743,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
|
||||
|
||||
} //if
|
||||
}//if
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, mNodeAllocator);
|
||||
}
|
||||
else result=NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -788,10 +788,10 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
|
||||
}
|
||||
CElement* theElement=gElementTable->mElements[theParent];
|
||||
if(theElement) {
|
||||
nsIParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
|
||||
if(theNode) {
|
||||
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
|
||||
NS_IF_RELEASE(theNode);
|
||||
IF_FREE(theNode, mNodeAllocator);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -211,19 +211,19 @@ public:
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink);
|
||||
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink);
|
||||
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink);
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink);
|
||||
|
||||
virtual nsresult HandleMisplacedStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleMisplacedStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual PRInt32 FindAutoCloseTargetForEndTag(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink, PRInt32& anIndex) {
|
||||
virtual PRInt32 FindAutoCloseTargetForEndTag(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink, PRInt32& anIndex) {
|
||||
PRInt32 result=-1;
|
||||
|
||||
if(mTag!=aTag) {
|
||||
@ -288,7 +288,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
|
||||
aContext->Push(aNode);
|
||||
|
||||
@ -300,7 +300,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
OpenContext(aNode,aTag,aContext,aSink);
|
||||
return OpenContainer(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
@ -315,22 +315,22 @@ public:
|
||||
/**********************************************************
|
||||
this gets called to close a tag in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult CloseContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsEntryStack *theStack=0;
|
||||
nsIParserNode *theNode=aContext->Pop(theStack);
|
||||
nsCParserNode *theNode=aContext->Pop(theStack);
|
||||
|
||||
CElement *theElement=(aTag==mTag) ? this : GetElement(aTag);
|
||||
result=theElement->NotifyClose(theNode,aTag,aContext,aSink);
|
||||
|
||||
NS_IF_RELEASE(aNode);
|
||||
IF_FREE(aNode, aContext->mNodeAllocator);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
this gets called to close a tag in the sink and in the context
|
||||
**********************************************************/
|
||||
virtual nsresult CloseContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult CloseContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag!=aTag) {
|
||||
CElement *theElement=GetElement(aTag);
|
||||
@ -762,7 +762,7 @@ public:
|
||||
/**********************************************************
|
||||
Table handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
@ -808,7 +808,7 @@ public:
|
||||
if(aContext->mTableStates) {
|
||||
if(aContext->mTableStates->CanOpenTBody()) {
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
|
||||
nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
|
||||
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
|
||||
}
|
||||
@ -831,7 +831,7 @@ public:
|
||||
/**********************************************************
|
||||
Table handles the closing of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aContext->HasOpenContainer(aTag)) {
|
||||
@ -981,7 +981,7 @@ public:
|
||||
/**********************************************************
|
||||
handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -992,7 +992,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
CElement::OpenContext(aNode,aTag,aContext,aSink);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
@ -1013,7 +1013,7 @@ public:
|
||||
/**********************************************************
|
||||
handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
return CElement::HandleEndToken(aNode,aTag,aContext,aSink);
|
||||
}
|
||||
|
||||
@ -1262,7 +1262,7 @@ public:
|
||||
/**********************************************************
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult NotifyClose(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
@ -1358,7 +1358,7 @@ public:
|
||||
/**********************************************************
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult NotifyClose(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
CElement* theHead=GetElement(eHTMLTag_head);
|
||||
if(theHead) {
|
||||
@ -1397,7 +1397,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
OpenContext(aNode,aTag,aContext,aSink);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1418,7 +1418,7 @@ public:
|
||||
/**********************************************************
|
||||
Call this for each element as it get's closed
|
||||
**********************************************************/
|
||||
virtual nsresult NotifyClose(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult NotifyClose(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aContext->HasOpenContainer(eHTMLTag_body)) {
|
||||
@ -1464,7 +1464,7 @@ public:
|
||||
/**********************************************************
|
||||
Pre handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=CElement::HandleStartToken(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
@ -1473,7 +1473,7 @@ public:
|
||||
/**********************************************************
|
||||
Pre handles the closing of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=CElement::HandleEndToken(aNode,aTag,aContext,aSink);
|
||||
return result;
|
||||
}
|
||||
@ -1512,7 +1512,7 @@ public:
|
||||
/**********************************************************
|
||||
handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsIParserNode *theNode=aContext->PeekNode();
|
||||
if(theNode) {
|
||||
@ -1569,7 +1569,7 @@ public:
|
||||
/**********************************************************
|
||||
fieldset handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleStartToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
nsIParserNode *theNode=aContext->PeekNode();
|
||||
if(theNode) {
|
||||
@ -1624,7 +1624,7 @@ public:
|
||||
/**********************************************************
|
||||
Toplevel handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -1643,7 +1643,7 @@ public:
|
||||
/**********************************************************
|
||||
TopLevel handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
@ -1728,7 +1728,7 @@ public:
|
||||
/**********************************************************
|
||||
HTML handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -1795,7 +1795,7 @@ public:
|
||||
//let's auto open the body
|
||||
|
||||
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
|
||||
nsIParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
|
||||
|
||||
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);
|
||||
|
||||
@ -1816,7 +1816,7 @@ public:
|
||||
/**********************************************************
|
||||
HTML handles the closing of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
switch(aTag) {
|
||||
@ -1886,7 +1886,7 @@ public:
|
||||
}
|
||||
|
||||
//this gets called after each tag is opened in the given context
|
||||
virtual nsresult OpenContainer(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainer(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
nsresult result=NS_OK;
|
||||
if(mTag==aTag) {
|
||||
// Close the head before opening a body.
|
||||
@ -1903,7 +1903,7 @@ public:
|
||||
/**********************************************************
|
||||
this gets called after each tag is opened in the given context
|
||||
**********************************************************/
|
||||
virtual nsresult OpenContainerInContext(nsIParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
virtual nsresult OpenContainerInContext(nsCParserNode *aNode,eHTMLTags aTag,nsDTDContext *aContext,nsIHTMLContentSink *aSink) {
|
||||
NS_ASSERTION(aContext!=nsnull,"need a valid context");
|
||||
nsresult result=NS_OK;
|
||||
// Since BODY is optional, we might come across more than one BODY!.
|
||||
@ -1922,7 +1922,7 @@ public:
|
||||
/**********************************************************
|
||||
Body handles the opening of it's own children
|
||||
**********************************************************/
|
||||
virtual nsresult HandleStartToken( nsIParserNode* aNode,
|
||||
virtual nsresult HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -1951,7 +1951,7 @@ public:
|
||||
Body doesnt really need to handle it's own kids, but it's
|
||||
a really convenient break point for debugging purposes.
|
||||
**********************************************************/
|
||||
virtual nsresult HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
virtual nsresult HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
switch(aTag) {
|
||||
case eHTMLTag_script:
|
||||
@ -2645,7 +2645,7 @@ nsresult CElement::WillHandleStartToken( CElement *anElement,
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
nsresult CElement::HandleStartToken( nsCParserNode* aNode,
|
||||
eHTMLTags aTag,
|
||||
nsDTDContext* aContext,
|
||||
nsIHTMLContentSink* aSink) {
|
||||
@ -2700,7 +2700,7 @@ nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
theParentTag=aContext->Last();
|
||||
theParent=gElementTable->mElements[theParentTag];
|
||||
|
||||
nsIParserNode *theNode=aContext->PeekNode(); //this will get popped later...
|
||||
nsCParserNode *theNode=aContext->PeekNode(); //this will get popped later...
|
||||
if(theParent->IsSinkContainer()) {
|
||||
CloseContainerInContext(theNode,theParentTag,aContext,aSink);
|
||||
}
|
||||
@ -2755,7 +2755,7 @@ nsresult CElement::HandleStartToken( nsIParserNode* aNode,
|
||||
}
|
||||
|
||||
|
||||
nsresult CElement::HandleEndToken(nsIParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult CElement::HandleEndToken(nsCParserNode* aNode,eHTMLTags aTag,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
|
||||
nsresult result=NS_OK;
|
||||
|
||||
if(aContext->Last()==aTag) {
|
||||
|
||||
@ -123,7 +123,7 @@ void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
|
||||
*
|
||||
* @update gess 04/22/99
|
||||
*/
|
||||
void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
void nsEntryStack::Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(aNode) {
|
||||
|
||||
EnsureCapacityFor(mCount+1);
|
||||
@ -131,9 +131,9 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
|
||||
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[mCount].mNode=(nsIParserNode*)aNode;
|
||||
mEntries[mCount].mNode=NS_CONST_CAST(nsCParserNode*,aNode);
|
||||
|
||||
NS_ADDREF(mEntries[mCount].mNode);
|
||||
IF_HOLD(mEntries[mCount].mNode);
|
||||
|
||||
mEntries[mCount].mParent=aStyleStack;
|
||||
mEntries[mCount++].mStyles=0;
|
||||
@ -146,7 +146,7 @@ void nsEntryStack::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
*
|
||||
* @update gess 11/10/99
|
||||
*/
|
||||
void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
void nsEntryStack::PushFront(const nsCParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(aNode) {
|
||||
|
||||
if(mCount<mCapacity) {
|
||||
@ -161,9 +161,9 @@ void nsEntryStack::PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStac
|
||||
((nsCParserNode*)aNode)->mUseCount++;
|
||||
|
||||
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
|
||||
mEntries[0].mNode=(nsIParserNode*)aNode;
|
||||
mEntries[0].mNode=NS_CONST_CAST(nsCParserNode*,aNode);
|
||||
|
||||
NS_ADDREF(mEntries[0].mNode);
|
||||
IF_HOLD(mEntries[0].mNode);
|
||||
|
||||
mEntries[0].mParent=aStyleStack;
|
||||
mEntries[0].mStyles=0;
|
||||
@ -203,8 +203,8 @@ void nsEntryStack::Append(nsEntryStack *aStack) {
|
||||
* aTag: the id of the tag to be removed
|
||||
* @update gess 02/25/00
|
||||
*/
|
||||
nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
nsCParserNode* result=0;
|
||||
|
||||
if((0<mCount) && (anIndex<mCount)){
|
||||
result=mEntries[anIndex].mNode;
|
||||
@ -246,9 +246,9 @@ nsIParserNode* nsEntryStack::Remove(PRInt32 anIndex,eHTMLTags aTag) {
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
*/
|
||||
nsIParserNode* nsEntryStack::Pop(void) {
|
||||
nsCParserNode* nsEntryStack::Pop(void) {
|
||||
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
if(0<mCount) {
|
||||
result=mEntries[--mCount].mNode;
|
||||
@ -297,8 +297,8 @@ eHTMLTags nsEntryStack::First() const {
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
*/
|
||||
nsIParserNode* nsEntryStack::NodeAt(PRInt32 anIndex) const {
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* nsEntryStack::NodeAt(PRInt32 anIndex) const {
|
||||
nsCParserNode* result=0;
|
||||
if((0<mCount) && (anIndex<mCount)) {
|
||||
result=mEntries[anIndex].mNode;
|
||||
}
|
||||
@ -885,7 +885,7 @@ PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
void nsDTDContext::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
void nsDTDContext::Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(aNode) {
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
@ -894,7 +894,7 @@ void nsDTDContext::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
if(size< eMaxTags)
|
||||
mXTags[size]=theTag;
|
||||
#endif
|
||||
mStack.Push((nsIParserNode*)aNode,aStyleStack);
|
||||
mStack.Push(aNode,aStyleStack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,10 +902,10 @@ void nsDTDContext::Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack) {
|
||||
* @update gess 11/11/99,
|
||||
* harishd 04/04/99
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
nsCParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
|
||||
PRInt32 theSize=mStack.mCount;
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
if(0<theSize) {
|
||||
|
||||
@ -932,7 +932,7 @@ nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
|
||||
* @update harishd 04/07/00
|
||||
*/
|
||||
|
||||
nsIParserNode* nsDTDContext::Pop() {
|
||||
nsCParserNode* nsDTDContext::Pop() {
|
||||
nsEntryStack *theTempStyleStack=0; // This has no use here...
|
||||
return Pop(theTempStyleStack);
|
||||
}
|
||||
@ -992,7 +992,7 @@ nsEntryStack* nsDTDContext::GetStylesAt(PRInt32 anIndex) const {
|
||||
*
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
void nsDTDContext::PushStyle(const nsIParserNode* aNode){
|
||||
void nsDTDContext::PushStyle(const nsCParserNode* aNode){
|
||||
|
||||
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
|
||||
if(theEntry ) {
|
||||
@ -1045,8 +1045,8 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||
// If you're here it means that we have hit the rock bottom
|
||||
// ,of the stack, and there's no need to handle anymore styles.
|
||||
// Fix for bug 29048
|
||||
nsIParserNode* theNode=aStyles->Pop();
|
||||
NS_IF_RELEASE(theNode);
|
||||
nsCParserNode* theNode=aStyles->Pop();
|
||||
IF_HOLD(theNode);
|
||||
delete aStyles;
|
||||
aStyles=0;
|
||||
}
|
||||
@ -1058,8 +1058,8 @@ void nsDTDContext::PushStyles(nsEntryStack *aStyles){
|
||||
*
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::PopStyle(void){
|
||||
nsIParserNode *result=0;
|
||||
nsCParserNode* nsDTDContext::PopStyle(void){
|
||||
nsCParserNode *result=0;
|
||||
|
||||
nsTagEntry *theEntry=mStack.EntryAt(mStack.mCount-1);
|
||||
if(theEntry && (theEntry->mNode)) {
|
||||
@ -1076,10 +1076,10 @@ nsIParserNode* nsDTDContext::PopStyle(void){
|
||||
*
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
nsCParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
|
||||
PRInt32 theLevel=0;
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||
@ -1105,10 +1105,10 @@ nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
*
|
||||
* @update gess 01/26/00
|
||||
*/
|
||||
nsIParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||
nsCParserNode* nsDTDContext::RemoveStyle(eHTMLTags aTag){
|
||||
|
||||
PRInt32 theLevel=0;
|
||||
nsIParserNode* result=0;
|
||||
nsCParserNode* result=0;
|
||||
|
||||
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
|
||||
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
|
||||
@ -1337,7 +1337,7 @@ nsNodeAllocator::~nsNodeAllocator() {
|
||||
#endif
|
||||
}
|
||||
|
||||
nsIParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
|
||||
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
|
||||
nsCParserNode* result=0;
|
||||
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
@ -1352,18 +1352,18 @@ nsIParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,ns
|
||||
result->Init(aToken,aLineNumber,aTokenAllocator,this);
|
||||
}
|
||||
else{
|
||||
result=new nsCParserNode(aToken,aLineNumber,aTokenAllocator,this);
|
||||
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
|
||||
#ifdef DEBUG_TRACK_NODES
|
||||
mCount++;
|
||||
AddNode(NS_STATIC_CAST(nsCParserNode*,result));
|
||||
#endif
|
||||
NS_IF_ADDREF(result);
|
||||
IF_HOLD(result);
|
||||
}
|
||||
#else
|
||||
result=new(mNodePool) nsCParserNode(aToken,aLineNumber,aTokenAllocator);
|
||||
NS_IF_ADDREF(result);
|
||||
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
|
||||
IF_HOLD(result);
|
||||
#endif
|
||||
return NS_STATIC_CAST(nsIParserNode*,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#define IF_HOLD(_ptr) if(_ptr) { _ptr->AddRef(); }
|
||||
#define IF_FREE(_ptr) if(_ptr) { _ptr->Release(); _ptr=0; } // recycles _ptr
|
||||
#define IF_FREE(_ptr, _allocator) if(_ptr) { _ptr->Release((_allocator)->GetArenaPool()); _ptr=0; } // recycles _ptr
|
||||
|
||||
class nsIParserNode;
|
||||
class nsCParserNode;
|
||||
@ -67,7 +67,7 @@ class nsEntryStack; //forware declare to make compilers happy.
|
||||
|
||||
struct nsTagEntry {
|
||||
eHTMLTags mTag; //for speedier access to tag id
|
||||
nsIParserNode* mNode;
|
||||
nsCParserNode* mNode;
|
||||
nsEntryStack* mParent;
|
||||
nsEntryStack* mStyles;
|
||||
};
|
||||
@ -78,12 +78,12 @@ public:
|
||||
~nsEntryStack();
|
||||
|
||||
void EnsureCapacityFor(PRInt32 aNewMax, PRInt32 aShiftOffset=0);
|
||||
void Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void PushFront(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void PushFront(const nsCParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
void Append(nsEntryStack *theStack);
|
||||
nsIParserNode* Pop(void);
|
||||
nsIParserNode* Remove(PRInt32 anIndex,eHTMLTags aTag);
|
||||
nsIParserNode* NodeAt(PRInt32 anIndex) const;
|
||||
nsCParserNode* Pop(void);
|
||||
nsCParserNode* Remove(PRInt32 anIndex,eHTMLTags aTag);
|
||||
nsCParserNode* NodeAt(PRInt32 anIndex) const;
|
||||
eHTMLTags First() const;
|
||||
eHTMLTags TagAt(PRInt32 anIndex) const;
|
||||
nsTagEntry* EntryAt(PRInt32 anIndex) const;
|
||||
@ -229,6 +229,8 @@ public:
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsAReadableString& aString);
|
||||
virtual CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag);
|
||||
|
||||
nsFixedSizeAllocator& GetArenaPool() { return mArenaPool; }
|
||||
|
||||
protected:
|
||||
nsFixedSizeAllocator mArenaPool;
|
||||
|
||||
@ -245,23 +247,30 @@ protected:
|
||||
that get created during the run of the system.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef HEAP_ALLOCATED_NODES
|
||||
class nsCParserNode;
|
||||
#endif
|
||||
|
||||
class nsNodeAllocator {
|
||||
public:
|
||||
|
||||
nsNodeAllocator();
|
||||
virtual ~nsNodeAllocator();
|
||||
virtual nsIParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
virtual nsCParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
|
||||
|
||||
nsFixedSizeAllocator& GetArenaPool() { return mNodePool; }
|
||||
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
void Recycle(nsIParserNode* aNode) { mSharedNodes.Push(NS_STATIC_CAST(void*,aNode)); }
|
||||
void Recycle(nsCParserNode* aNode) { mSharedNodes.Push(NS_STATIC_CAST(void*,aNode)); }
|
||||
protected:
|
||||
nsDeque mSharedNodes;
|
||||
#ifdef DEBUG_TRACK_NODES
|
||||
PRInt32 mCount;
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsFixedSizeAllocator mNodePool;
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
@ -273,10 +282,10 @@ public:
|
||||
nsDTDContext();
|
||||
~nsDTDContext();
|
||||
|
||||
void Push(const nsIParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
nsIParserNode* Pop(nsEntryStack*& aChildStack);
|
||||
nsIParserNode* Pop();
|
||||
nsIParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
|
||||
void Push(const nsCParserNode* aNode,nsEntryStack* aStyleStack=0);
|
||||
nsCParserNode* Pop(nsEntryStack*& aChildStack);
|
||||
nsCParserNode* Pop();
|
||||
nsCParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
|
||||
eHTMLTags First(void) const;
|
||||
eHTMLTags Last(void) const;
|
||||
nsTagEntry* LastEntry(void) const;
|
||||
@ -290,11 +299,11 @@ public:
|
||||
PRInt32 GetCount(void) {return mStack.mCount;}
|
||||
PRInt32 GetResidualStyleCount(void) {return mResidualStyleCount;}
|
||||
nsEntryStack* GetStylesAt(PRInt32 anIndex) const;
|
||||
void PushStyle(const nsIParserNode* aNode);
|
||||
void PushStyle(const nsCParserNode* aNode);
|
||||
void PushStyles(nsEntryStack *theStyles);
|
||||
nsIParserNode* PopStyle(void);
|
||||
nsIParserNode* PopStyle(eHTMLTags aTag);
|
||||
nsIParserNode* RemoveStyle(eHTMLTags aTag);
|
||||
nsCParserNode* PopStyle(void);
|
||||
nsCParserNode* PopStyle(eHTMLTags aTag);
|
||||
nsCParserNode* RemoveStyle(eHTMLTags aTag);
|
||||
|
||||
static void ReleaseGlobalObjects(void);
|
||||
|
||||
@ -342,10 +351,16 @@ public:
|
||||
Now define the token deallocator class...
|
||||
**************************************************************/
|
||||
class CTokenDeallocator: public nsDequeFunctor{
|
||||
protected:
|
||||
nsFixedSizeAllocator& mArenaPool;
|
||||
|
||||
public:
|
||||
CTokenDeallocator(nsFixedSizeAllocator& aArenaPool)
|
||||
: mArenaPool(aArenaPool) {}
|
||||
|
||||
virtual void* operator()(void* anObject) {
|
||||
CToken* aToken = (CToken*)anObject;
|
||||
delete aToken;
|
||||
CToken::Destroy(aToken, mArenaPool);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -234,7 +234,7 @@ NS_IMETHODIMP nsExpatDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
@ -133,7 +133,7 @@ NS_IMPL_RELEASE(nsHTMLTokenizer)
|
||||
*/
|
||||
nsHTMLTokenizer::~nsHTMLTokenizer(){
|
||||
if(mTokenDeque.GetSize()){
|
||||
CTokenDeallocator theDeallocator;
|
||||
CTokenDeallocator theDeallocator(mTokenAllocator->GetArenaPool());
|
||||
mTokenDeque.ForEach(theDeallocator);
|
||||
}
|
||||
}
|
||||
@ -149,7 +149,7 @@ void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,
|
||||
aDeque->Push(aToken);
|
||||
}
|
||||
else {
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, aTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -589,12 +589,12 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
|
||||
AddToken((CToken*&)theToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
else {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){
|
||||
aToken->SetEmpty(PR_TRUE);
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result)
|
||||
result=NS_OK;
|
||||
}
|
||||
@ -728,7 +728,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
AddToken(endToken,result,&mTokenDeque,theAllocator);
|
||||
}
|
||||
else {
|
||||
IF_FREE(text);
|
||||
IF_FREE(text, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -742,11 +742,11 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
while(mTokenDeque.GetSize()>theDequeSize) {
|
||||
CToken* theToken=(CToken*)mTokenDeque.Pop();
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
}
|
||||
} //if
|
||||
else IF_FREE(aToken);
|
||||
else IF_FREE(aToken, mTokenAllocator);
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
@ -900,7 +900,7 @@ nsresult nsHTMLTokenizer::ConsumeText(CToken*& aToken,nsScanner& aScanner){
|
||||
result=theToken->Consume(ch,aScanner,mParseMode);
|
||||
if(!NS_SUCCEEDED(result)) {
|
||||
if(0==theToken->GetTextLength()){
|
||||
IF_FREE(aToken);
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
aToken = nsnull;
|
||||
}
|
||||
else result=NS_OK;
|
||||
|
||||
@ -114,6 +114,8 @@ protected:
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CStartToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CStartToken(eHTMLTags aTag=eHTMLTag_unknown);
|
||||
CStartToken(const nsAReadableString& aString);
|
||||
@ -168,6 +170,8 @@ class CStartToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CEndToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CEndToken(eHTMLTags aTag);
|
||||
CEndToken(const nsAReadableString& aString);
|
||||
@ -195,6 +199,8 @@ class CEndToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CCommentToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CCommentToken();
|
||||
CCommentToken(const nsAReadableString& aString);
|
||||
@ -217,6 +223,8 @@ class CCommentToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CEntityToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CEntityToken();
|
||||
CEntityToken(const nsAReadableString& aString);
|
||||
@ -244,6 +252,8 @@ class CEntityToken : public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CWhitespaceToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CWhitespaceToken();
|
||||
CWhitespaceToken(const nsAReadableString& aString);
|
||||
@ -264,6 +274,8 @@ class CWhitespaceToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CTextToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CTextToken();
|
||||
CTextToken(const nsAReadableString& aString);
|
||||
@ -291,6 +303,8 @@ class CTextToken: public CHTMLToken {
|
||||
* @update vidur 11/12/98
|
||||
*/
|
||||
class CCDATASectionToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CCDATASectionToken();
|
||||
CCDATASectionToken(const nsAReadableString& aString);
|
||||
@ -311,6 +325,8 @@ public:
|
||||
*
|
||||
*/
|
||||
class CMarkupDeclToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CMarkupDeclToken();
|
||||
CMarkupDeclToken(const nsAReadableString& aString);
|
||||
@ -333,6 +349,8 @@ protected:
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CAttributeToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CAttributeToken();
|
||||
CAttributeToken(const nsAReadableString& aString);
|
||||
@ -367,6 +385,8 @@ class CAttributeToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CNewlineToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CNewlineToken();
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
@ -389,6 +409,8 @@ class CNewlineToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CScriptToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CScriptToken();
|
||||
CScriptToken(const nsAReadableString& aString);
|
||||
@ -410,6 +432,8 @@ class CScriptToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CStyleToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CStyleToken();
|
||||
CStyleToken(const nsAReadableString& aString);
|
||||
@ -430,6 +454,8 @@ class CStyleToken: public CHTMLToken {
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class CInstructionToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CInstructionToken();
|
||||
CInstructionToken(const nsAReadableString& aString);
|
||||
@ -443,6 +469,8 @@ class CInstructionToken: public CHTMLToken {
|
||||
};
|
||||
|
||||
class CErrorToken : public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CErrorToken(nsParserError* aError=0);
|
||||
~CErrorToken();
|
||||
@ -469,6 +497,8 @@ protected:
|
||||
*/
|
||||
|
||||
class CDoctypeDeclToken: public CHTMLToken {
|
||||
CTOKEN_IMPL_SIZEOF
|
||||
|
||||
public:
|
||||
CDoctypeDeclToken(eHTMLTags aTag=eHTMLTag_unknown);
|
||||
CDoctypeDeclToken(const nsAReadableString& aString,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
|
||||
@ -65,7 +65,7 @@ class CToken;
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
*/
|
||||
class nsIParserNode : public nsISupports {
|
||||
class nsIParserNode { // XXX Should be nsAParserNode
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ const nsString& GetEmptyString() {
|
||||
*/
|
||||
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator):
|
||||
nsIParserNode() {
|
||||
NS_INIT_REFCNT();
|
||||
mRefCnt = 0;
|
||||
MOZ_COUNT_CTOR(nsCParserNode);
|
||||
|
||||
static int theNodeCount=0;
|
||||
@ -88,9 +88,6 @@ nsCParserNode::~nsCParserNode() {
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsCParserNode)
|
||||
NS_IMPL_RELEASE(nsCParserNode)
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
@ -105,7 +102,7 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
|
||||
if(mAttributes && (mAttributes->GetSize())) {
|
||||
CToken* theAttrToken=0;
|
||||
while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
|
||||
IF_FREE(theAttrToken);
|
||||
IF_FREE(theAttrToken, aTokenAllocator);
|
||||
}
|
||||
}
|
||||
mToken=aToken;
|
||||
@ -121,40 +118,6 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called as part of our COM-like interfaces.
|
||||
* Its purpose is to create an interface to parser object
|
||||
* of some type.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param nsIID id of object to discover
|
||||
* @param aInstancePtr ptr to newly discovered interface
|
||||
* @return NS_xxx result code
|
||||
*/
|
||||
nsresult nsCParserNode::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
||||
*aInstancePtr = (nsIParserNode*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kIParserNodeIID)) { //do IParser base class...
|
||||
*aInstancePtr = (nsIParserNode*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kClassIID)) { //do this class...
|
||||
*aInstancePtr = (nsCParserNode*)(this);
|
||||
}
|
||||
else {
|
||||
*aInstancePtr=0;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Causes the given attribute to be added to internal
|
||||
* mAttributes list, and mAttributeCount to be incremented.
|
||||
@ -380,7 +343,7 @@ nsresult nsCParserNode::ReleaseAll() {
|
||||
if(mAttributes) {
|
||||
CToken* theAttrToken=0;
|
||||
while((theAttrToken=NS_STATIC_CAST(CToken*,mAttributes->Pop()))) {
|
||||
IF_FREE(theAttrToken);
|
||||
IF_FREE(theAttrToken, mTokenAllocator);
|
||||
}
|
||||
delete mAttributes;
|
||||
mAttributes=0;
|
||||
@ -389,7 +352,7 @@ nsresult nsCParserNode::ReleaseAll() {
|
||||
delete mSkippedContent;
|
||||
mSkippedContent=0;
|
||||
}
|
||||
IF_FREE(mToken);
|
||||
IF_FREE(mToken, mTokenAllocator);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -50,40 +50,59 @@
|
||||
class nsTokenAllocator;
|
||||
|
||||
class nsCParserNode : public nsIParserNode {
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mRefCnt;
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
void AddRef()
|
||||
{
|
||||
++mRefCnt;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
void* operator new(size_t aSize) {
|
||||
return ::operator new(aSize);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
*
|
||||
* @update harishd 01/01/01
|
||||
* @param aSize -
|
||||
* @param aArena - Allocate memory from this pool.
|
||||
*/
|
||||
static void * operator new (size_t aSize, nsFixedSizeAllocator& anArena)
|
||||
void Release(nsFixedSizeAllocator& aPool)
|
||||
{
|
||||
return anArena.Alloc(aSize);
|
||||
if (--mRefCnt == 0)
|
||||
Destroy(this, aPool);
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update harishd 01/01/01
|
||||
* @param aPtr - The memory that should be recycled/freed.
|
||||
* @param aSize - The size of memory that needs to be freed.
|
||||
*/
|
||||
static void operator delete (void* aPtr,size_t aSize)
|
||||
{
|
||||
// NodeAllocator would take care of heap allocated nodes..
|
||||
|
||||
#ifndef HEAP_ALLOCATED_NODES
|
||||
nsFixedSizeAllocator::Free(aPtr,aSize);
|
||||
private:
|
||||
|
||||
/**
|
||||
* Hide operator new; clients should use Create() instead.
|
||||
*/
|
||||
static void* operator new(size_t) { return 0; }
|
||||
|
||||
/**
|
||||
* Hide operator delete; clients should use Destroy() instead.
|
||||
*/
|
||||
static void operator delete(void*,size_t) {}
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
static nsCParserNode* Create(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator)
|
||||
{
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
return new
|
||||
#else
|
||||
nsFixedSizeAllocator& pool = aNodeAllocator->GetArenaPool();
|
||||
void* place = pool.Alloc(sizeof(nsCParserNode));
|
||||
return ::new (place)
|
||||
#endif
|
||||
nsCParserNode(aToken, aLineNumber, aTokenAllocator, aNodeAllocator);
|
||||
}
|
||||
|
||||
static void Destroy(nsCParserNode* aNode, nsFixedSizeAllocator& aPool)
|
||||
{
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
delete aNode;
|
||||
#else
|
||||
aNode->~nsCParserNode();
|
||||
aPool.Free(aNode, sizeof(*aNode));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -248,7 +267,6 @@ class nsCParserNode : public nsIParserNode {
|
||||
#ifdef HEAP_ALLOCATED_NODES
|
||||
nsNodeAllocator* mNodeAllocator; // weak
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -33,6 +33,20 @@
|
||||
* of that particular token type gets detected in the
|
||||
* input stream.
|
||||
*
|
||||
* CToken objects that are allocated from the heap _must_ be allocated
|
||||
* using the nsTokenAllocator: the nsTokenAllocator object uses an
|
||||
* arena to manage the tokens.
|
||||
*
|
||||
* The nsTokenAllocator object's arena implementation requires
|
||||
* object size at destruction time to properly recycle the object;
|
||||
* therefore, CToken::operator delete() is not public. Instead,
|
||||
* heap-allocated tokens should be destroyed using the static
|
||||
* Destroy() method, which accepts a token and the arena from which
|
||||
* the token was allocated.
|
||||
*
|
||||
* Leaf classes (that are actually instantiated from the heap) must
|
||||
* implement the SizeOf() method, which Destroy() uses to determine
|
||||
* the size of the token in order to properly recycle it.
|
||||
*/
|
||||
|
||||
|
||||
@ -45,9 +59,8 @@
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
|
||||
|
||||
class nsScanner;
|
||||
|
||||
class nsTokenAllocator;
|
||||
|
||||
enum eContainerInfo {
|
||||
eWellFormed,
|
||||
@ -55,6 +68,14 @@ enum eContainerInfo {
|
||||
eFormUnknown
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement the SizeOf() method; leaf classes derived from CToken
|
||||
* must declare this.
|
||||
*/
|
||||
#define CTOKEN_IMPL_SIZEOF \
|
||||
protected: \
|
||||
virtual size_t SizeOf() const { return sizeof(*this); } \
|
||||
public:
|
||||
|
||||
/**
|
||||
* Token objects represent sequences of characters as they
|
||||
@ -70,27 +91,43 @@ class CToken {
|
||||
|
||||
enum eTokenOrigin {eSource,eResidualStyle};
|
||||
|
||||
protected:
|
||||
|
||||
// nsTokenAllocator should be the only class that tries to
|
||||
// allocate tokens from the heap.
|
||||
friend class nsTokenAllocator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aSize -
|
||||
* @param aArena - Allocate memory from this pool.
|
||||
*/
|
||||
static void * operator new (size_t aSize, nsFixedSizeAllocator& anArena)
|
||||
static void * operator new (size_t aSize,nsFixedSizeAllocator& anArena)
|
||||
{
|
||||
return anArena.Alloc(aSize);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update harishd 08/01/00
|
||||
* @param aPtr - The memory that should be recycled/freed.
|
||||
* @param aSize - The size of memory that needs to be freed.
|
||||
* Hide operator delete; clients should use Destroy() instead.
|
||||
*/
|
||||
static void operator delete (void* aPtr,size_t aSize)
|
||||
static void operator delete (void*,size_t) {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* destructor
|
||||
* @update gess5/11/98
|
||||
*/
|
||||
virtual ~CToken();
|
||||
|
||||
/**
|
||||
* Destroy a token.
|
||||
*/
|
||||
static void Destroy(CToken* aToken,nsFixedSizeAllocator& aArenaPool)
|
||||
{
|
||||
nsFixedSizeAllocator::Free(aPtr,aSize);
|
||||
size_t sz = aToken->SizeOf();
|
||||
aToken->~CToken();
|
||||
aArenaPool.Free(aToken, sz);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,22 +140,17 @@ class CToken {
|
||||
* Free yourself if no one is holding you.
|
||||
* @update harishd 08/02/00
|
||||
*/
|
||||
void Release() {
|
||||
void Release(nsFixedSizeAllocator& aArenaPool) {
|
||||
if(--mUseCount==0)
|
||||
delete this;
|
||||
Destroy(this, aArenaPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* @update gess7/21/98
|
||||
*/
|
||||
CToken(PRInt32 aTag=0);
|
||||
|
||||
/**
|
||||
* destructor
|
||||
* @update gess5/11/98
|
||||
*/
|
||||
virtual ~CToken();
|
||||
|
||||
/**
|
||||
* Retrieve string value of the token
|
||||
* @update gess5/11/98
|
||||
@ -229,6 +261,10 @@ class CToken {
|
||||
PRInt32 mNewlineCount;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Returns the size of the token object.
|
||||
*/
|
||||
virtual size_t SizeOf() const = 0;
|
||||
|
||||
PRInt32 mTypeID;
|
||||
PRInt16 mAttrCount;
|
||||
|
||||
@ -534,7 +534,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
|
||||
@ -258,7 +258,7 @@ NS_IMETHODIMP CWellFormedDTD::BuildModel(nsIParser* aParser,nsITokenizer* aToken
|
||||
if(theToken) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else {
|
||||
// if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
@ -362,7 +362,7 @@ nsresult CWellFormedDTD::Terminate(nsIParser* aParser)
|
||||
if(theType==eToken_error) {
|
||||
result=HandleToken(theToken,aParser);
|
||||
}
|
||||
IF_FREE(theToken);
|
||||
IF_FREE(theToken, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else break;
|
||||
}//while
|
||||
@ -717,7 +717,7 @@ nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
IF_FREE(token);
|
||||
IF_FREE(token, mTokenizer->GetTokenAllocator());
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIEnumerator.h"
|
||||
@ -76,6 +77,10 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
// CompositeDataSourceImpl
|
||||
//
|
||||
|
||||
class CompositeEnumeratorImpl;
|
||||
class CompositeArcsInOutEnumeratorImpl;
|
||||
class CompositeAssertionEnumeratorImpl;
|
||||
|
||||
class CompositeDataSourceImpl : public nsIRDFCompositeDataSource,
|
||||
public nsIRDFObserver
|
||||
{
|
||||
@ -112,6 +117,10 @@ protected:
|
||||
nsFixedSizeAllocator mAllocator;
|
||||
|
||||
virtual ~CompositeDataSourceImpl() {}
|
||||
|
||||
friend class CompositeEnumeratorImpl;
|
||||
friend class CompositeArcsInOutEnumeratorImpl;
|
||||
friend class CompositeAssertionEnumeratorImpl;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -121,25 +130,7 @@ protected:
|
||||
|
||||
class CompositeEnumeratorImpl : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
#if defined(HAVE_CPP_EXCEPTIONS) && defined(HAVE_CPP_PLACEMENT_DELETE)
|
||||
static void operator delete(void* aPtr, size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
#endif
|
||||
|
||||
CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs);
|
||||
|
||||
virtual ~CompositeEnumeratorImpl();
|
||||
|
||||
// nsISupports interface
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator interface
|
||||
@ -152,7 +143,15 @@ public:
|
||||
virtual nsresult
|
||||
HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult) = 0;
|
||||
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs);
|
||||
|
||||
virtual ~CompositeEnumeratorImpl();
|
||||
|
||||
CompositeDataSourceImpl* mCompositeDataSource;
|
||||
|
||||
nsISimpleEnumerator* mCurrent;
|
||||
@ -165,8 +164,8 @@ protected:
|
||||
|
||||
|
||||
CompositeEnumeratorImpl::CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs)
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs)
|
||||
: mCompositeDataSource(aCompositeDataSource),
|
||||
mCurrent(nsnull),
|
||||
mResult(nsnull),
|
||||
@ -195,8 +194,9 @@ CompositeEnumeratorImpl::~CompositeEnumeratorImpl(void)
|
||||
NS_RELEASE(mCompositeDataSource);
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(CompositeEnumeratorImpl, nsISimpleEnumerator);
|
||||
NS_IMPL_ADDREF(CompositeEnumeratorImpl)
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(CompositeEnumeratorImpl, Destroy())
|
||||
NS_IMPL_QUERY_INTERFACE1(CompositeEnumeratorImpl, nsISimpleEnumerator);
|
||||
|
||||
NS_IMETHODIMP
|
||||
CompositeEnumeratorImpl::HasMoreElements(PRBool* aResult)
|
||||
@ -356,11 +356,20 @@ class CompositeArcsInOutEnumeratorImpl : public CompositeEnumeratorImpl
|
||||
public:
|
||||
enum Type { eArcsIn, eArcsOut };
|
||||
|
||||
CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
|
||||
nsIRDFNode* aNode,
|
||||
Type aType,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs);
|
||||
static CompositeArcsInOutEnumeratorImpl*
|
||||
Create(nsFixedSizeAllocator& aAllocator,
|
||||
CompositeDataSourceImpl* aCompositeDataSource,
|
||||
nsIRDFNode* aNode,
|
||||
Type aType,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs) {
|
||||
void* place = aAllocator.Alloc(sizeof(CompositeArcsInOutEnumeratorImpl));
|
||||
return place
|
||||
? ::new (place) CompositeArcsInOutEnumeratorImpl(aCompositeDataSource,
|
||||
aNode, aType,
|
||||
aAllowNegativeAssertions,
|
||||
aCoalesceDuplicateArcs)
|
||||
: nsnull; }
|
||||
|
||||
virtual ~CompositeArcsInOutEnumeratorImpl();
|
||||
|
||||
@ -370,11 +379,25 @@ public:
|
||||
virtual nsresult
|
||||
HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult);
|
||||
|
||||
virtual void Destroy();
|
||||
|
||||
protected:
|
||||
CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
|
||||
nsIRDFNode* aNode,
|
||||
Type aType,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs);
|
||||
|
||||
private:
|
||||
nsIRDFNode* mNode;
|
||||
Type mType;
|
||||
PRBool mAllowNegativeAssertions;
|
||||
PRBool mCoalesceDuplicateArcs;
|
||||
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
};
|
||||
|
||||
|
||||
@ -423,6 +446,19 @@ CompositeArcsInOutEnumeratorImpl::HasNegation(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CompositeArcsInOutEnumeratorImpl::Destroy()
|
||||
{
|
||||
// Keep the datasource alive for the duration of the stack
|
||||
// frame so its allocator stays valid.
|
||||
nsCOMPtr<nsIRDFCompositeDataSource> kungFuDeathGrip =
|
||||
dont_QueryInterface(mCompositeDataSource);
|
||||
|
||||
nsFixedSizeAllocator& pool = mCompositeDataSource->mAllocator;
|
||||
this->~CompositeArcsInOutEnumeratorImpl();
|
||||
pool.Free(this, sizeof(*this));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
@ -432,6 +468,33 @@ CompositeArcsInOutEnumeratorImpl::HasNegation(
|
||||
class CompositeAssertionEnumeratorImpl : public CompositeEnumeratorImpl
|
||||
{
|
||||
public:
|
||||
static CompositeAssertionEnumeratorImpl*
|
||||
Create(nsFixedSizeAllocator& aAllocator,
|
||||
CompositeDataSourceImpl* aCompositeDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget,
|
||||
PRBool aTruthValue,
|
||||
PRBool aAllowNegativeAssertions,
|
||||
PRBool aCoalesceDuplicateArcs) {
|
||||
void* place = aAllocator.Alloc(sizeof(CompositeAssertionEnumeratorImpl));
|
||||
return place
|
||||
? ::new (place) CompositeAssertionEnumeratorImpl(aCompositeDataSource,
|
||||
aSource, aProperty, aTarget,
|
||||
aTruthValue,
|
||||
aAllowNegativeAssertions,
|
||||
aCoalesceDuplicateArcs)
|
||||
: nsnull; }
|
||||
|
||||
virtual nsresult
|
||||
GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
|
||||
|
||||
virtual nsresult
|
||||
HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult);
|
||||
|
||||
virtual void Destroy();
|
||||
|
||||
protected:
|
||||
CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
@ -442,12 +505,6 @@ public:
|
||||
|
||||
virtual ~CompositeAssertionEnumeratorImpl();
|
||||
|
||||
virtual nsresult
|
||||
GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
|
||||
|
||||
virtual nsresult
|
||||
HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, PRBool* aResult);
|
||||
|
||||
private:
|
||||
nsIRDFResource* mSource;
|
||||
nsIRDFResource* mProperty;
|
||||
@ -455,6 +512,11 @@ private:
|
||||
PRBool mTruthValue;
|
||||
PRBool mAllowNegativeAssertions;
|
||||
PRBool mCoalesceDuplicateArcs;
|
||||
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
};
|
||||
|
||||
|
||||
@ -515,6 +577,19 @@ CompositeAssertionEnumeratorImpl::HasNegation(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositeAssertionEnumeratorImpl::Destroy()
|
||||
{
|
||||
// Keep the datasource alive for the duration of the stack
|
||||
// frame so its allocator stays valid.
|
||||
nsCOMPtr<nsIRDFCompositeDataSource> kungFuDeathGrip =
|
||||
dont_QueryInterface(mCompositeDataSource);
|
||||
|
||||
nsFixedSizeAllocator& pool = mCompositeDataSource->mAllocator;
|
||||
this->~CompositeAssertionEnumeratorImpl();
|
||||
pool.Free(this, sizeof(*this));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
@ -693,8 +768,12 @@ CompositeDataSourceImpl::GetSources(nsIRDFResource* aProperty,
|
||||
if ((mAllowNegativeAssertions == PR_FALSE) && (aTruthValue == PR_FALSE))
|
||||
return(NS_RDF_NO_VALUE);
|
||||
|
||||
*aResult = new (mAllocator) CompositeAssertionEnumeratorImpl(this, nsnull, aProperty,
|
||||
aTarget, aTruthValue, mAllowNegativeAssertions, mCoalesceDuplicateArcs);
|
||||
*aResult = CompositeAssertionEnumeratorImpl::Create(mAllocator,
|
||||
this, nsnull, aProperty,
|
||||
aTarget, aTruthValue,
|
||||
mAllowNegativeAssertions,
|
||||
mCoalesceDuplicateArcs);
|
||||
|
||||
if (! *aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -797,8 +876,13 @@ CompositeDataSourceImpl::GetTargets(nsIRDFResource* aSource,
|
||||
if ((mAllowNegativeAssertions == PR_FALSE) && (aTruthValue == PR_FALSE))
|
||||
return(NS_RDF_NO_VALUE);
|
||||
|
||||
*aResult = new (mAllocator) CompositeAssertionEnumeratorImpl(this, aSource, aProperty,
|
||||
nsnull, aTruthValue, mAllowNegativeAssertions, mCoalesceDuplicateArcs);
|
||||
*aResult =
|
||||
CompositeAssertionEnumeratorImpl::Create(mAllocator, this,
|
||||
aSource, aProperty, nsnull,
|
||||
aTruthValue,
|
||||
mAllowNegativeAssertions,
|
||||
mCoalesceDuplicateArcs);
|
||||
|
||||
if (! *aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -1133,9 +1217,10 @@ CompositeDataSourceImpl::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator**
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsISimpleEnumerator* result =
|
||||
new (mAllocator) CompositeArcsInOutEnumeratorImpl(this, aTarget,
|
||||
CompositeArcsInOutEnumeratorImpl::eArcsIn,
|
||||
mAllowNegativeAssertions, mCoalesceDuplicateArcs);
|
||||
CompositeArcsInOutEnumeratorImpl::Create(mAllocator, this, aTarget,
|
||||
CompositeArcsInOutEnumeratorImpl::eArcsIn,
|
||||
mAllowNegativeAssertions,
|
||||
mCoalesceDuplicateArcs);
|
||||
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -1158,9 +1243,10 @@ CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource* aSource,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsISimpleEnumerator* result =
|
||||
new (mAllocator) CompositeArcsInOutEnumeratorImpl(this, aSource,
|
||||
CompositeArcsInOutEnumeratorImpl::eArcsOut,
|
||||
mAllowNegativeAssertions, mCoalesceDuplicateArcs);
|
||||
CompositeArcsInOutEnumeratorImpl::Create(mAllocator, this, aSource,
|
||||
CompositeArcsInOutEnumeratorImpl::eArcsOut,
|
||||
mAllowNegativeAssertions,
|
||||
mCoalesceDuplicateArcs);
|
||||
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "rdfutil.h"
|
||||
#include "plhash.h"
|
||||
#include "pldhash.h"
|
||||
#include "plstr.h"
|
||||
#include "prlog.h"
|
||||
#include "rdf.h"
|
||||
@ -98,32 +98,35 @@ static PRLogModuleInfo* gLog = nsnull;
|
||||
class Assertion
|
||||
{
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
static Assertion*
|
||||
Create(nsFixedSizeAllocator& aAllocator,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget,
|
||||
PRBool aTruthValue) {
|
||||
void* place = aAllocator.Alloc(sizeof(Assertion));
|
||||
return place
|
||||
? ::new (place) Assertion(aSource, aProperty, aTarget, aTruthValue)
|
||||
: nsnull; }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
#if defined(HAVE_CPP_EXCEPTIONS) && defined(HAVE_CPP_PLACEMENT_DELETE)
|
||||
static void operator delete(void* aPtr, size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
#endif
|
||||
static void
|
||||
Destroy(nsFixedSizeAllocator& aAllocator,
|
||||
Assertion* aAssertion) {
|
||||
aAssertion->~Assertion();
|
||||
aAllocator.Free(aAssertion, sizeof(*aAssertion)); }
|
||||
|
||||
Assertion(nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget,
|
||||
PRBool aTruthValue);
|
||||
|
||||
void AddRef()
|
||||
{
|
||||
++mRefCnt;
|
||||
}
|
||||
~Assertion();
|
||||
|
||||
void Release()
|
||||
{
|
||||
void AddRef() { ++mRefCnt; }
|
||||
|
||||
void Release(nsFixedSizeAllocator& aAllocator) {
|
||||
if (--mRefCnt == 0)
|
||||
delete this;
|
||||
}
|
||||
Destroy(aAllocator, this); }
|
||||
|
||||
// public for now, because I'm too lazy to go thru and clean this up.
|
||||
nsIRDFResource* mSource; // OWNER
|
||||
@ -140,8 +143,11 @@ public:
|
||||
PRBool IsMarked() { return mMarked; }
|
||||
void Unmark() { mMarked = PR_FALSE; }
|
||||
|
||||
protected:
|
||||
~Assertion();
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
};
|
||||
|
||||
|
||||
@ -191,6 +197,8 @@ rdf_HashPointer(const void* key)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// InMemoryDataSource
|
||||
class InMemoryArcsEnumeratorImpl;
|
||||
class InMemoryAssertionEnumeratorImpl;
|
||||
class InMemoryResourceEnumeratorImpl;
|
||||
|
||||
class InMemoryDataSource : public nsIRDFDataSource,
|
||||
@ -204,31 +212,23 @@ protected:
|
||||
// nsIRDFResource object per unique URI). The value of an entry is
|
||||
// an Assertion struct, which is a linked list of (subject
|
||||
// predicate object) triples.
|
||||
PLHashTable* mForwardArcs;
|
||||
PLHashTable* mReverseArcs;
|
||||
|
||||
static PLHashAllocOps gAllocOps;
|
||||
|
||||
static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize) {
|
||||
return new char[aSize]; }
|
||||
|
||||
static void PR_CALLBACK FreeTable(void* aPool, void* aItem) {
|
||||
delete[] NS_STATIC_CAST(char*, aItem); }
|
||||
|
||||
static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) {
|
||||
void* result = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)->Alloc(sizeof(PLHashEntry));
|
||||
return NS_REINTERPRET_CAST(PLHashEntry*, result); }
|
||||
|
||||
static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) {
|
||||
if (aFlag == HT_FREE_ENTRY)
|
||||
nsFixedSizeAllocator::Free(aHashEntry, sizeof(PLHashEntry)); }
|
||||
PLDHashTable mForwardArcs;
|
||||
PLDHashTable mReverseArcs;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> mObservers;
|
||||
|
||||
static const PRInt32 kInitialTableSize;
|
||||
|
||||
static PRIntn PR_CALLBACK DeleteForwardArcsEntry(PLHashEntry* he, PRIntn i, void* arg);
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg);
|
||||
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
ResourceEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg);
|
||||
|
||||
friend class InMemoryArcsEnumeratorImpl;
|
||||
friend class InMemoryAssertionEnumeratorImpl;
|
||||
friend class InMemoryResourceEnumeratorImpl; // b/c it needs to enumerate mForwardArcs
|
||||
|
||||
// Thread-safe writer implementation methods.
|
||||
@ -251,7 +251,6 @@ protected:
|
||||
NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult);
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
// nsIRDFDataSource methods
|
||||
@ -261,43 +260,51 @@ public:
|
||||
NS_DECL_NSIRDFPURGEABLEDATASOURCE
|
||||
|
||||
protected:
|
||||
static PRIntn PR_CALLBACK SweepForwardArcsEntries(PLHashEntry* he, PRIntn i, void* arg);
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
SweepForwardArcsEntries(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg);
|
||||
|
||||
struct Entry {
|
||||
PLDHashEntryHdr mHdr;
|
||||
nsIRDFNode* mNode;
|
||||
Assertion* mAssertions;
|
||||
};
|
||||
|
||||
public:
|
||||
// Implementation methods
|
||||
Assertion* GetForwardArcs(nsIRDFResource* u)
|
||||
{
|
||||
// Use PL_HashTableRawLookup() so we can inline the hash
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mForwardArcs, rdf_HashPointer(u), u);
|
||||
return NS_REINTERPRET_CAST(Assertion*, *hep ? ((*hep)->value) : 0);
|
||||
}
|
||||
Assertion*
|
||||
GetForwardArcs(nsIRDFResource* u) {
|
||||
PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mForwardArcs, u, PL_DHASH_LOOKUP);
|
||||
return PL_DHASH_ENTRY_IS_BUSY(hdr)
|
||||
? NS_REINTERPRET_CAST(Entry*, hdr)->mAssertions
|
||||
: nsnull; }
|
||||
|
||||
Assertion* GetReverseArcs(nsIRDFNode* v)
|
||||
{
|
||||
// Use PL_HashTableRawLookup() so we can inline the hash
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(mReverseArcs, rdf_HashPointer(v), v);
|
||||
return NS_REINTERPRET_CAST(Assertion*, *hep ? ((*hep)->value) : 0);
|
||||
}
|
||||
Assertion*
|
||||
GetReverseArcs(nsIRDFNode* v) {
|
||||
PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mReverseArcs, v, PL_DHASH_LOOKUP);
|
||||
return PL_DHASH_ENTRY_IS_BUSY(hdr)
|
||||
? NS_REINTERPRET_CAST(Entry*, hdr)->mAssertions
|
||||
: nsnull; }
|
||||
|
||||
void SetForwardArcs(nsIRDFResource* u, Assertion* as)
|
||||
{
|
||||
if (as) {
|
||||
PL_HashTableAdd(mForwardArcs, u, as);
|
||||
}
|
||||
else {
|
||||
PL_HashTableRemove(mForwardArcs, u);
|
||||
}
|
||||
}
|
||||
void
|
||||
SetForwardArcs(nsIRDFResource* u, Assertion* as) {
|
||||
PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mForwardArcs, u,
|
||||
as ? PL_DHASH_ADD : PL_DHASH_REMOVE);
|
||||
if (as && hdr) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, hdr);
|
||||
entry->mNode = u;
|
||||
entry->mAssertions = as;
|
||||
} }
|
||||
|
||||
void SetReverseArcs(nsIRDFNode* v, Assertion* as)
|
||||
{
|
||||
if (as) {
|
||||
PL_HashTableAdd(mReverseArcs, v, as);
|
||||
}
|
||||
else {
|
||||
PL_HashTableRemove(mReverseArcs, v);
|
||||
}
|
||||
}
|
||||
void
|
||||
SetReverseArcs(nsIRDFNode* v, Assertion* as) {
|
||||
PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mReverseArcs, v,
|
||||
as ? PL_DHASH_ADD : PL_DHASH_REMOVE);
|
||||
if (as && hdr) {
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, hdr);
|
||||
entry->mNode = v;
|
||||
entry->mAssertions = as;
|
||||
} }
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
void
|
||||
@ -314,13 +321,10 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
PLHashAllocOps InMemoryDataSource::gAllocOps = {
|
||||
AllocTable, FreeTable, AllocEntry, FreeEntry };
|
||||
|
||||
const PRInt32 InMemoryDataSource::kInitialTableSize = 32;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// InMemoryAssertionEnumeratorImpl
|
||||
//
|
||||
|
||||
/**
|
||||
* InMemoryAssertionEnumeratorImpl
|
||||
@ -337,17 +341,10 @@ private:
|
||||
PRBool mTruthValue;
|
||||
Assertion* mNextAssertion;
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
#if defined(HAVE_CPP_EXCEPTIONS) && defined(HAVE_CPP_PLACEMENT_DELETE)
|
||||
static void operator delete(void* aPtr, size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
#endif
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
InMemoryAssertionEnumeratorImpl(InMemoryDataSource* aDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
@ -357,6 +354,33 @@ public:
|
||||
|
||||
virtual ~InMemoryAssertionEnumeratorImpl();
|
||||
|
||||
public:
|
||||
static InMemoryAssertionEnumeratorImpl*
|
||||
Create(InMemoryDataSource* aDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget,
|
||||
PRBool aTruthValue) {
|
||||
void* place = aDataSource->mAllocator.Alloc(sizeof(InMemoryAssertionEnumeratorImpl));
|
||||
return place
|
||||
? ::new (place) InMemoryAssertionEnumeratorImpl(aDataSource,
|
||||
aSource, aProperty, aTarget,
|
||||
aTruthValue)
|
||||
: nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(InMemoryAssertionEnumeratorImpl* aEnumerator) {
|
||||
// Keep the datasource alive for the duration of the stack
|
||||
// frame so its allocator stays valid.
|
||||
nsCOMPtr<nsIRDFDataSource> kungFuDeathGrip =
|
||||
dont_QueryInterface(aEnumerator->mDataSource);
|
||||
|
||||
// Grab the pool from the datasource; since we keep the
|
||||
// datasource alive, this has to be safe.
|
||||
nsFixedSizeAllocator& pool = aEnumerator->mDataSource->mAllocator;
|
||||
aEnumerator->~InMemoryAssertionEnumeratorImpl();
|
||||
pool.Free(aEnumerator, sizeof(*aEnumerator)); }
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
@ -409,7 +433,7 @@ InMemoryAssertionEnumeratorImpl::~InMemoryAssertionEnumeratorImpl()
|
||||
#endif
|
||||
|
||||
if (mNextAssertion)
|
||||
mNextAssertion->Release();
|
||||
mNextAssertion->Release(mDataSource->mAllocator);
|
||||
|
||||
NS_IF_RELEASE(mDataSource);
|
||||
NS_IF_RELEASE(mSource);
|
||||
@ -418,7 +442,9 @@ InMemoryAssertionEnumeratorImpl::~InMemoryAssertionEnumeratorImpl()
|
||||
NS_IF_RELEASE(mValue);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(InMemoryAssertionEnumeratorImpl, nsISimpleEnumerator)
|
||||
NS_IMPL_ADDREF(InMemoryAssertionEnumeratorImpl)
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(InMemoryAssertionEnumeratorImpl, Destroy(this))
|
||||
NS_IMPL_QUERY_INTERFACE1(InMemoryAssertionEnumeratorImpl, nsISimpleEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryAssertionEnumeratorImpl::HasMoreElements(PRBool* aResult)
|
||||
@ -455,7 +481,7 @@ InMemoryAssertionEnumeratorImpl::HasMoreElements(PRBool* aResult)
|
||||
mNextAssertion->AddRef();
|
||||
|
||||
// ...and release the reference from the enumerator to the old one.
|
||||
as->Release();
|
||||
as->Release(mDataSource->mAllocator);
|
||||
|
||||
if (foundIt) {
|
||||
*aResult = PR_TRUE;
|
||||
@ -501,6 +527,11 @@ InMemoryAssertionEnumeratorImpl::GetNext(nsISupports** aResult)
|
||||
class InMemoryArcsEnumeratorImpl : public nsISimpleEnumerator
|
||||
{
|
||||
private:
|
||||
// Hide so that only Create() and Destroy() can be used to
|
||||
// allocate and deallocate from the heap
|
||||
static void* operator new(size_t) { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
||||
InMemoryDataSource* mDataSource;
|
||||
nsIRDFResource* mSource;
|
||||
nsIRDFNode* mTarget;
|
||||
@ -508,29 +539,40 @@ private:
|
||||
nsIRDFResource* mCurrent;
|
||||
Assertion* mAssertion;
|
||||
|
||||
public:
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
return aAllocator.Alloc(aSize); }
|
||||
|
||||
static void operator delete(void* aPtr, size_t aSize) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
|
||||
#if defined(HAVE_CPP_EXCEPTIONS) && defined(HAVE_CPP_PLACEMENT_DELETE)
|
||||
static void operator delete(void* aPtr, size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
nsFixedSizeAllocator::Free(aPtr, aSize); }
|
||||
#endif
|
||||
|
||||
InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFNode* aTarget);
|
||||
|
||||
virtual ~InMemoryArcsEnumeratorImpl();
|
||||
|
||||
public:
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator interface
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
static InMemoryArcsEnumeratorImpl*
|
||||
Create(InMemoryDataSource* aDataSource,
|
||||
nsIRDFResource* aSource,
|
||||
nsIRDFNode* aTarget) {
|
||||
void* place = aDataSource->mAllocator.Alloc(sizeof(InMemoryArcsEnumeratorImpl));
|
||||
return place
|
||||
? ::new (place) InMemoryArcsEnumeratorImpl(aDataSource, aSource, aTarget)
|
||||
: nsnull; }
|
||||
|
||||
static void
|
||||
Destroy(InMemoryArcsEnumeratorImpl* aEnumerator) {
|
||||
// Keep the datasource alive for the duration of the stack
|
||||
// frame so its allocator stays valid.
|
||||
nsCOMPtr<nsIRDFDataSource> kungFuDeathGrip =
|
||||
dont_QueryInterface(aEnumerator->mDataSource);
|
||||
|
||||
// Grab the pool from the datasource; since we keep the
|
||||
// datasource alive, this has to be safe.
|
||||
nsFixedSizeAllocator& pool = aEnumerator->mDataSource->mAllocator;
|
||||
aEnumerator->~InMemoryArcsEnumeratorImpl();
|
||||
pool.Free(aEnumerator, sizeof(*aEnumerator)); }
|
||||
};
|
||||
|
||||
|
||||
@ -574,7 +616,9 @@ InMemoryArcsEnumeratorImpl::~InMemoryArcsEnumeratorImpl()
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(InMemoryArcsEnumeratorImpl, nsISimpleEnumerator)
|
||||
NS_IMPL_ADDREF(InMemoryArcsEnumeratorImpl)
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(InMemoryArcsEnumeratorImpl, Destroy(this))
|
||||
NS_IMPL_QUERY_INTERFACE1(InMemoryArcsEnumeratorImpl, nsISimpleEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryArcsEnumeratorImpl::HasMoreElements(PRBool* aResult)
|
||||
@ -678,8 +722,6 @@ NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResu
|
||||
|
||||
|
||||
InMemoryDataSource::InMemoryDataSource(nsISupports* aOuter)
|
||||
: mForwardArcs(nsnull),
|
||||
mReverseArcs(nsnull)
|
||||
{
|
||||
NS_INIT_AGGREGATED(aOuter);
|
||||
|
||||
@ -705,25 +747,17 @@ InMemoryDataSource::InMemoryDataSource(nsISupports* aOuter)
|
||||
nsresult
|
||||
InMemoryDataSource::Init()
|
||||
{
|
||||
mForwardArcs = PL_NewHashTable(kInitialTableSize,
|
||||
rdf_HashPointer,
|
||||
PL_CompareValues,
|
||||
PL_CompareValues,
|
||||
&gAllocOps,
|
||||
&mAllocator);
|
||||
PL_DHashTableInit(&mForwardArcs,
|
||||
PL_DHashGetStubOps(),
|
||||
nsnull,
|
||||
sizeof(Entry),
|
||||
PL_DHASH_MIN_SIZE);
|
||||
|
||||
if (! mForwardArcs)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mReverseArcs = PL_NewHashTable(kInitialTableSize,
|
||||
rdf_HashPointer,
|
||||
PL_CompareValues,
|
||||
PL_CompareValues,
|
||||
&gAllocOps,
|
||||
&mAllocator);
|
||||
|
||||
if (! mReverseArcs)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
PL_DHashTableInit(&mReverseArcs,
|
||||
PL_DHashGetStubOps(),
|
||||
nsnull,
|
||||
sizeof(Entry),
|
||||
PL_DHASH_MIN_SIZE);
|
||||
|
||||
#ifdef MOZ_THREADSAFE_RDF
|
||||
mLock = PR_NewLock();
|
||||
@ -747,20 +781,14 @@ InMemoryDataSource::~InMemoryDataSource()
|
||||
fprintf(stdout, "%d - RDF: InMemoryDataSource\n", gInstanceCount);
|
||||
#endif
|
||||
|
||||
if (mForwardArcs) {
|
||||
// This'll release all of the Assertion objects that are
|
||||
// associated with this data source. We only need to do this
|
||||
// for the forward arcs, because the reverse arcs table
|
||||
// indexes the exact same set of resources.
|
||||
PL_HashTableEnumerateEntries(mForwardArcs, DeleteForwardArcsEntry, nsnull);
|
||||
// This'll release all of the Assertion objects that are
|
||||
// associated with this data source. We only need to do this
|
||||
// for the forward arcs, because the reverse arcs table
|
||||
// indexes the exact same set of resources.
|
||||
PL_DHashTableEnumerate(&mForwardArcs, DeleteForwardArcsEntry, &mAllocator);
|
||||
PL_DHashTableFinish(&mForwardArcs);
|
||||
|
||||
PL_HashTableDestroy(mForwardArcs);
|
||||
mForwardArcs = nsnull;
|
||||
}
|
||||
if (mReverseArcs) {
|
||||
PL_HashTableDestroy(mReverseArcs);
|
||||
mReverseArcs = nsnull;
|
||||
}
|
||||
PL_DHashTableFinish(&mReverseArcs);
|
||||
|
||||
PR_LOG(gLog, PR_LOG_ALWAYS,
|
||||
("InMemoryDataSource(%p): destroyed.", this));
|
||||
@ -770,19 +798,23 @@ InMemoryDataSource::~InMemoryDataSource()
|
||||
#endif
|
||||
}
|
||||
|
||||
PRIntn
|
||||
InMemoryDataSource::DeleteForwardArcsEntry(PLHashEntry* he, PRIntn i, void* arg)
|
||||
PLDHashOperator PR_CALLBACK
|
||||
InMemoryDataSource::DeleteForwardArcsEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg)
|
||||
{
|
||||
Assertion* as = (Assertion*) he->value;
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aHdr);
|
||||
nsFixedSizeAllocator* allocator = NS_STATIC_CAST(nsFixedSizeAllocator*, aArg);
|
||||
|
||||
Assertion* as = entry->mAssertions;
|
||||
while (as) {
|
||||
Assertion* doomed = as;
|
||||
as = as->mNext;
|
||||
|
||||
// Unlink, and release the datasource's reference.
|
||||
doomed->mNext = doomed->mInvNext = nsnull;
|
||||
doomed->Release();
|
||||
doomed->Release(*allocator);
|
||||
}
|
||||
return HT_ENUMERATE_NEXT;
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
@ -1005,8 +1037,9 @@ InMemoryDataSource::GetSources(nsIRDFResource* aProperty,
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryAssertionEnumeratorImpl* result
|
||||
= new (mAllocator) InMemoryAssertionEnumeratorImpl(this, nsnull, aProperty, aTarget, aTruthValue);
|
||||
InMemoryAssertionEnumeratorImpl* result =
|
||||
InMemoryAssertionEnumeratorImpl::Create(this, nsnull, aProperty,
|
||||
aTarget, aTruthValue);
|
||||
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -1037,8 +1070,9 @@ InMemoryDataSource::GetTargets(nsIRDFResource* aSource,
|
||||
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryAssertionEnumeratorImpl* result
|
||||
= new (mAllocator) InMemoryAssertionEnumeratorImpl(this, aSource, aProperty, nsnull, aTruthValue);
|
||||
InMemoryAssertionEnumeratorImpl* result =
|
||||
InMemoryAssertionEnumeratorImpl::Create(this, aSource, aProperty,
|
||||
nsnull, aTruthValue);
|
||||
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -1080,7 +1114,7 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource,
|
||||
next = next->mNext;
|
||||
}
|
||||
|
||||
as = new (mAllocator) Assertion(aSource, aProperty, aTarget, aTruthValue);
|
||||
as = Assertion::Create(mAllocator, aSource, aProperty, aTarget, aTruthValue);
|
||||
if (! as)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -1219,7 +1253,7 @@ InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource,
|
||||
|
||||
// Unlink, and release the datasource's reference
|
||||
as->mNext = as->mInvNext = nsnull;
|
||||
as->Release();
|
||||
as->Release(mAllocator);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1457,7 +1491,7 @@ InMemoryDataSource::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResu
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
InMemoryArcsEnumeratorImpl* result =
|
||||
new (mAllocator) InMemoryArcsEnumeratorImpl(this, nsnull, aTarget);
|
||||
InMemoryArcsEnumeratorImpl::Create(this, nsnull, aTarget);
|
||||
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -1478,7 +1512,7 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator**
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
InMemoryArcsEnumeratorImpl* result =
|
||||
new (mAllocator) InMemoryArcsEnumeratorImpl(this, aSource, nsnull);
|
||||
InMemoryArcsEnumeratorImpl::Create(this, aSource, nsnull);
|
||||
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -1489,16 +1523,16 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator**
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRIntn PR_CALLBACK
|
||||
rdf_ResourceEnumerator(PLHashEntry* he, PRIntn i, void* closure)
|
||||
PLDHashOperator PR_CALLBACK
|
||||
InMemoryDataSource::ResourceEnumerator(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg)
|
||||
{
|
||||
nsISupportsArray* resources = NS_STATIC_CAST(nsISupportsArray*, closure);
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aHdr);
|
||||
nsISupportsArray* resources = NS_STATIC_CAST(nsISupportsArray*, aArg);
|
||||
|
||||
nsIRDFResource* resource =
|
||||
NS_CONST_CAST(nsIRDFResource*, NS_STATIC_CAST(const nsIRDFResource*, he->key));
|
||||
|
||||
resources->AppendElement(resource);
|
||||
return HT_ENUMERATE_NEXT;
|
||||
resources->AppendElement(entry->mNode);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
@ -1514,7 +1548,7 @@ InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult)
|
||||
NS_AUTOLOCK(mLock);
|
||||
|
||||
// Enumerate all of our entries into an nsISupportsArray.
|
||||
PL_HashTableEnumerateEntries(mForwardArcs, rdf_ResourceEnumerator, values.get());
|
||||
PL_DHashTableEnumerate(&mForwardArcs, ResourceEnumerator, values.get());
|
||||
|
||||
*aResult = new nsArrayEnumerator(values);
|
||||
if (! *aResult)
|
||||
@ -1610,18 +1644,18 @@ InMemoryDataSource::Mark(nsIRDFResource* aSource,
|
||||
|
||||
struct SweepInfo {
|
||||
Assertion* mUnassertList;
|
||||
PLHashTable* mReverseArcs;
|
||||
PLDHashTable* mReverseArcs;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
InMemoryDataSource::Sweep()
|
||||
{
|
||||
SweepInfo info = { nsnull, mReverseArcs };
|
||||
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);
|
||||
PL_DHashTableEnumerate(&mForwardArcs, SweepForwardArcsEntries, &info);
|
||||
}
|
||||
|
||||
// Now we've left the autolock. Do the notification.
|
||||
@ -1649,19 +1683,22 @@ InMemoryDataSource::Sweep()
|
||||
|
||||
// Unlink, and release the datasource's reference
|
||||
doomed->mNext = doomed->mInvNext = nsnull;
|
||||
doomed->Release();
|
||||
doomed->Release(mAllocator);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRIntn
|
||||
InMemoryDataSource::SweepForwardArcsEntries(PLHashEntry* he, PRIntn i, void* arg)
|
||||
PLDHashOperator PR_CALLBACK
|
||||
InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHdr,
|
||||
PRUint32 aNumber, void* aArg)
|
||||
{
|
||||
SweepInfo* info = (SweepInfo*) arg;
|
||||
Entry* entry = NS_REINTERPRET_CAST(Entry*, aHdr);
|
||||
SweepInfo* info = NS_STATIC_CAST(SweepInfo*, aArg);
|
||||
|
||||
Assertion* as = (Assertion*) he->value;
|
||||
Assertion* as = entry->mAssertions;
|
||||
Assertion* prev = nsnull;
|
||||
while (as) {
|
||||
if (as->IsMarked()) {
|
||||
@ -1677,17 +1714,17 @@ InMemoryDataSource::SweepForwardArcsEntries(PLHashEntry* he, PRIntn i, void* arg
|
||||
}
|
||||
else {
|
||||
// it's the first one. update the hashtable entry.
|
||||
he->value = next;
|
||||
entry->mAssertions = next;
|
||||
}
|
||||
|
||||
// remove from the reverse arcs
|
||||
PLHashEntry** hep =
|
||||
PL_HashTableRawLookup(info->mReverseArcs,
|
||||
rdf_HashPointer(as->mTarget),
|
||||
as->mTarget);
|
||||
|
||||
Assertion* ras = (Assertion*) ((*hep)->value);
|
||||
NS_ASSERTION(ras != nsnull, "no assertion in reverse arcs");
|
||||
PLDHashEntryHdr* hdr =
|
||||
PL_DHashTableOperate(info->mReverseArcs, as->mTarget, PL_DHASH_LOOKUP);
|
||||
|
||||
NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(hdr), "no assertion in reverse arcs");
|
||||
|
||||
Entry* rentry = NS_REINTERPRET_CAST(Entry*, hdr);
|
||||
Assertion* ras = rentry->mAssertions;
|
||||
Assertion* rprev = nsnull;
|
||||
while (ras) {
|
||||
if (ras == as) {
|
||||
@ -1696,7 +1733,7 @@ InMemoryDataSource::SweepForwardArcsEntries(PLHashEntry* he, PRIntn i, void* arg
|
||||
}
|
||||
else {
|
||||
// it's the first one. update the hashtable entry.
|
||||
(*hep)->value = ras->mInvNext;
|
||||
rentry->mAssertions = ras->mInvNext;
|
||||
}
|
||||
as->mInvNext = nsnull; // for my sanity.
|
||||
break;
|
||||
@ -1706,9 +1743,8 @@ InMemoryDataSource::SweepForwardArcsEntries(PLHashEntry* he, PRIntn i, void* arg
|
||||
}
|
||||
|
||||
// Wow, it was the _only_ one. Unhash it.
|
||||
if (! (*hep)->value)
|
||||
PL_HashTableRawRemove(info->mReverseArcs, hep, *hep);
|
||||
|
||||
if (! rentry->mAssertions)
|
||||
PL_DHashTableOperate(info->mReverseArcs, as->mTarget, PL_DHASH_REMOVE);
|
||||
|
||||
// add to the list of assertions to unassert
|
||||
as->mNext = info->mUnassertList;
|
||||
@ -1719,11 +1755,11 @@ InMemoryDataSource::SweepForwardArcsEntries(PLHashEntry* he, PRIntn i, void* arg
|
||||
}
|
||||
}
|
||||
|
||||
PRIntn result = HT_ENUMERATE_NEXT;
|
||||
PLDHashOperator result = PL_DHASH_NEXT;
|
||||
|
||||
// if no more assertions exist for this resource, then unhash it.
|
||||
if (! he->value)
|
||||
result |= HT_ENUMERATE_REMOVE;
|
||||
if (! entry->mAssertions)
|
||||
result = PL_DHASH_REMOVE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -229,6 +229,40 @@ NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
|
||||
return mRefCnt; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given
|
||||
* <i>_class</i>.
|
||||
* @param _class The name of the class implementing the method
|
||||
* @param _destroy A statement that is executed when the object's
|
||||
* refcount drops to zero.
|
||||
*
|
||||
* For example,
|
||||
*
|
||||
* NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this))
|
||||
*
|
||||
* will cause
|
||||
*
|
||||
* Destroy(this);
|
||||
*
|
||||
* to be invoked when the object's refcount drops to zero. This
|
||||
* allows for arbitrary teardown activity to occur (e.g., deallocation
|
||||
* of object allocated with placement new).
|
||||
*/
|
||||
#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
NS_ASSERT_OWNINGTHREAD(_class); \
|
||||
--mRefCnt; \
|
||||
NS_LOG_RELEASE(this, mRefCnt, #_class); \
|
||||
if (mRefCnt == 0) { \
|
||||
mRefCnt = 1; /* stabilize */ \
|
||||
_destroy; \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
@ -242,20 +276,8 @@ NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
|
||||
* destructor, we make sure that no balanced refcounting can return
|
||||
* the refcount to |0|.
|
||||
*/
|
||||
#define NS_IMPL_RELEASE(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
NS_ASSERT_OWNINGTHREAD(_class); \
|
||||
--mRefCnt; \
|
||||
NS_LOG_RELEASE(this, mRefCnt, #_class); \
|
||||
if (mRefCnt == 0) { \
|
||||
mRefCnt = 1; /* stabilize */ \
|
||||
NS_DELETEXPCOM(this); \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
}
|
||||
#define NS_IMPL_RELEASE(_class) \
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -32,14 +32,13 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
|
||||
|
||||
nsresult
|
||||
nsFixedSizeAllocator::Bucket *
|
||||
nsFixedSizeAllocator::AddBucket(size_t aSize)
|
||||
{
|
||||
void* p;
|
||||
PL_ARENA_ALLOCATE(p, &mPool, sizeof(Bucket));
|
||||
if (! p)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return nsnull;
|
||||
|
||||
Bucket* bucket = NS_STATIC_CAST(Bucket*, p);
|
||||
bucket->mSize = aSize;
|
||||
@ -47,11 +46,9 @@ nsFixedSizeAllocator::AddBucket(size_t aSize)
|
||||
bucket->mNext = mBuckets;
|
||||
|
||||
mBuckets = bucket;
|
||||
return NS_OK;
|
||||
return bucket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
nsFixedSizeAllocator::Init(const char* aName,
|
||||
const size_t* aBucketSizes,
|
||||
@ -77,33 +74,36 @@ nsFixedSizeAllocator::Init(const char* aName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void*
|
||||
nsFixedSizeAllocator::Alloc(size_t aSize)
|
||||
nsFixedSizeAllocator::Bucket *
|
||||
nsFixedSizeAllocator::FindBucket(size_t aSize)
|
||||
{
|
||||
Bucket** link = &mBuckets;
|
||||
Bucket* bucket = mBuckets;
|
||||
Bucket* bucket;
|
||||
|
||||
while (bucket != nsnull) {
|
||||
while ((bucket = *link) != nsnull) {
|
||||
if (aSize == bucket->mSize) {
|
||||
// Promote to the head of the list, under the assumption
|
||||
// that we'll allocate same-sized object cotemporaneously.
|
||||
// that we'll allocate same-sized object contemporaneously.
|
||||
*link = bucket->mNext;
|
||||
bucket->mNext = mBuckets;
|
||||
mBuckets = bucket;
|
||||
break;
|
||||
return bucket;
|
||||
}
|
||||
|
||||
link = &bucket->mNext;
|
||||
bucket = bucket->mNext;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void*
|
||||
nsFixedSizeAllocator::Alloc(size_t aSize)
|
||||
{
|
||||
Bucket* bucket = FindBucket(aSize);
|
||||
if (! bucket) {
|
||||
// Oops, we don't carry that size. Let's fix that.
|
||||
nsresult rv = AddBucket(aSize);
|
||||
if (NS_FAILED(rv))
|
||||
bucket = AddBucket(aSize);
|
||||
if (! bucket)
|
||||
return nsnull;
|
||||
|
||||
bucket = mBuckets;
|
||||
}
|
||||
|
||||
void* next;
|
||||
@ -112,37 +112,29 @@ nsFixedSizeAllocator::Alloc(size_t aSize)
|
||||
bucket->mFirst = bucket->mFirst->mNext;
|
||||
}
|
||||
else {
|
||||
// Allocate headroom so we can have a backpointer. Use
|
||||
// 'sizeof double' so that the block stays well-aligned
|
||||
PL_ARENA_ALLOCATE(next, &mPool, aSize + sizeof(double));
|
||||
|
||||
FreeEntry* entry = NS_STATIC_CAST(FreeEntry*, next);
|
||||
entry->mBucket = bucket;
|
||||
PL_ARENA_ALLOCATE(next, &mPool, aSize);
|
||||
if (!next)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
next = NS_STATIC_CAST(void*, NS_STATIC_CAST(char*, next) + sizeof(double));
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCRT::memset(next, 0xc8, bucket->mSize);
|
||||
nsCRT::memset(next, 0xc8, aSize);
|
||||
#endif
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsFixedSizeAllocator::Free(void* aPtr, size_t aSize)
|
||||
{
|
||||
FreeEntry* entry = NS_REINTERPRET_CAST(FreeEntry*, NS_STATIC_CAST(char*, aPtr) - sizeof(double));
|
||||
|
||||
Bucket* bucket = entry->mBucket;
|
||||
FreeEntry* entry = NS_REINTERPRET_CAST(FreeEntry*, aPtr);
|
||||
Bucket* bucket = FindBucket(aSize);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_ASSERTION(bucket->mSize == aSize, "ack! corruption! bucket->mSize != aSize!");
|
||||
NS_ASSERTION(bucket && bucket->mSize == aSize, "ack! corruption! bucket->mSize != aSize!");
|
||||
nsCRT::memset(aPtr, 0xd8, bucket->mSize);
|
||||
#endif
|
||||
|
||||
entry->mNext = bucket->mFirst;
|
||||
bucket->mFirst = entry;
|
||||
}
|
||||
|
||||
|
||||
@ -111,7 +111,7 @@
|
||||
#include "nsError.h"
|
||||
#include "plarena.h"
|
||||
|
||||
#define NS_SIZE_IN_HEAP(_size) ((_size) + sizeof(double))
|
||||
#define NS_SIZE_IN_HEAP(_size) (_size)
|
||||
|
||||
class NS_COM nsFixedSizeAllocator
|
||||
{
|
||||
@ -125,7 +125,6 @@ protected:
|
||||
friend struct FreeEntry;
|
||||
|
||||
struct FreeEntry {
|
||||
Bucket* mBucket;
|
||||
FreeEntry* mNext;
|
||||
};
|
||||
|
||||
@ -137,15 +136,19 @@ protected:
|
||||
|
||||
Bucket* mBuckets;
|
||||
|
||||
nsresult
|
||||
Bucket *
|
||||
AddBucket(size_t aSize);
|
||||
|
||||
Bucket *
|
||||
FindBucket(size_t aSize);
|
||||
|
||||
public:
|
||||
nsFixedSizeAllocator() : mBuckets(nsnull) {}
|
||||
|
||||
~nsFixedSizeAllocator() {
|
||||
if (mBuckets)
|
||||
PL_FinishArenaPool(&mPool); }
|
||||
PL_FinishArenaPool(&mPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the fixed size allocator. 'aName' is used to tag
|
||||
@ -169,7 +172,7 @@ public:
|
||||
/**
|
||||
* Free a pointer allocated using a fixed-size allocator
|
||||
*/
|
||||
static void Free(void* aPtr, size_t aSize);
|
||||
void Free(void* aPtr, size_t aSize);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -229,6 +229,40 @@ NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
|
||||
return mRefCnt; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given
|
||||
* <i>_class</i>.
|
||||
* @param _class The name of the class implementing the method
|
||||
* @param _destroy A statement that is executed when the object's
|
||||
* refcount drops to zero.
|
||||
*
|
||||
* For example,
|
||||
*
|
||||
* NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this))
|
||||
*
|
||||
* will cause
|
||||
*
|
||||
* Destroy(this);
|
||||
*
|
||||
* to be invoked when the object's refcount drops to zero. This
|
||||
* allows for arbitrary teardown activity to occur (e.g., deallocation
|
||||
* of object allocated with placement new).
|
||||
*/
|
||||
#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
NS_ASSERT_OWNINGTHREAD(_class); \
|
||||
--mRefCnt; \
|
||||
NS_LOG_RELEASE(this, mRefCnt, #_class); \
|
||||
if (mRefCnt == 0) { \
|
||||
mRefCnt = 1; /* stabilize */ \
|
||||
_destroy; \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
@ -242,20 +276,8 @@ NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
|
||||
* destructor, we make sure that no balanced refcounting can return
|
||||
* the refcount to |0|.
|
||||
*/
|
||||
#define NS_IMPL_RELEASE(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
|
||||
NS_ASSERT_OWNINGTHREAD(_class); \
|
||||
--mRefCnt; \
|
||||
NS_LOG_RELEASE(this, mRefCnt, #_class); \
|
||||
if (mRefCnt == 0) { \
|
||||
mRefCnt = 1; /* stabilize */ \
|
||||
NS_DELETEXPCOM(this); \
|
||||
return 0; \
|
||||
} \
|
||||
return mRefCnt; \
|
||||
}
|
||||
#define NS_IMPL_RELEASE(_class) \
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user