diff --git a/rdf/base/idl/nsIRDFContainer.idl b/rdf/base/idl/nsIRDFContainer.idl index a19900dad20a..9fc3d112595b 100644 --- a/rdf/base/idl/nsIRDFContainer.idl +++ b/rdf/base/idl/nsIRDFContainer.idl @@ -28,26 +28,59 @@ interface nsIRDFContainer : nsISupports { readonly attribute nsIRDFDataSource DataSource; readonly attribute nsIRDFResource Resource; - // Initialize the container wrapper to the specified resource - // using the specified datasource for context. + /** + * Initialize the container wrapper to the specified resource + * using the specified datasource for context. + */ void Init(in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer); - // Return the number of elements in the container. Note that this - // may not always be accurate due to aggregation. + /** + * Return the number of elements in the container. Note that this + * may not always be accurate due to aggregation. + */ long GetCount(); - // Return an enumerator that can be used to enumerate the contents - // of the container in ascending order. + /** + * Return an enumerator that can be used to enumerate the contents + * of the container in ascending order. + */ nsISimpleEnumerator GetElements(); - // Append an element to the container, assigning it the next - // available ordinal. + /** + * Append an element to the container, assigning it the next + * available ordinal. + */ void AppendElement(in nsIRDFNode aElement); - // Remove the first occurence of the specified element from the - // container. + /** + * Remove the first occurence of the specified element from the + * container. If aRenumber is 'true' + */ void RemoveElement(in nsIRDFNode aElement, in boolean aRenumber); + + /** + * Insert aElement at the specified index. If aRenumber is 'true', then + * the underlying RDF graph will be 're-numbered' to accomodate the new + * element. + */ void InsertElementAt(in nsIRDFNode aElement, in long aIndex, in boolean aRenumber); + + /** + * Remove the element at the specified index. If aRenumber is 'true', then + * the underlying RDF graph will be 're-numbered' to accomodate the new + * element. + * + * @return the element that was removed. + */ + nsIRDFNode RemoveElementAt(in long aIndex, in boolean aRenumber); + + /** + * Determine the index of an element in the container. + * + * @return The index of the specified element in the container. If + * the element is not contained in the container, this function + * returns '-1'. + */ long IndexOf(in nsIRDFNode aElement); }; diff --git a/rdf/base/src/nsRDFContainer.cpp b/rdf/base/src/nsRDFContainer.cpp index 2f1cc18c0297..e6f1da062197 100644 --- a/rdf/base/src/nsRDFContainer.cpp +++ b/rdf/base/src/nsRDFContainer.cpp @@ -53,6 +53,7 @@ public: NS_IMETHOD AppendElement(nsIRDFNode *aElement); NS_IMETHOD RemoveElement(nsIRDFNode *aElement, PRBool aRenumber); NS_IMETHOD InsertElementAt(nsIRDFNode *aElement, PRInt32 aIndex, PRBool aRenumber); + NS_IMETHOD RemoveElementAt(PRInt32 aIndex, PRBool aRenumber, nsIRDFNode** _retval); NS_IMETHOD IndexOf(nsIRDFNode *aElement, PRInt32 *_retval); private: @@ -281,6 +282,53 @@ RDFContainerImpl::InsertElementAt(nsIRDFNode *aElement, PRInt32 aIndex, PRBool a return NS_OK; } +NS_IMETHODIMP +RDFContainerImpl::RemoveElementAt(PRInt32 aIndex, PRBool aRenumber, nsIRDFNode** _retval) +{ + NS_PRECONDITION(_retval != nsnull, "null ptr"); + if (! _retval) + return NS_ERROR_NULL_POINTER; + + *_retval = nsnull; + + if (aIndex< 1) + return NS_ERROR_ILLEGAL_VALUE; + + nsresult rv; + + PRInt32 count; + rv = GetCount(&count); + if (NS_FAILED(rv)) return rv; + + if (aIndex > count) + return NS_ERROR_ILLEGAL_VALUE; + + nsCOMPtr ordinal; + rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr old; + rv = mDataSource->GetTarget(mContainer, ordinal, PR_TRUE, getter_AddRefs(old)); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_OK) { + rv = mDataSource->Unassert(mContainer, ordinal, old); + if (NS_FAILED(rv)) return rv; + + if (aRenumber) { + // Now slide the rest of the collection backwards to fill in + // the gap. This will have the side effect of completely + // renumber the container from index to the end. + rv = Renumber(aIndex); + if (NS_FAILED(rv)) return rv; + } + } + + *_retval = old; + NS_ADDREF(*_retval); + + return NS_OK; +} NS_IMETHODIMP RDFContainerImpl::IndexOf(nsIRDFNode *aElement, PRInt32 *aIndex)