LCOV - code coverage report
Current view: directory - content/base/src - nsNodeInfo.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 92 77 83.7 %
Date: 2012-06-02 Functions: 16 13 81.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /*
      39                 :  * Class that represents a prefix/namespace/localName triple; a single
      40                 :  * nodeinfo is shared by all elements in a document that have that
      41                 :  * prefix, namespace, and localName.
      42                 :  */
      43                 : 
      44                 : #include "mozilla/Util.h"
      45                 : 
      46                 : #include "nscore.h"
      47                 : #include "nsNodeInfo.h"
      48                 : #include "nsNodeInfoManager.h"
      49                 : #include "nsCOMPtr.h"
      50                 : #include "nsString.h"
      51                 : #include "nsIAtom.h"
      52                 : #include "nsDOMString.h"
      53                 : #include "nsCRT.h"
      54                 : #include "nsContentUtils.h"
      55                 : #include "nsReadableUtils.h"
      56                 : #include "nsAutoPtr.h"
      57                 : #include NEW_H
      58                 : #include "nsFixedSizeAllocator.h"
      59                 : #include "prprf.h"
      60                 : #include "nsIDocument.h"
      61                 : #include "nsGkAtoms.h"
      62                 : 
      63                 : using namespace mozilla;
      64                 : 
      65                 : static const size_t kNodeInfoPoolSizes[] = {
      66                 :   sizeof(nsNodeInfo)
      67                 : };
      68                 : 
      69                 : static const PRInt32 kNodeInfoPoolInitialSize = 
      70                 :   (NS_SIZE_IN_HEAP(sizeof(nsNodeInfo))) * 64;
      71                 : 
      72                 : // static
      73                 : nsFixedSizeAllocator* nsNodeInfo::sNodeInfoPool = nsnull;
      74                 : 
      75                 : // static
      76                 : nsNodeInfo*
      77           11993 : nsNodeInfo::Create(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
      78                 :                    PRUint16 aNodeType, nsIAtom *aExtraName,
      79                 :                    nsNodeInfoManager *aOwnerManager)
      80                 : {
      81           11993 :   if (!sNodeInfoPool) {
      82             249 :     sNodeInfoPool = new nsFixedSizeAllocator();
      83             249 :     if (!sNodeInfoPool)
      84               0 :       return nsnull;
      85                 : 
      86                 :     nsresult rv = sNodeInfoPool->Init("NodeInfo Pool", kNodeInfoPoolSizes,
      87             249 :                                       1, kNodeInfoPoolInitialSize);
      88             249 :     if (NS_FAILED(rv)) {
      89               0 :       delete sNodeInfoPool;
      90               0 :       sNodeInfoPool = nsnull;
      91               0 :       return nsnull;
      92                 :     }
      93                 :   }
      94                 : 
      95                 :   // Create a new one
      96           11993 :   void* place = sNodeInfoPool->Alloc(sizeof(nsNodeInfo));
      97                 :   return place ?
      98                 :     new (place) nsNodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
      99           11993 :                            aOwnerManager) :
     100           23986 :     nsnull;
     101                 : }
     102                 : 
     103           23970 : nsNodeInfo::~nsNodeInfo()
     104                 : {
     105           11985 :   mOwnerManager->RemoveNodeInfo(this);
     106                 : 
     107           11985 :   NS_RELEASE(mInner.mName);
     108           11985 :   NS_IF_RELEASE(mInner.mPrefix);
     109           11985 :   NS_IF_RELEASE(mInner.mExtraName);
     110           11985 :   NS_RELEASE(mOwnerManager);
     111           23970 : }
     112                 : 
     113                 : 
     114           11993 : nsNodeInfo::nsNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
     115                 :                        PRUint16 aNodeType, nsIAtom* aExtraName,
     116           11993 :                        nsNodeInfoManager *aOwnerManager)
     117                 : {
     118           11993 :   CHECK_VALID_NODEINFO(aNodeType, aName, aNamespaceID, aExtraName);
     119           11993 :   NS_ABORT_IF_FALSE(aOwnerManager, "Invalid aOwnerManager");
     120                 : 
     121                 :   // Initialize mInner
     122           11993 :   NS_ADDREF(mInner.mName = aName);
     123           11993 :   NS_IF_ADDREF(mInner.mPrefix = aPrefix);
     124           11993 :   mInner.mNamespaceID = aNamespaceID;
     125           11993 :   mInner.mNodeType = aNodeType;
     126           11993 :   NS_ADDREF(mOwnerManager = aOwnerManager);
     127           11993 :   NS_IF_ADDREF(mInner.mExtraName = aExtraName);
     128                 : 
     129           11993 :   mDocument = aOwnerManager->GetDocument();
     130                 : 
     131                 :   // Now compute our cached members.
     132                 : 
     133                 :   // Qualified name.  If we have no prefix, use ToString on
     134                 :   // mInner.mName so that we get to share its buffer.
     135           11993 :   if (aPrefix) {
     136            2812 :     mQualifiedName = nsDependentAtomString(mInner.mPrefix) +
     137            5624 :                      NS_LITERAL_STRING(":") +
     138            8436 :                      nsDependentAtomString(mInner.mName);
     139                 :   } else {
     140            9181 :     mInner.mName->ToString(mQualifiedName);
     141                 :   }
     142                 : 
     143           11993 :   switch (aNodeType) {
     144                 :     case nsIDOMNode::ELEMENT_NODE:
     145                 :     case nsIDOMNode::ATTRIBUTE_NODE:
     146                 :       // Correct the case for HTML
     147           10922 :       if (aNodeType == nsIDOMNode::ELEMENT_NODE &&
     148             786 :           aNamespaceID == kNameSpaceID_XHTML && GetDocument() &&
     149             786 :           GetDocument()->IsHTML()) {
     150             775 :         nsContentUtils::ASCIIToUpper(mQualifiedName, mNodeName);
     151                 :       } else {
     152            8575 :         mNodeName = mQualifiedName;
     153                 :       }
     154            9350 :       mInner.mName->ToString(mLocalName);
     155            9350 :       break;
     156                 :     case nsIDOMNode::TEXT_NODE:
     157                 :     case nsIDOMNode::CDATA_SECTION_NODE:
     158                 :     case nsIDOMNode::COMMENT_NODE:
     159                 :     case nsIDOMNode::DOCUMENT_NODE:
     160                 :     case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
     161            2533 :       mInner.mName->ToString(mNodeName);
     162            2533 :       SetDOMStringToNull(mLocalName);
     163            2533 :       break;
     164                 :     case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
     165                 :     case nsIDOMNode::DOCUMENT_TYPE_NODE:
     166             110 :       mInner.mExtraName->ToString(mNodeName);
     167             110 :       SetDOMStringToNull(mLocalName);
     168             110 :       break;
     169                 :     default:
     170               0 :       NS_ABORT_IF_FALSE(aNodeType == PR_UINT16_MAX,
     171                 :                         "Unknown node type");
     172                 :   }
     173           11993 : }
     174                 : 
     175                 : 
     176                 : // nsISupports
     177                 : 
     178            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfo)
     179           11972 : NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfo)
     180                 : 
     181                 : static const char* kNSURIs[] = {
     182                 :   " ([none])",
     183                 :   " (xmlns)",
     184                 :   " (xml)",
     185                 :   " (xhtml)",
     186                 :   " (XLink)",
     187                 :   " (XSLT)",
     188                 :   " (XBL)",
     189                 :   " (MathML)",
     190                 :   " (RDF)",
     191                 :   " (XUL)"
     192                 : };
     193                 : 
     194           14219 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsNodeInfo)
     195           14219 :   if (NS_UNLIKELY(cb.WantDebugInfo())) {
     196                 :     char name[72];
     197               0 :     PRUint32 nsid = tmp->NamespaceID();
     198               0 :     nsAtomCString localName(tmp->NameAtom());
     199               0 :     if (nsid < ArrayLength(kNSURIs)) {
     200                 :       PR_snprintf(name, sizeof(name), "nsNodeInfo%s %s", kNSURIs[nsid],
     201               0 :                   localName.get());
     202                 :     }
     203                 :     else {
     204               0 :       PR_snprintf(name, sizeof(name), "nsNodeInfo %s", localName.get());
     205                 :     }
     206                 : 
     207               0 :     cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsNodeInfo), name);
     208                 :   }
     209                 :   else {
     210           14219 :     NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsNodeInfo, tmp->mRefCnt.get())
     211                 :   }
     212                 : 
     213           14219 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mOwnerManager,
     214                 :                                                   nsNodeInfoManager)
     215           14219 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     216                 : 
     217          437916 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeInfo)
     218          437908 : NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
     219          933568 : NS_INTERFACE_TABLE_HEAD(nsNodeInfo)
     220          933568 :   NS_INTERFACE_TABLE1(nsNodeInfo, nsINodeInfo)
     221          933568 :   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsNodeInfo)
     222               0 : NS_INTERFACE_MAP_END
     223                 : 
     224                 : // nsINodeInfo
     225                 : 
     226                 : nsresult
     227           21464 : nsNodeInfo::GetNamespaceURI(nsAString& aNameSpaceURI) const
     228                 : {
     229           21464 :   nsresult rv = NS_OK;
     230                 : 
     231           21464 :   if (mInner.mNamespaceID > 0) {
     232           21325 :     rv = nsContentUtils::NameSpaceManager()->GetNameSpaceURI(mInner.mNamespaceID,
     233           21325 :                                                              aNameSpaceURI);
     234                 :   } else {
     235             139 :     SetDOMStringToNull(aNameSpaceURI);
     236                 :   }
     237                 : 
     238           21464 :   return rv;
     239                 : }
     240                 : 
     241                 : 
     242                 : bool
     243               0 : nsNodeInfo::NamespaceEquals(const nsAString& aNamespaceURI) const
     244                 : {
     245                 :   PRInt32 nsid =
     246               0 :     nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
     247                 : 
     248               0 :   return nsINodeInfo::NamespaceEquals(nsid);
     249                 : }
     250                 : 
     251                 : // static
     252                 : void
     253            1403 : nsNodeInfo::ClearCache()
     254                 : {
     255                 :   // Clear our cache.
     256            1403 :   delete sNodeInfoPool;
     257            1403 :   sNodeInfoPool = nsnull;
     258            1403 : }
     259                 : 
     260                 : void
     261           11985 : nsNodeInfo::LastRelease()
     262                 : {
     263           23970 :   nsRefPtr<nsNodeInfoManager> kungFuDeathGrip = mOwnerManager;
     264           11985 :   this->~nsNodeInfo();
     265                 : 
     266                 :   // The refcount balancing and destructor re-entrancy protection
     267                 :   // code in Release() sets mRefCnt to 1 so we have to set it to 0
     268                 :   // here to prevent leaks
     269           11985 :   mRefCnt = 0;
     270                 : 
     271           11985 :   NS_ASSERTION(sNodeInfoPool, "No NodeInfoPool when deleting NodeInfo!!!");
     272           11985 :   sNodeInfoPool->Free(this, sizeof(nsNodeInfo));
     273           16377 : }

Generated by: LCOV version 1.7