From d86d1443a196cf498b3af420a28b996bd7db1d95 Mon Sep 17 00:00:00 2001 From: "cvshook%sicking.cc" Date: Tue, 17 Oct 2006 21:40:07 +0000 Subject: [PATCH] Bug 355754: Add nsTPtrArray. r=darin sr=bz --- content/base/src/nsAttrValue.cpp | 18 +++--- content/base/src/nsAttrValue.h | 4 +- content/xslt/src/xslt/txStylesheet.cpp | 23 +++---- content/xslt/src/xslt/txStylesheet.h | 7 ++- content/xslt/src/xslt/txToplevelItems.cpp | 4 +- content/xslt/src/xslt/txToplevelItems.h | 2 +- xpcom/glue/Makefile.in | 1 + xpcom/glue/nsTArray.h | 18 ++++++ xpcom/glue/nsTPtrArray.h | 74 +++-------------------- xpcom/tests/TestTArray.cpp | 46 ++++++++++++++ 10 files changed, 98 insertions(+), 99 deletions(-) diff --git a/content/base/src/nsAttrValue.cpp b/content/base/src/nsAttrValue.cpp index 25ef2de043d..f7a1c2254ca 100644 --- a/content/base/src/nsAttrValue.cpp +++ b/content/base/src/nsAttrValue.cpp @@ -48,12 +48,13 @@ #include "nsCSSDeclaration.h" #include "nsIHTMLDocument.h" #include "nsIDocument.h" +#include "nsTPtrArray.h" #ifdef MOZ_SVG #include "nsISVGValue.h" #endif -nsVoidArray* nsAttrValue::sEnumTableArray = nsnull; +nsTPtrArray* nsAttrValue::sEnumTableArray = nsnull; nsAttrValue::nsAttrValue() : mBits(0) @@ -97,7 +98,7 @@ nsAttrValue::Init() { NS_ASSERTION(!sEnumTableArray, "nsAttrValue already initialized"); - sEnumTableArray = new nsVoidArray; + sEnumTableArray = new nsTPtrArray; NS_ENSURE_TRUE(sEnumTableArray, NS_ERROR_OUT_OF_MEMORY); return NS_OK; @@ -350,8 +351,8 @@ nsAttrValue::ToString(nsAString& aResult) const case eEnum: { PRInt16 val = GetEnumValue(); - EnumTable* table = NS_STATIC_CAST(EnumTable*, sEnumTableArray-> - FastElementAt(GetIntInternal() & NS_ATTRVALUE_ENUMTABLEINDEX_MASK)); + const EnumTable* table = sEnumTableArray-> + ElementAt(GetIntInternal() & NS_ATTRVALUE_ENUMTABLEINDEX_MASK); while (table->tag) { if (table->value == val) { aResult.AssignASCII(table->tag); @@ -832,21 +833,18 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue, { ResetIfSet(); - // Have to const cast here since nsVoidArray can't deal with constpointers - EnumTable* tableStart = NS_CONST_CAST(EnumTable*, aTable); - nsAutoString val(aValue); while (aTable->tag) { if (aCaseSensitive ? val.EqualsASCII(aTable->tag) : val.EqualsIgnoreCase(aTable->tag)) { // Find index of EnumTable - PRInt16 index = sEnumTableArray->IndexOf(tableStart); + PRInt16 index = sEnumTableArray->IndexOf(aTable); if (index < 0) { - index = sEnumTableArray->Count(); + index = sEnumTableArray->Length(); NS_ASSERTION(index <= NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE, "too many enum tables"); - if (!sEnumTableArray->AppendElement(tableStart)) { + if (!sEnumTableArray->AppendElement(aTable)) { return PR_FALSE; } } diff --git a/content/base/src/nsAttrValue.h b/content/base/src/nsAttrValue.h index 9acbb661fea..15dbef316a6 100644 --- a/content/base/src/nsAttrValue.h +++ b/content/base/src/nsAttrValue.h @@ -57,7 +57,7 @@ class nsICSSStyleRule; class nsISVGValue; class nsIDocument; template class nsCOMArray; -class nsVoidArray; +template class nsTPtrArray; #define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12 @@ -285,7 +285,7 @@ private: PRBool EnsureEmptyMiscContainer(); PRBool EnsureEmptyAtomArray(); - static nsVoidArray* sEnumTableArray; + static nsTPtrArray* sEnumTableArray; PtrBits mBits; }; diff --git a/content/xslt/src/xslt/txStylesheet.cpp b/content/xslt/src/xslt/txStylesheet.cpp index 5dac726a46a..87a54126a89 100644 --- a/content/xslt/src/xslt/txStylesheet.cpp +++ b/content/xslt/src/xslt/txStylesheet.cpp @@ -272,7 +272,7 @@ txStylesheet::getKeyMap() PRBool txStylesheet::isStripSpaceAllowed(const txXPathNode& aNode, txIMatchContext* aContext) { - PRInt32 frameCount = mStripSpaceTests.Count(); + PRInt32 frameCount = mStripSpaceTests.Length(); if (frameCount == 0) { return PR_FALSE; } @@ -293,8 +293,7 @@ txStylesheet::isStripSpaceAllowed(const txXPathNode& aNode, txIMatchContext* aCo // check Whitespace stipping handling list against given Node PRInt32 i; for (i = 0; i < frameCount; ++i) { - txStripSpaceTest* sst = - NS_STATIC_CAST(txStripSpaceTest*, mStripSpaceTests[i]); + txStripSpaceTest* sst = mStripSpaceTests[i]; if (sst->matches(node, aContext)) { return sst->stripsSpace() && !XMLUtils::getXMLSpacePreserve(node); } @@ -322,7 +321,7 @@ txStylesheet::doneCompiling() frameIter.reset(); ImportFrame* frame; while ((frame = NS_STATIC_CAST(ImportFrame*, frameIter.next()))) { - nsVoidArray frameStripSpaceTests; + nsTPtrArray frameStripSpaceTests; txListIterator itemIter(&frame->mToplevelItems); itemIter.resetToEnd(); @@ -507,23 +506,19 @@ txStylesheet::addFrames(txListIterator& aInsertIter) nsresult txStylesheet::addStripSpace(txStripSpaceItem* aStripSpaceItem, - nsVoidArray& frameStripSpaceTests) + nsTPtrArray& aFrameStripSpaceTests) { - PRInt32 testCount = aStripSpaceItem->mStripSpaceTests.Count(); + PRInt32 testCount = aStripSpaceItem->mStripSpaceTests.Length(); for (; testCount > 0; --testCount) { - txStripSpaceTest* sst = - NS_STATIC_CAST(txStripSpaceTest*, - aStripSpaceItem->mStripSpaceTests[testCount-1]); + txStripSpaceTest* sst = aStripSpaceItem->mStripSpaceTests[testCount-1]; double priority = sst->getDefaultPriority(); - PRInt32 i, frameCount = frameStripSpaceTests.Count(); + PRInt32 i, frameCount = aFrameStripSpaceTests.Length(); for (i = 0; i < frameCount; ++i) { - txStripSpaceTest* fsst = - NS_STATIC_CAST(txStripSpaceTest*, frameStripSpaceTests[i]); - if (fsst->getDefaultPriority() < priority) { + if (aFrameStripSpaceTests[i]->getDefaultPriority() < priority) { break; } } - if (!frameStripSpaceTests.InsertElementAt(sst, i)) { + if (!aFrameStripSpaceTests.InsertElementAt(i, sst)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/content/xslt/src/xslt/txStylesheet.h b/content/xslt/src/xslt/txStylesheet.h index d580565240a..3cb91ef60ae 100644 --- a/content/xslt/src/xslt/txStylesheet.h +++ b/content/xslt/src/xslt/txStylesheet.h @@ -43,7 +43,7 @@ #include "txExpandedNameMap.h" #include "txList.h" #include "txXSLTPatterns.h" -#include "nsVoidArray.h" +#include "nsTPtrArray.h" class txInstruction; class txToplevelItem; @@ -52,6 +52,7 @@ class txVariableItem; class txStripSpaceItem; class txAttributeSetItem; class txDecimalFormat; +class txStripSpaceTest; class txStylesheet { @@ -161,7 +162,7 @@ private: nsresult addGlobalVariable(txVariableItem* aVariable); nsresult addFrames(txListIterator& aInsertIter); nsresult addStripSpace(txStripSpaceItem* aStripSpaceItem, - nsVoidArray& frameStripSpaceTests); + nsTPtrArray& aFrameStripSpaceTests); nsresult addAttributeSet(txAttributeSetItem* aAttributeSetItem); // Refcount @@ -196,7 +197,7 @@ private: txExpandedNameMap mKeys; // Array of all txStripSpaceTests, sorted in acending order - nsVoidArray mStripSpaceTests; + nsTPtrArray mStripSpaceTests; // Default templates nsAutoPtr mContainerTemplate; diff --git a/content/xslt/src/xslt/txToplevelItems.cpp b/content/xslt/src/xslt/txToplevelItems.cpp index ba27a7116c6..379c16904c7 100644 --- a/content/xslt/src/xslt/txToplevelItems.cpp +++ b/content/xslt/src/xslt/txToplevelItems.cpp @@ -50,9 +50,9 @@ TX_IMPL_GETTYPE(txStripSpaceItem, txToplevelItem::stripSpace) txStripSpaceItem::~txStripSpaceItem() { - PRInt32 i, count = mStripSpaceTests.Count(); + PRInt32 i, count = mStripSpaceTests.Length(); for (i = 0; i < count; ++i) { - delete NS_STATIC_CAST(txStripSpaceTest*, mStripSpaceTests[i]); + delete mStripSpaceTests[i]; } } diff --git a/content/xslt/src/xslt/txToplevelItems.h b/content/xslt/src/xslt/txToplevelItems.h index 19518bee1b7..f4876c2d2de 100644 --- a/content/xslt/src/xslt/txToplevelItems.h +++ b/content/xslt/src/xslt/txToplevelItems.h @@ -128,7 +128,7 @@ public: nsresult addStripSpaceTest(txStripSpaceTest* aStripSpaceTest); - nsVoidArray mStripSpaceTests; + nsTPtrArray mStripSpaceTests; }; // xsl:template diff --git a/xpcom/glue/Makefile.in b/xpcom/glue/Makefile.in index bf9e5046ea5..9725ab110bf 100644 --- a/xpcom/glue/Makefile.in +++ b/xpcom/glue/Makefile.in @@ -88,6 +88,7 @@ SDK_HEADERS = \ nsTHashtable.h \ nsVoidArray.h \ nsTArray.h \ + nsTPtrArray.h \ nsTWeakRef.h \ nsID.h \ nsIGenericFactory.h \ diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index ac334bfb417..0f1aae124aa 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -275,6 +275,24 @@ class nsTArray : public nsTArray_base { return Elements()[i]; } + // This method provides direct access to the i'th element of the array in + // a bounds safe manner. If the requested index is out of bounds the + // provided default value is returned. + // @param i The index of an element in the array. + // @param def The value to return if the index is out of bounds. + elem_type& SafeElementAt(index_type i, elem_type& def) { + return i < Length() ? Elements()[i] : def; + } + + // This method provides direct access to the i'th element of the array in + // a bounds safe manner. If the requested index is out of bounds the + // provided default value is returned. + // @param i The index of an element in the array. + // @param def The value to return if the index is out of bounds. + const elem_type& SafeElementAt(index_type i, const elem_type& def) const { + return i < Length() ? Elements()[i] : def; + } + // Shorthand for ElementAt(i) elem_type& operator[](index_type i) { return ElementAt(i); diff --git a/xpcom/glue/nsTPtrArray.h b/xpcom/glue/nsTPtrArray.h index a65cdbfb44b..5bf5f3a56c5 100755 --- a/xpcom/glue/nsTPtrArray.h +++ b/xpcom/glue/nsTPtrArray.h @@ -51,6 +51,10 @@ template class nsTPtrArray : public nsTArray { public: typedef nsTPtrArray self_type; + typedef nsTArray parent_type; + typedef parent_type::size_type size_type; + typedef parent_type::elem_type elem_type; + typedef parent_type::index_type index_type; // // Initialization methods @@ -75,81 +79,17 @@ class nsTPtrArray : public nsTArray { // Forward SafeElementAt to avoid shadowing (and warnings thereof) elem_type& SafeElementAt(index_type i, elem_type& def) { - return nsTArray::SafeElementAt(i, def); + return parent_type::SafeElementAt(i, def); } const elem_type& SafeElementAt(index_type i, const elem_type& def) const { - return nsTArray::SafeElementAt(i, def); + return parent_type::SafeElementAt(i, def); } // This method provides direct access to the i'th element of the array in // a bounds safe manner. If the requested index is out of bounds null is // returned. // @param i The index of an element in the array. - elem_type& SafeElementAt(index_type i) { - return SafeElementAt(i, nsnull); - } - - // This method provides direct access to the i'th element of the array in - // a bounds safe manner. If the requested index is out of bounds null is - // returned. - // @param i The index of an element in the array. - const elem_type& SafeElementAt(index_type i) const { - return SafeElementAt(i, nsnull); - } -}; - -// -// The templatized array class for storing pointers to const objects. This -// class is the same as nsTPtrArray except that it stores pointers to const -// objects. -// -template -class nsTConstPtrArray : public nsTArray { - public: - typedef nsTConstPtrArray self_type; - - // - // Initialization methods - // - - nsTConstPtrArray() {} - - // Initialize this array and pre-allocate some number of elements. - explicit nsTConstPtrArray(size_type capacity) { - SetCapacity(capacity); - } - - // The array's copy-constructor performs a 'deep' copy of the given array. - // @param other The array object to copy. - nsTConstPtrArray(const self_type& other) { - AppendElements(other); - } - - // - // Accessor methods - // - - // Forward SafeElementAt to avoid shadowing (and warnings thereof) - elem_type& SafeElementAt(index_type i, elem_type& def) { - return nsTArray::SafeElementAt(i, def); - } - const elem_type& SafeElementAt(index_type i, const elem_type& def) const { - return nsTArray::SafeElementAt(i, def); - } - - // This method provides direct access to the i'th element of the array in - // a bounds safe manner. If the requested index is out of bounds null is - // returned. - // @param i The index of an element in the array. - elem_type& SafeElementAt(index_type i) { - return SafeElementAt(i, nsnull); - } - - // This method provides direct access to the i'th element of the array in - // a bounds safe manner. If the requested index is out of bounds null is - // returned. - // @param i The index of an element in the array. - const elem_type& SafeElementAt(index_type i) const { + elem_type SafeElementAt(index_type i) const { return SafeElementAt(i, nsnull); } }; diff --git a/xpcom/tests/TestTArray.cpp b/xpcom/tests/TestTArray.cpp index 71d0ce90a2c..1012796609e 100644 --- a/xpcom/tests/TestTArray.cpp +++ b/xpcom/tests/TestTArray.cpp @@ -39,6 +39,7 @@ #include #include #include "nsTArray.h" +#include "nsTPtrArray.h" #include "nsMemory.h" #include "nsAutoPtr.h" #include "nsString.h" @@ -62,11 +63,21 @@ static PRBool test_basic_array(ElementType *data, const ElementType& extra) { nsTArray ary; ary.AppendElements(data, dataLen); + if (ary.Length() != dataLen) { + return PR_FALSE; + } PRUint32 i; for (i = 0; i < ary.Length(); ++i) { if (ary[i] != data[i]) return PR_FALSE; } + for (i = 0; i < ary.Length(); ++i) { + if (ary.SafeElementAt(i, extra) != data[i]) + return PR_FALSE; + } + if (ary.SafeElementAt(ary.Length(), extra) != extra || + ary.SafeElementAt(ary.Length() * 10, extra) != extra) + return PR_FALSE; // ensure sort results in ascending order ary.Sort(); for (i = 1; i < ary.Length(); ++i) { @@ -109,6 +120,9 @@ static PRBool test_basic_array(ElementType *data, ary.Clear(); if (!ary.IsEmpty() || ary.Elements() == nsnull) return PR_FALSE; + if (ary.SafeElementAt(0, extra) != extra || + ary.SafeElementAt(10, extra) != extra) + return PR_FALSE; ary = copy; for (i = 0; i < copy.Length(); ++i) { @@ -365,6 +379,37 @@ static PRBool test_refptr_array() { //---- +static PRBool test_ptrarray() { + nsTPtrArray ary; + if (ary.SafeElementAt(0) != nsnull) + return PR_FALSE; + if (ary.SafeElementAt(1000) != nsnull) + return PR_FALSE; + PRUint32 a = 10; + ary.AppendElement(&a); + if (*ary[0] != a) + return PR_FALSE; + if (*ary.SafeElementAt(0) != a) + return PR_FALSE; + + nsTPtrArray cary; + if (cary.SafeElementAt(0) != nsnull) + return PR_FALSE; + if (cary.SafeElementAt(1000) != nsnull) + return PR_FALSE; + const PRUint32 b = 14; + cary.AppendElement(&a); + cary.AppendElement(&b); + if (*cary[0] != a || *cary[1] != b) + return PR_FALSE; + if (*cary.SafeElementAt(0) != a || *cary.SafeElementAt(1) != b) + return PR_FALSE; + + return PR_TRUE; +} + +//---- + typedef PRBool (*TestFunc)(); #define DECL_TEST(name) { #name, name } @@ -380,6 +425,7 @@ static const struct Test { DECL_TEST(test_string_array), DECL_TEST(test_comptr_array), DECL_TEST(test_refptr_array), + DECL_TEST(test_ptrarray), { nsnull, nsnull } };