Back to index

lightning-sunbird  0.9+nobinonly
txXPathTreeWalker.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 TransforMiiX XSLT processor code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2003
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Peter Van der Beken <peterv@propagandism.org>
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 txXPathTreeWalker_h__
00040 #define txXPathTreeWalker_h__
00041 
00042 #include "txCore.h"
00043 #include "txXPathNode.h"
00044 
00045 class nsIAtom;
00046 
00047 #ifndef TX_EXE
00048 #include "nsINodeInfo.h"
00049 #include "nsVoidArray.h"
00050 
00051 class txUint32Array : public nsVoidArray
00052 {
00053 public:
00054     PRBool AppendValue(PRUint32 aValue)
00055     {
00056         return InsertElementAt(NS_INT32_TO_PTR(aValue), Count());
00057     }
00058     PRBool RemoveValueAt(PRUint32 aIndex)
00059     {
00060         return RemoveElementsAt(aIndex, 1);
00061     }
00062     PRInt32 ValueAt(PRUint32 aIndex) const
00063     {
00064         return NS_PTR_TO_INT32(ElementAt(aIndex));
00065     }
00066 };
00067 
00068 class nsIDOMDocument;
00069 #endif
00070 
00071 class txXPathTreeWalker
00072 {
00073 public:
00074     txXPathTreeWalker(const txXPathTreeWalker& aOther);
00075     explicit txXPathTreeWalker(const txXPathNode& aNode);
00076     ~txXPathTreeWalker();
00077 
00078     PRBool getAttr(nsIAtom* aLocalName, PRInt32 aNSID, nsAString& aValue) const;
00079     PRInt32 getNamespaceID() const;
00080     PRUint16 getNodeType() const;
00081     void appendNodeValue(nsAString& aResult) const;
00082     void getNodeName(nsAString& aName) const;
00083 
00084     void moveTo(const txXPathTreeWalker& aWalker);
00085 
00086     PRBool moveToParent();
00087     PRBool moveToElementById(const nsAString& aID);
00088     PRBool moveToFirstAttribute();
00089     PRBool moveToNextAttribute();
00090     PRBool moveToFirstChild();
00091     PRBool moveToLastChild();
00092     PRBool moveToNextSibling();
00093     PRBool moveToPreviousSibling();
00094 
00095     PRBool isOnNode(const txXPathNode& aNode) const;
00096 
00097     const txXPathNode& getCurrentPosition() const;
00098 
00099 private:
00100     txXPathNode mPosition;
00101 
00102 #ifndef TX_EXE
00103     PRBool moveToValidAttribute(PRUint32 aStartIndex);
00104     PRBool moveToSibling(PRInt32 aDir);
00105 
00106     PRUint32 mCurrentIndex;
00107     txUint32Array mDescendants;
00108 #endif
00109 };
00110 
00111 class txXPathNodeUtils
00112 {
00113 public:
00114     static PRBool getAttr(const txXPathNode& aNode, nsIAtom* aLocalName,
00115                           PRInt32 aNSID, nsAString& aValue);
00116     static already_AddRefed<nsIAtom> getLocalName(const txXPathNode& aNode);
00117     static void getLocalName(const txXPathNode& aNode, nsAString& aLocalName);
00118     static void getNodeName(const txXPathNode& aNode,
00119                             nsAString& aName);
00120     static PRInt32 getNamespaceID(const txXPathNode& aNode);
00121     static void getNamespaceURI(const txXPathNode& aNode, nsAString& aURI);
00122     static PRUint16 getNodeType(const txXPathNode& aNode);
00123     static void appendNodeValue(const txXPathNode& aNode, nsAString& aResult);
00124     static PRBool isWhitespace(const txXPathNode& aNode);
00125     static txXPathNode* getDocument(const txXPathNode& aNode);
00126     static txXPathNode* getOwnerDocument(const txXPathNode& aNode);
00127     static PRInt32 getUniqueIdentifier(const txXPathNode& aNode);
00128     static nsresult getXSLTId(const txXPathNode& aNode, nsAString& aResult);
00129     static void release(txXPathNode* aNode);
00130     static void getBaseURI(const txXPathNode& aNode, nsAString& aURI);
00131     static PRIntn comparePosition(const txXPathNode& aNode,
00132                                   const txXPathNode& aOtherNode);
00133     static PRBool localNameEquals(const txXPathNode& aNode,
00134                                   nsIAtom* aLocalName);
00135     static PRBool isRoot(const txXPathNode& aNode);
00136     static PRBool isElement(const txXPathNode& aNode);
00137     static PRBool isAttribute(const txXPathNode& aNode);
00138     static PRBool isProcessingInstruction(const txXPathNode& aNode);
00139     static PRBool isComment(const txXPathNode& aNode);
00140     static PRBool isText(const txXPathNode& aNode);
00141 
00142 #ifdef TX_EXE
00143 private:
00144     static void appendNodeValueHelper(NodeDefinition* aNode, nsAString& aResult);
00145 #endif
00146 };
00147 
00148 #ifdef TX_EXE
00149 class txXPathNativeNode
00150 {
00151 public:
00152     static txXPathNode* createXPathNode(Node* aNode);
00153     static nsresult getElement(const txXPathNode& aNode, Element** aResult);
00154     static nsresult getDocument(const txXPathNode& aNode, Document** aResult);
00155 };
00156 #else
00157 class txXPathNativeNode
00158 {
00159 public:
00160     static txXPathNode* createXPathNode(nsIDOMNode* aNode);
00161     static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
00162     static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult);
00163     static nsIContent* getContent(const txXPathNode& aNode);
00164     static nsIDocument* getDocument(const txXPathNode& aNode);
00165     static void addRef(const txXPathNode& aNode)
00166     {
00167         // Hopefully it's ok to access mContent through mDocument.
00168         NS_ADDREF(aNode.mDocument);
00169     }
00170     static void release(const txXPathNode& aNode)
00171     {
00172         // Hopefully it's ok to access mContent through mDocument.
00173         nsISupports *node = aNode.mDocument;
00174         NS_RELEASE(node);
00175     }
00176 };
00177 
00178 #endif
00179 
00180 inline const txXPathNode&
00181 txXPathTreeWalker::getCurrentPosition() const
00182 {
00183     return mPosition;
00184 }
00185 
00186 inline PRBool
00187 txXPathTreeWalker::getAttr(nsIAtom* aLocalName, PRInt32 aNSID,
00188                            nsAString& aValue) const
00189 {
00190     return txXPathNodeUtils::getAttr(mPosition, aLocalName, aNSID, aValue);
00191 }
00192 
00193 inline PRInt32
00194 txXPathTreeWalker::getNamespaceID() const
00195 {
00196     return txXPathNodeUtils::getNamespaceID(mPosition);
00197 }
00198 
00199 inline void
00200 txXPathTreeWalker::appendNodeValue(nsAString& aResult) const
00201 {
00202     txXPathNodeUtils::appendNodeValue(mPosition, aResult);
00203 }
00204 
00205 inline void
00206 txXPathTreeWalker::getNodeName(nsAString& aName) const
00207 {
00208     txXPathNodeUtils::getNodeName(mPosition, aName);
00209 }
00210 
00211 inline void
00212 txXPathTreeWalker::moveTo(const txXPathTreeWalker& aWalker)
00213 {
00214 #ifdef TX_EXE
00215     mPosition.mInner = aWalker.mPosition.mInner;
00216 #else
00217     mPosition.mIndex = aWalker.mPosition.mIndex;
00218     // Hopefully it's ok to access mContent through mDocument.
00219     mPosition.mDocument = aWalker.mPosition.mDocument;
00220     mCurrentIndex = aWalker.mCurrentIndex;
00221     mDescendants.Clear();
00222 #endif
00223 }
00224 
00225 inline PRBool
00226 txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const
00227 {
00228     return (mPosition == aNode);
00229 }
00230 
00231 /* static */
00232 inline PRInt32
00233 txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode)
00234 {
00235 #ifdef TX_EXE
00236     return NS_PTR_TO_INT32(aNode.mInner);
00237 #else
00238     NS_PRECONDITION(aNode.mIndex == txXPathNode::eDocument,
00239                     "Only implemented for documents.");
00240     return NS_PTR_TO_INT32(aNode.mDocument);
00241 #endif
00242 }
00243 
00244 /* static */
00245 inline void
00246 txXPathNodeUtils::release(txXPathNode* aNode)
00247 {
00248 #ifdef TX_EXE
00249     delete aNode->mInner;
00250 #else
00251     NS_RELEASE(aNode->mDocument);
00252 #endif
00253 }
00254 
00255 /* static */
00256 inline PRBool
00257 txXPathNodeUtils::localNameEquals(const txXPathNode& aNode,
00258                                   nsIAtom* aLocalName)
00259 {
00260 #ifdef TX_EXE
00261     nsCOMPtr<nsIAtom> localName;
00262     aNode.mInner->getLocalName(getter_AddRefs(localName));
00263 
00264     return localName == aLocalName;
00265 #else
00266     if (aNode.isContent()) {
00267         nsINodeInfo *ni = aNode.mContent->GetNodeInfo();
00268         if (ni) {
00269             return ni->Equals(aLocalName);
00270         }
00271     }
00272 
00273     nsCOMPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
00274 
00275     return localName == aLocalName;
00276 #endif
00277 }
00278 
00279 /* static */
00280 inline PRBool
00281 txXPathNodeUtils::isRoot(const txXPathNode& aNode)
00282 {
00283 #ifdef TX_EXE
00284     return aNode.mInner->getNodeType() == Node::DOCUMENT_NODE;
00285 #else
00286     return aNode.isDocument();
00287 #endif
00288 }
00289 
00290 /* static */
00291 inline PRBool
00292 txXPathNodeUtils::isElement(const txXPathNode& aNode)
00293 {
00294 #ifdef TX_EXE
00295     return aNode.mInner->getNodeType() == Node::ELEMENT_NODE;
00296 #else
00297     return aNode.isContent() &&
00298            aNode.mContent->IsContentOfType(nsIContent::eELEMENT);
00299 #endif
00300 }
00301 
00302 
00303 /* static */
00304 inline PRBool
00305 txXPathNodeUtils::isAttribute(const txXPathNode& aNode)
00306 {
00307 #ifdef TX_EXE
00308     return aNode.mInner->getNodeType() == Node::ATTRIBUTE_NODE;
00309 #else
00310     return aNode.isAttribute();
00311 #endif
00312 }
00313 
00314 /* static */
00315 inline PRBool
00316 txXPathNodeUtils::isProcessingInstruction(const txXPathNode& aNode)
00317 {
00318 #ifdef TX_EXE
00319     return aNode.mInner->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE;
00320 #else
00321     return aNode.isContent() &&
00322            aNode.mContent->IsContentOfType(nsIContent::ePROCESSING_INSTRUCTION);
00323 #endif
00324 }
00325 
00326 /* static */
00327 inline PRBool
00328 txXPathNodeUtils::isComment(const txXPathNode& aNode)
00329 {
00330 #ifdef TX_EXE
00331     return aNode.mInner->getNodeType() == Node::COMMENT_NODE;
00332 #else
00333     return aNode.isContent() &&
00334            aNode.mContent->IsContentOfType(nsIContent::eCOMMENT);
00335 #endif
00336 }
00337 
00338 /* static */
00339 inline PRBool
00340 txXPathNodeUtils::isText(const txXPathNode& aNode)
00341 {
00342 #ifdef TX_EXE
00343     return aNode.mInner->getNodeType() == Node::TEXT_NODE;
00344 #else
00345     return aNode.isContent() &&
00346            aNode.mContent->IsContentOfType(nsIContent::eTEXT);
00347 #endif
00348 }
00349 
00350 #endif /* txXPathTreeWalker_h__ */