dom/xslt/xpath/txResultRecycler.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "txResultRecycler.h"
     7 #include "txExprResult.h"
     8 #include "txNodeSet.h"
    10 txResultRecycler::txResultRecycler()
    11     : mEmptyStringResult(nullptr),
    12       mTrueResult(nullptr),
    13       mFalseResult(nullptr)
    14 {
    15 }
    17 txResultRecycler::~txResultRecycler()
    18 {
    19     txStackIterator stringIter(&mStringResults);
    20     while (stringIter.hasNext()) {
    21         delete static_cast<StringResult*>(stringIter.next());
    22     }
    23     txStackIterator nodesetIter(&mNodeSetResults);
    24     while (nodesetIter.hasNext()) {
    25         delete static_cast<txNodeSet*>(nodesetIter.next());
    26     }
    27     txStackIterator numberIter(&mNumberResults);
    28     while (numberIter.hasNext()) {
    29         delete static_cast<NumberResult*>(numberIter.next());
    30     }
    32     NS_IF_RELEASE(mEmptyStringResult);
    33     NS_IF_RELEASE(mTrueResult);
    34     NS_IF_RELEASE(mFalseResult);
    35 }
    38 nsresult
    39 txResultRecycler::init()
    40 {
    41     NS_ASSERTION(!mEmptyStringResult && !mTrueResult && !mFalseResult,
    42                  "Already inited");
    43     mEmptyStringResult = new StringResult(nullptr);
    44     NS_ENSURE_TRUE(mEmptyStringResult, NS_ERROR_OUT_OF_MEMORY);
    46     NS_ADDREF(mEmptyStringResult);
    48     mTrueResult = new BooleanResult(true);
    49     NS_ENSURE_TRUE(mTrueResult, NS_ERROR_OUT_OF_MEMORY);
    51     NS_ADDREF(mTrueResult);
    53     mFalseResult = new BooleanResult(false);
    54     NS_ENSURE_TRUE(mFalseResult, NS_ERROR_OUT_OF_MEMORY);
    56     NS_ADDREF(mFalseResult);
    58     return NS_OK;
    59 }
    62 void
    63 txResultRecycler::recycle(txAExprResult* aResult)
    64 {
    65     NS_ASSERTION(aResult->mRefCnt == 0, "In-use txAExprResult recycled");
    66     nsRefPtr<txResultRecycler> kungFuDeathGrip;
    67     aResult->mRecycler.swap(kungFuDeathGrip);
    69     nsresult rv = NS_OK;
    70     switch (aResult->getResultType()) {
    71         case txAExprResult::STRING:
    72         {
    73             rv = mStringResults.push(static_cast<StringResult*>(aResult));
    74             if (NS_FAILED(rv)) {
    75                 delete aResult;
    76             }
    77             return;
    78         }
    79         case txAExprResult::NODESET:
    80         {
    81             static_cast<txNodeSet*>(aResult)->clear();
    82             rv = mNodeSetResults.push(static_cast<txNodeSet*>(aResult));
    83             if (NS_FAILED(rv)) {
    84                 delete aResult;
    85             }
    86             return;
    87         }
    88         case txAExprResult::NUMBER:
    89         {
    90             rv = mNumberResults.push(static_cast<NumberResult*>(aResult));
    91             if (NS_FAILED(rv)) {
    92                 delete aResult;
    93             }
    94             return;
    95         }
    96         default:
    97         {
    98             delete aResult;
    99         }
   100     }
   101 }
   103 nsresult
   104 txResultRecycler::getStringResult(StringResult** aResult)
   105 {
   106     if (mStringResults.isEmpty()) {
   107         *aResult = new StringResult(this);
   108         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
   109     }
   110     else {
   111         *aResult = static_cast<StringResult*>(mStringResults.pop());
   112         (*aResult)->mValue.Truncate();
   113         (*aResult)->mRecycler = this;
   114     }
   115     NS_ADDREF(*aResult);
   117     return NS_OK;
   118 }
   120 nsresult
   121 txResultRecycler::getStringResult(const nsAString& aValue,
   122                                   txAExprResult** aResult)
   123 {
   124     if (mStringResults.isEmpty()) {
   125         *aResult = new StringResult(aValue, this);
   126         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
   127     }
   128     else {
   129         StringResult* strRes =
   130             static_cast<StringResult*>(mStringResults.pop());
   131         strRes->mValue = aValue;
   132         strRes->mRecycler = this;
   133         *aResult = strRes;
   134     }
   135     NS_ADDREF(*aResult);
   137     return NS_OK;
   138 }
   140 void
   141 txResultRecycler::getEmptyStringResult(txAExprResult** aResult)
   142 {
   143     *aResult = mEmptyStringResult;
   144     NS_ADDREF(*aResult);
   145 }
   147 nsresult
   148 txResultRecycler::getNodeSet(txNodeSet** aResult)
   149 {
   150     if (mNodeSetResults.isEmpty()) {
   151         *aResult = new txNodeSet(this);
   152         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
   153     }
   154     else {
   155         *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
   156         (*aResult)->mRecycler = this;
   157     }
   158     NS_ADDREF(*aResult);
   160     return NS_OK;
   161 }
   163 nsresult
   164 txResultRecycler::getNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult)
   165 {
   166     if (mNodeSetResults.isEmpty()) {
   167         *aResult = new txNodeSet(*aNodeSet, this);
   168         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
   169     }
   170     else {
   171         *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
   172         (*aResult)->append(*aNodeSet);
   173         (*aResult)->mRecycler = this;
   174     }
   175     NS_ADDREF(*aResult);
   177     return NS_OK;
   178 }
   180 nsresult
   181 txResultRecycler::getNodeSet(const txXPathNode& aNode, txAExprResult** aResult)
   182 {
   183     if (mNodeSetResults.isEmpty()) {
   184         *aResult = new txNodeSet(aNode, this);
   185         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
   186     }
   187     else {
   188         txNodeSet* nodes = static_cast<txNodeSet*>(mNodeSetResults.pop());
   189         nodes->append(aNode);
   190         nodes->mRecycler = this;
   191         *aResult = nodes;
   192     }
   193     NS_ADDREF(*aResult);
   195     return NS_OK;
   196 }
   198 nsresult
   199 txResultRecycler::getNumberResult(double aValue, txAExprResult** aResult)
   200 {
   201     if (mNumberResults.isEmpty()) {
   202         *aResult = new NumberResult(aValue, this);
   203         NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
   204     }
   205     else {
   206         NumberResult* numRes =
   207             static_cast<NumberResult*>(mNumberResults.pop());
   208         numRes->value = aValue;
   209         numRes->mRecycler = this;
   210         *aResult = numRes;
   211     }
   212     NS_ADDREF(*aResult);
   214     return NS_OK;
   215 }
   217 void
   218 txResultRecycler::getBoolResult(bool aValue, txAExprResult** aResult)
   219 {
   220     *aResult = aValue ? mTrueResult : mFalseResult;
   221     NS_ADDREF(*aResult);
   222 }
   224 nsresult
   225 txResultRecycler::getNonSharedNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult)
   226 {
   227     if (aNodeSet->mRefCnt > 1) {
   228         return getNodeSet(aNodeSet, aResult);
   229     }
   231     *aResult = aNodeSet;
   232     NS_ADDREF(*aResult);
   234     return NS_OK;
   235 }
   237 void
   238 txAExprResult::Release()
   239 {
   240     --mRefCnt;
   241     NS_LOG_RELEASE(this, mRefCnt, "txAExprResult");
   242     if (mRefCnt == 0) {
   243         if (mRecycler) {
   244             mRecycler->recycle(this);
   245         }
   246         else {
   247             delete this;
   248         }
   249     }
   250 }

mercurial