Back to index

lightning-sunbird  0.9+nobinonly
nsAttrName.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * IBM Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2003
00020  * IBM Corporation. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   IBM Corporation
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsAttrName_h___
00040 #define nsAttrName_h___
00041 
00042 #include "nsINodeInfo.h"
00043 #include "nsIAtom.h"
00044 #include "nsDOMString.h"
00045 
00046 typedef unsigned long PtrBits;
00047 
00048 #define NS_ATTRNAME_NODEINFO_BIT 1
00049 class nsAttrName
00050 {
00051 public:
00052   nsAttrName(const nsAttrName& aOther)
00053     : mBits(aOther.mBits)
00054   {
00055     AddRefInternalName();
00056   }
00057 
00058   explicit nsAttrName(nsIAtom* aAtom)
00059     : mBits(NS_REINTERPRET_CAST(PtrBits, aAtom))
00060   {
00061     NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
00062     NS_ADDREF(aAtom);
00063   }
00064 
00065   explicit nsAttrName(nsINodeInfo* aNodeInfo)
00066   {
00067     NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
00068     if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
00069       mBits = NS_REINTERPRET_CAST(PtrBits, aNodeInfo->NameAtom());
00070       NS_ADDREF(aNodeInfo->NameAtom());
00071     }
00072     else {
00073       mBits = NS_REINTERPRET_CAST(PtrBits, aNodeInfo) |
00074               NS_ATTRNAME_NODEINFO_BIT;
00075       NS_ADDREF(aNodeInfo);
00076     }
00077   }
00078 
00079   ~nsAttrName()
00080   {
00081     ReleaseInternalName();
00082   }
00083 
00084   void SetTo(nsINodeInfo* aNodeInfo)
00085   {
00086     NS_ASSERTION(aNodeInfo, "null nodeinfo-name in nsAttrName");
00087 
00088     ReleaseInternalName();
00089     if (aNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
00090       mBits = NS_REINTERPRET_CAST(PtrBits, aNodeInfo->NameAtom());
00091       NS_ADDREF(aNodeInfo->NameAtom());
00092     }
00093     else {
00094       mBits = NS_REINTERPRET_CAST(PtrBits, aNodeInfo) |
00095               NS_ATTRNAME_NODEINFO_BIT;
00096       NS_ADDREF(aNodeInfo);
00097     }
00098   }
00099 
00100   void SetTo(nsIAtom* aAtom)
00101   {
00102     NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
00103 
00104     ReleaseInternalName();
00105     mBits = NS_REINTERPRET_CAST(PtrBits, aAtom);
00106     NS_ADDREF(aAtom);
00107   }
00108 
00109   PRBool IsAtom() const
00110   {
00111     return !(mBits & NS_ATTRNAME_NODEINFO_BIT);
00112   }
00113 
00114   nsINodeInfo* NodeInfo() const
00115   {
00116     NS_ASSERTION(!IsAtom(), "getting nodeinfo-value of atom-name");
00117     return NS_REINTERPRET_CAST(nsINodeInfo*, mBits & ~NS_ATTRNAME_NODEINFO_BIT);
00118   }
00119 
00120   nsIAtom* Atom() const
00121   {
00122     NS_ASSERTION(IsAtom(), "getting atom-value of nodeinfo-name");
00123     return NS_REINTERPRET_CAST(nsIAtom*, mBits);
00124   }
00125 
00126   PRBool Equals(const nsAttrName& aOther) const
00127   {
00128     return mBits == aOther.mBits;
00129   }
00130 
00131   // Faster comparison in the case we know the namespace is null
00132   PRBool Equals(nsIAtom* aAtom) const
00133   {
00134     return NS_REINTERPRET_CAST(PtrBits, aAtom) == mBits;
00135   }
00136 
00137   PRBool Equals(nsIAtom* aLocalName, PRInt32 aNamespaceID) const
00138   {
00139     if (aNamespaceID == kNameSpaceID_None) {
00140       return Equals(aLocalName);
00141     }
00142     return !IsAtom() && NodeInfo()->Equals(aLocalName, aNamespaceID);
00143   }
00144 
00145   PRInt32 NamespaceID() const
00146   {
00147     return IsAtom() ? kNameSpaceID_None : NodeInfo()->NamespaceID();
00148   }
00149 
00150   nsIAtom* LocalName() const
00151   {
00152     return IsAtom() ? Atom() : NodeInfo()->NameAtom();
00153   }
00154 
00155   nsIAtom* GetPrefix() const
00156   {
00157     return IsAtom() ? nsnull : NodeInfo()->GetPrefixAtom();
00158   }
00159 
00160   PRBool QualifiedNameEquals(const nsACString& aName) const
00161   {
00162     return IsAtom() ? Atom()->EqualsUTF8(aName) :
00163                       NodeInfo()->QualifiedNameEquals(aName);
00164   }
00165 
00166   void GetQualifiedName(nsAString& aStr) const
00167   {
00168     if (IsAtom()) {
00169       Atom()->ToString(aStr);
00170     }
00171     else {
00172       NodeInfo()->GetQualifiedName(aStr);
00173     }
00174   }
00175 
00176   void GetPrefix(nsAString& aStr) const
00177   {
00178     if (IsAtom()) {
00179       SetDOMStringToNull(aStr);
00180     }
00181     else {
00182       NodeInfo()->GetPrefix(aStr);
00183     }
00184   }
00185 
00186   PRUint32 HashValue() const
00187   {
00188     // mBits and PRUint32 might have different size. This should silence
00189     // any warnings or compile-errors. This is what the implementation of
00190     // NS_PTR_TO_INT32 does to take care of the same problem.
00191     return mBits - 0;
00192   }
00193 
00194   PRBool IsSmaller(nsIAtom* aOther) const
00195   {
00196     return mBits < NS_REINTERPRET_CAST(PtrBits, aOther);
00197   }
00198 
00199 private:
00200 
00201   void AddRefInternalName()
00202   {
00203     // Since both nsINodeInfo and nsIAtom inherit nsISupports as its first
00204     // interface we can safely assume that it's first in the vtable
00205     nsISupports* name = NS_REINTERPRET_CAST(nsISupports *,
00206       mBits & ~NS_ATTRNAME_NODEINFO_BIT);
00207 
00208     NS_ADDREF(name);
00209   }
00210 
00211   void ReleaseInternalName()
00212   {
00213     // Since both nsINodeInfo and nsIAtom inherit nsISupports as its first
00214     // interface we can safely assume that it's first in the vtable
00215     nsISupports* name = NS_REINTERPRET_CAST(nsISupports *,
00216       mBits & ~NS_ATTRNAME_NODEINFO_BIT);
00217 
00218     NS_RELEASE(name);
00219   }
00220 
00221   PtrBits mBits;
00222 };
00223 
00224 #endif