/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Mozilla browser. * * The Initial Developer of the Original Code is Netscape * Communications, Inc. Portions created by Netscape are * Copyright (C) 1999, Mozilla. All Rights Reserved. * * Contributor(s): * Radha Kulkarni */ #include "nsISupportsUtils.h" #include "nsIDOMDocument.h" #include "nsSHEntry.h" #include "nsIGenericFactory.h" #ifdef XXX_NS_DEBUG // XXX: we'll need a logging facility for debugging #define WEB_TRACE(_bit,_args) \ PR_BEGIN_MACRO \ if (WEB_LOG_TEST(gLogModule,_bit)) { \ PR_LogPrint _args; \ } \ PR_END_MACRO #else #define WEB_TRACE(_bit,_args) #endif //***************************************************************************** //*** nsSHEnumerator: Object Management //***************************************************************************** class nsSHEnumerator : public nsIEnumerator { public: NS_DECL_ISUPPORTS NS_DECL_NSIENUMERATOR NS_IMETHOD CurrentItem(nsISHEntry ** aItem); private: friend class nsSHEntry; nsSHEnumerator(nsSHEntry * aEntry); virtual ~nsSHEnumerator(); PRInt32 mIndex; nsSHEntry * mSHEntry; }; //***************************************************************************** //*** nsSHEntry: Object Management //***************************************************************************** nsSHEntry::nsSHEntry() { NS_INIT_REFCNT(); mURI = (nsnull); mPostData = (nsnull); mDocument= (nsnull); mLayoutHistoryState= (nsnull); mTitle = nsnull; } NS_IMETHODIMP nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, nsIDOMDocument * aDOMDocument, nsIInputStream * aInputStream, nsISupports * aHistoryLayoutState) { SetUri(aURI); SetTitle(aTitle); SetDocument(aDOMDocument); SetPostData(aInputStream); SetLayoutHistoryState(aHistoryLayoutState); return NS_OK; } nsSHEntry::~nsSHEntry() { NS_IF_RELEASE(mURI); NS_IF_RELEASE(mPostData); NS_IF_RELEASE(mDocument); NS_IF_RELEASE(mLayoutHistoryState); if (mTitle) delete mTitle; DestroyChildren(); } void nsSHEntry::DestroyChildren() { PRInt32 i, n; n = GetChildCount(&n); for (i = 0; i < n; i++) { nsISHEntry* child = (nsISHEntry *) mChildren.ElementAt(i); child->SetParent(nsnull); // Weak reference to parent delete child; } mChildren.Clear(); } // nsSHEntry::nsISupports NS_IMPL_ISUPPORTS2(nsSHEntry, nsISHEntry, nsISHContainer) NS_IMETHODIMP nsSHEntry::GetUri(nsIURI **aUri) { NS_ENSURE_ARG_POINTER(aUri); *aUri = mURI; NS_IF_ADDREF(mURI); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetUri(nsIURI * aUri) { NS_IF_RELEASE(mURI); mURI = aUri; NS_IF_ADDREF(mURI); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetDocument(nsIDOMDocument * aDocument) { NS_IF_RELEASE(mDocument); mDocument = aDocument; NS_IF_ADDREF(mDocument); return NS_OK; } NS_IMETHODIMP nsSHEntry::GetDocument(nsIDOMDocument ** aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mDocument; NS_IF_ADDREF(mDocument); return NS_OK; } NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle) { NS_ENSURE_ARG_POINTER(aTitle); if (mTitle) *aTitle = mTitle->ToNewUnicode(); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetTitle(const PRUnichar* aTitle) { if (mTitle) delete mTitle; if (aTitle) mTitle = new nsString(aTitle); return NS_OK; } NS_IMETHODIMP nsSHEntry::GetPostData(nsIInputStream ** aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mPostData; NS_IF_ADDREF(mPostData); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetPostData(nsIInputStream * aPostData) { NS_IF_RELEASE(mPostData); mPostData = aPostData; NS_IF_ADDREF(aPostData); return NS_OK; } NS_IMETHODIMP nsSHEntry::GetLayoutHistoryState(nsISupports ** aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mLayoutHistoryState; NS_IF_ADDREF(mLayoutHistoryState); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetLayoutHistoryState(nsISupports * aState) { NS_IF_RELEASE(mLayoutHistoryState); mLayoutHistoryState = aState; NS_IF_ADDREF(aState); return NS_OK; } NS_IMETHODIMP nsSHEntry::GetParent(nsISHEntry ** aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = mParent; NS_IF_ADDREF(*aResult); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetParent(nsISHEntry * aParent) { /* parent not Addrefed on purpose to avoid cyclic reference * Null parent is OK */ mParent = aParent; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetChildCount(PRInt32 * aCount) { NS_ENSURE_ARG_POINTER(aCount); *aCount = mChildren.Count(); return NS_OK; } NS_IMETHODIMP nsSHEntry::AddChild(nsISHEntry * aChild) { NS_ENSURE_ARG_POINTER(aChild); NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE); mChildren.AppendElement((void *)aChild); NS_ADDREF(aChild); return NS_OK; } NS_IMETHODIMP nsSHEntry::RemoveChild(nsISHEntry * aChild) { NS_ENSURE_ARG_POINTER(aChild); PRBool childRemoved = mChildren.RemoveElement((void *)aChild); if (childRemoved) { aChild->SetParent(nsnull); NS_RELEASE(aChild); } return NS_OK; } NS_IMETHODIMP nsSHEntry::GetChildEnumerator(nsIEnumerator** aChildEnumerator) { nsresult status = NS_OK; NS_ENSURE_ARG_POINTER(aChildEnumerator); nsSHEnumerator * iterator = new nsSHEnumerator(this); if (iterator && !!NS_SUCCEEDED(status = CallQueryInterface(iterator, aChildEnumerator))) delete iterator; return status; } //***************************************************************************** //*** nsSHEnumerator: Object Management //***************************************************************************** nsSHEnumerator::nsSHEnumerator(nsSHEntry * aEntry):mIndex(0) { NS_INIT_REFCNT(); mSHEntry = aEntry; } nsSHEnumerator::~nsSHEnumerator() { } NS_IMETHODIMP nsSHEnumerator::Next() { mIndex++; PRUint32 cnt=0; cnt = mSHEntry->mChildren.Count(); if (mIndex < (PRInt32)cnt) return NS_OK; return NS_ERROR_FAILURE; } #if 0 NS_IMETHODIMP nsSHEnumerator::Prev() { mIndex--; if (mIndex >= 0 ) return NS_OK; return NS_ERROR_FAILURE; } NS_IMETHODIMP nsSHEnumerator::Last() { PRUint32 cnt; nsresult rv = mSHEntry->mChildren.Count(&cnt); if (NS_FAILED(rv)) return rv; mIndex = (PRInt32)cnt-1; return NS_OK; } #endif /* 0 */ NS_IMETHODIMP nsSHEnumerator::First() { mIndex = 0; return NS_OK; } NS_IMETHODIMP nsSHEnumerator::CurrentItem(nsISupports **aItem) { if (!aItem) return NS_ERROR_NULL_POINTER; PRUint32 cnt= mSHEntry->mChildren.Count(); if (mIndex >=0 && mIndex < (PRInt32)cnt){ *aItem = (nsISupports *)mSHEntry->mChildren.ElementAt(mIndex); NS_IF_ADDREF(*aItem); return NS_OK; } return NS_ERROR_FAILURE; } NS_IMPL_ISUPPORTS1(nsSHEnumerator, nsIEnumerator) NS_IMETHODIMP nsSHEnumerator::CurrentItem(nsISHEntry **aItem) { if (!aItem) return NS_ERROR_NULL_POINTER; PRUint32 cnt = mSHEntry->mChildren.Count(); if (mIndex >=0 && mIndex < (PRInt32)cnt){ nsCOMPtr indexIsupports = (nsISHEntry *) mSHEntry->mChildren.ElementAt(mIndex); return indexIsupports->QueryInterface(nsISHEntry::GetIID(),(void **)aItem); } return NS_ERROR_FAILURE; } NS_IMETHODIMP nsSHEnumerator::IsDone() { PRUint32 cnt; cnt = mSHEntry->mChildren.Count(); if (mIndex >= 0 && mIndex < (PRInt32)cnt ) { return NS_ENUMERATOR_FALSE; } return NS_OK; } #if 0 NS_IMETHODIMP nsRangeListIterator::QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (nsnull == aInstancePtr) { return NS_ERROR_NULL_POINTER; } if (aIID.Equals(nsIEnumerator::GetIID())) { *aInstancePtr = NS_STATIC_CAST(nsIEnumerator*, this); NS_ADDREF_THIS(); return NS_OK; } if (aIID.Equals(nsIBidirectionalEnumerator::GetIID())) { *aInstancePtr = NS_STATIC_CAST(nsIBidirectionalEnumerator*, this); NS_ADDREF_THIS(); return NS_OK; } return mDomSelection->QueryInterface(aIID, aInstancePtr); } #endif ////////////END nsSHEnumerator methods NS_IMETHODIMP NS_NewSHEntry(nsISupports* aOuter, REFNSIID aIID, void** aResult) { NS_PRECONDITION(aResult != nsnull, "null ptr"); if (! aResult) return NS_ERROR_NULL_POINTER; NS_PRECONDITION(aOuter == nsnull, "no aggregation"); if (aOuter) return NS_ERROR_NO_AGGREGATION; nsresult rv = NS_OK; nsSHEntry* result = new nsSHEntry(); if (! result) return NS_ERROR_OUT_OF_MEMORY; rv = result->QueryInterface(aIID, aResult); if (NS_FAILED(rv)) { delete result; *aResult = nsnull; return rv; } return rv; }