dom/xslt/xpath/txExpr.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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 #ifndef TRANSFRMX_EXPR_H
     7 #define TRANSFRMX_EXPR_H
     9 #include "mozilla/Attributes.h"
    10 #include "nsAutoPtr.h"
    11 #include "txExprResult.h"
    12 #include "txCore.h"
    13 #include "nsString.h"
    14 #include "txOwningArray.h"
    15 #include "nsIAtom.h"
    17 #ifdef DEBUG
    18 #define TX_TO_STRING
    19 #endif
    21 /*
    22   XPath class definitions.
    23   Much of this code was ported from XSL:P.
    24 */
    26 class nsIAtom;
    27 class txIParseContext;
    28 class txIMatchContext;
    29 class txIEvalContext;
    30 class txNodeSet;
    31 class txXPathNode;
    33 /**
    34  * A Base Class for all XSL Expressions
    35 **/
    36 class Expr
    37 {
    38 public:
    39     Expr()
    40     {
    41         MOZ_COUNT_CTOR(Expr);
    42     }
    43     virtual ~Expr()
    44     {
    45         MOZ_COUNT_DTOR(Expr);
    46     }
    48     /**
    49      * Evaluates this Expr based on the given context node and processor state
    50      * @param context the context node for evaluation of this Expr
    51      * @param ps the ContextState containing the stack information needed
    52      * for evaluation
    53      * @return the result of the evaluation
    54     **/
    55     virtual nsresult evaluate(txIEvalContext* aContext,
    56                               txAExprResult** aResult) = 0;
    59     /**
    60      * Returns the type of this expression.
    61      */
    62     enum ExprType {
    63         LOCATIONSTEP_EXPR,
    64         PATH_EXPR,
    65         UNION_EXPR,
    66         LITERAL_EXPR,
    67         OTHER_EXPR
    68     };
    69     virtual ExprType getType()
    70     {
    71       return OTHER_EXPR;
    72     }
    74     /**
    75      * Returns the type or types of results this Expr return.
    76      */
    77     typedef uint16_t ResultType;
    78     enum {
    79         NODESET_RESULT = 0x01,
    80         BOOLEAN_RESULT = 0x02,
    81         NUMBER_RESULT = 0x04,
    82         STRING_RESULT = 0x08,
    83         RTF_RESULT = 0x10,
    84         ANY_RESULT = 0xFFFF
    85     };
    86     virtual ResultType getReturnType() = 0;
    87     bool canReturnType(ResultType aType)
    88     {
    89         return (getReturnType() & aType) != 0;
    90     }
    92     typedef uint16_t ContextSensitivity;
    93     enum {
    94         NO_CONTEXT = 0x00,
    95         NODE_CONTEXT = 0x01,
    96         POSITION_CONTEXT = 0x02,
    97         SIZE_CONTEXT = 0x04,
    98         NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT,
    99         VARIABLES_CONTEXT = 0x08,
   100         PRIVATE_CONTEXT = 0x10,
   101         ANY_CONTEXT = 0xFFFF
   102     };
   104     /**
   105      * Returns true if this expression is sensitive to *any* of
   106      * the requested contexts in aContexts.
   107      */
   108     virtual bool isSensitiveTo(ContextSensitivity aContexts) = 0;
   110     /**
   111      * Returns sub-expression at given position
   112      */
   113     virtual Expr* getSubExprAt(uint32_t aPos) = 0;
   115     /**
   116      * Replace sub-expression at given position. Does not delete the old
   117      * expression, that is the responsibility of the caller.
   118      */
   119     virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0;
   121     virtual nsresult evaluateToBool(txIEvalContext* aContext,
   122                                     bool& aResult);
   124     virtual nsresult evaluateToString(txIEvalContext* aContext,
   125                                       nsString& aResult);
   127 #ifdef TX_TO_STRING
   128     /**
   129      * Returns the String representation of this Expr.
   130      * @param dest the String to use when creating the String
   131      * representation. The String representation will be appended to
   132      * any data in the destination String, to allow cascading calls to
   133      * other #toString() methods for Expressions.
   134      * @return the String representation of this Expr.
   135     **/
   136     virtual void toString(nsAString& str) = 0;
   137 #endif
   138 }; //-- Expr
   140 #ifdef TX_TO_STRING
   141 #define TX_DECL_TOSTRING \
   142     void toString(nsAString& aDest);
   143 #define TX_DECL_GETNAMEATOM \
   144     nsresult getNameAtom(nsIAtom** aAtom);
   145 #else
   146 #define TX_DECL_TOSTRING
   147 #define TX_DECL_GETNAMEATOM
   148 #endif
   150 #define TX_DECL_EXPR_BASE \
   151     nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \
   152     ResultType getReturnType(); \
   153     bool isSensitiveTo(ContextSensitivity aContexts);
   155 #define TX_DECL_EXPR \
   156     TX_DECL_EXPR_BASE \
   157     TX_DECL_TOSTRING \
   158     Expr* getSubExprAt(uint32_t aPos); \
   159     void setSubExprAt(uint32_t aPos, Expr* aExpr);
   161 #define TX_DECL_OPTIMIZABLE_EXPR \
   162     TX_DECL_EXPR \
   163     ExprType getType();
   166 #define TX_DECL_FUNCTION \
   167     TX_DECL_GETNAMEATOM \
   168     TX_DECL_EXPR_BASE
   170 #define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)          \
   171 Expr::ResultType                                              \
   172 _class::getReturnType()                                       \
   173 {                                                             \
   174     return _ReturnType;                                       \
   175 }
   177 #define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType)             \
   178 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   179 Expr*                                                         \
   180 _class::getSubExprAt(uint32_t aPos)                           \
   181 {                                                             \
   182     return nullptr;                                            \
   183 }                                                             \
   184 void                                                          \
   185 _class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   186 {                                                             \
   187     NS_NOTREACHED("setting bad subexpression index");         \
   188 }
   190 #define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1)     \
   191 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   192 Expr*                                                         \
   193 _class::getSubExprAt(uint32_t aPos)                           \
   194 {                                                             \
   195     if (aPos == 0) {                                          \
   196         return _Expr1;                                        \
   197     }                                                         \
   198     return nullptr;                                            \
   199 }                                                             \
   200 void                                                          \
   201 _class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   202 {                                                             \
   203     NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
   204     _Expr1.forget();                                          \
   205     _Expr1 = aExpr;                                           \
   206 }
   208 #define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
   209 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   210 Expr*                                                         \
   211 _class::getSubExprAt(uint32_t aPos)                           \
   212 {                                                             \
   213     switch(aPos) {                                            \
   214         case 0:                                               \
   215             return _Expr1;                                    \
   216         case 1:                                               \
   217             return _Expr2;                                    \
   218         default:                                              \
   219             break;                                            \
   220     }                                                         \
   221     return nullptr;                                            \
   222 }                                                             \
   223 void                                                          \
   224 _class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   225 {                                                             \
   226     NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
   227     if (aPos == 0) {                                          \
   228         _Expr1.forget();                                      \
   229         _Expr1 = aExpr;                                       \
   230     }                                                         \
   231     else {                                                    \
   232         _Expr2.forget();                                      \
   233         _Expr2 = aExpr;                                       \
   234     }                                                         \
   235 }
   237 #define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
   238 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   239 Expr*                                                         \
   240 _class::getSubExprAt(uint32_t aPos)                           \
   241 {                                                             \
   242     return _ExprList.SafeElementAt(aPos);                     \
   243 }                                                             \
   244 void                                                          \
   245 _class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   246 {                                                             \
   247     NS_ASSERTION(aPos < _ExprList.Length(),                   \
   248                  "setting bad subexpression index");          \
   249     _ExprList[aPos] = aExpr;                                  \
   250 }
   253 /**
   254  * This class represents a FunctionCall as defined by the XPath 1.0
   255  * Recommendation.
   256 **/
   257 class FunctionCall : public Expr
   258 {
   259 public:
   260     /**
   261      * Adds the given parameter to this FunctionCall's parameter list.
   262      * The ownership of the given Expr is passed over to the FunctionCall,
   263      * even on failure.
   264      * @param aExpr the Expr to add to this FunctionCall's parameter list
   265      * @return nsresult indicating out of memory
   266      */
   267     nsresult addParam(Expr* aExpr)
   268     {
   269         return mParams.AppendElement(aExpr) ?
   270             NS_OK : NS_ERROR_OUT_OF_MEMORY;
   271     }
   273     /**
   274      * Check if the number of parameters falls within a range.
   275      *
   276      * @param aParamCountMin minimum number of required parameters.
   277      * @param aParamCountMax maximum number of parameters. If aParamCountMax
   278      *                       is negative the maximum number is not checked.
   279      * @return boolean representing whether the number of parameters falls
   280      *         within the expected range or not.
   281      *
   282      * XXX txIEvalContext should be txIParseContest, bug 143291
   283      */
   284     virtual bool requireParams(int32_t aParamCountMin,
   285                                  int32_t aParamCountMax,
   286                                  txIEvalContext* aContext);
   288     TX_DECL_TOSTRING
   289     Expr* getSubExprAt(uint32_t aPos) MOZ_OVERRIDE;
   290     void setSubExprAt(uint32_t aPos, Expr* aExpr) MOZ_OVERRIDE;
   292 protected:
   294     txOwningArray<Expr> mParams;
   296     /*
   297      * Evaluates the given Expression and converts its result to a number.
   298      */
   299     static nsresult evaluateToNumber(Expr* aExpr, txIEvalContext* aContext,
   300                                      double* aResult);
   302     /*
   303      * Evaluates the given Expression and converts its result to a NodeSet.
   304      * If the result is not a NodeSet an error is returned.
   305      */
   306     static nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext,
   307                                       txNodeSet** aResult);
   309     /**
   310      * Returns true if any argument is sensitive to the given context.
   311      */
   312     bool argsSensitiveTo(ContextSensitivity aContexts);
   315 #ifdef TX_TO_STRING
   316     /*
   317      * Returns the name of the function as an atom.
   318      */
   319     virtual nsresult getNameAtom(nsIAtom** aAtom) = 0;
   320 #endif
   321 };
   323 class txCoreFunctionCall : public FunctionCall
   324 {
   325 public:
   327     // This must be ordered in the same order as descriptTable in
   328     // txCoreFunctionCall.cpp. If you change one, change the other.
   329     enum eType {
   330         COUNT = 0,         // count()
   331         ID,                // id()
   332         LAST,              // last()
   333         LOCAL_NAME,        // local-name()
   334         NAMESPACE_URI,     // namespace-uri()
   335         NAME,              // name()
   336         POSITION,          // position()
   338         CONCAT,            // concat()
   339         CONTAINS,          // contains()
   340         NORMALIZE_SPACE,   // normalize-space()
   341         STARTS_WITH,       // starts-with()
   342         STRING,            // string()
   343         STRING_LENGTH,     // string-length()
   344         SUBSTRING,         // substring()
   345         SUBSTRING_AFTER,   // substring-after()
   346         SUBSTRING_BEFORE,  // substring-before()
   347         TRANSLATE,         // translate()
   349         NUMBER,            // number()
   350         ROUND,             // round()
   351         FLOOR,             // floor()
   352         CEILING,           // ceiling()
   353         SUM,               // sum()
   355         BOOLEAN,           // boolean()
   356         _FALSE,            // false()
   357         LANG,              // lang()
   358         _NOT,              // not()
   359         _TRUE              // true()
   360     };
   362     /*
   363      * Creates a txCoreFunctionCall of the given type
   364      */
   365     txCoreFunctionCall(eType aType) : mType(aType)
   366     {
   367     }
   369     TX_DECL_FUNCTION
   371     static bool getTypeFromAtom(nsIAtom* aName, eType& aType);
   373 private:
   374     eType mType;
   375 };
   378 /*
   379  * This class represents a NodeTest as defined by the XPath spec
   380  */
   381 class txNodeTest
   382 {
   383 public:
   384     txNodeTest()
   385     {
   386         MOZ_COUNT_CTOR(txNodeTest);
   387     }
   388     virtual ~txNodeTest()
   389     {
   390         MOZ_COUNT_DTOR(txNodeTest);
   391     }
   393     /*
   394      * Virtual methods
   395      * pretty much a txPattern, but not supposed to be used 
   396      * standalone. The NodeTest node() is different to the
   397      * Pattern "node()" (document node isn't matched)
   398      */
   399     virtual bool matches(const txXPathNode& aNode,
   400                            txIMatchContext* aContext) = 0;
   401     virtual double getDefaultPriority() = 0;
   403     /**
   404      * Returns the type of this nodetest.
   405      */
   406     enum NodeTestType {
   407         NAME_TEST,
   408         NODETYPE_TEST,
   409         OTHER_TEST
   410     };
   411     virtual NodeTestType getType()
   412     {
   413       return OTHER_TEST;
   414     }
   416     /**
   417      * Returns true if this expression is sensitive to *any* of
   418      * the requested flags.
   419      */
   420     virtual bool isSensitiveTo(Expr::ContextSensitivity aContext) = 0;
   422 #ifdef TX_TO_STRING
   423     virtual void toString(nsAString& aDest) = 0;
   424 #endif
   425 };
   427 #define TX_DECL_NODE_TEST \
   428     TX_DECL_TOSTRING \
   429     bool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
   430     double getDefaultPriority(); \
   431     bool isSensitiveTo(Expr::ContextSensitivity aContext);
   433 /*
   434  * This class represents a NameTest as defined by the XPath spec
   435  */
   436 class txNameTest : public txNodeTest
   437 {
   438 public:
   439     /*
   440      * Creates a new txNameTest with the given type and the given
   441      * principal node type
   442      */
   443     txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID,
   444                uint16_t aNodeType);
   446     NodeTestType getType() MOZ_OVERRIDE;
   448     TX_DECL_NODE_TEST
   450     nsCOMPtr<nsIAtom> mPrefix;
   451     nsCOMPtr<nsIAtom> mLocalName;
   452     int32_t mNamespace;
   453 private:
   454     uint16_t mNodeType;
   455 };
   457 /*
   458  * This class represents a NodeType as defined by the XPath spec
   459  */
   460 class txNodeTypeTest : public txNodeTest
   461 {
   462 public:
   463     enum NodeType {
   464         COMMENT_TYPE,
   465         TEXT_TYPE,
   466         PI_TYPE,
   467         NODE_TYPE
   468     };
   470     /*
   471      * Creates a new txNodeTypeTest of the given type
   472      */
   473     txNodeTypeTest(NodeType aNodeType)
   474         : mNodeType(aNodeType)
   475     {
   476     }
   478     /*
   479      * Sets the name of the node to match. Only availible for pi nodes
   480      */
   481     void setNodeName(const nsAString& aName)
   482     {
   483         mNodeName = do_GetAtom(aName);
   484     }
   486     NodeType getNodeTestType()
   487     {
   488         return mNodeType;
   489     }
   491     NodeTestType getType() MOZ_OVERRIDE;
   493     TX_DECL_NODE_TEST
   495 private:
   496     NodeType mNodeType;
   497     nsCOMPtr<nsIAtom> mNodeName;
   498 };
   500 /**
   501  * Class representing a nodetest combined with a predicate. May only be used
   502  * if the predicate is not sensitive to the context-nodelist.
   503  */
   504 class txPredicatedNodeTest : public txNodeTest
   505 {
   506 public:
   507     txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate);
   508     TX_DECL_NODE_TEST
   510 private:
   511     nsAutoPtr<txNodeTest> mNodeTest;
   512     nsAutoPtr<Expr> mPredicate;
   513 };
   515 /**
   516  * Represents an ordered list of Predicates,
   517  * for use with Step and Filter Expressions
   518 **/
   519 class PredicateList  {
   520 public:
   521     /**
   522      * Adds the given Expr to the list.
   523      * The ownership of the given Expr is passed over the PredicateList,
   524      * even on failure.
   525      * @param aExpr the Expr to add to the list
   526      * @return nsresult indicating out of memory
   527      */
   528     nsresult add(Expr* aExpr)
   529     {
   530         NS_ASSERTION(aExpr, "missing expression");
   531         return mPredicates.AppendElement(aExpr) ?
   532             NS_OK : NS_ERROR_OUT_OF_MEMORY;
   533     }
   535     nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
   537     /**
   538      * Drops the first predicate without deleting it.
   539      */
   540     void dropFirst()
   541     {
   542         mPredicates.RemoveElementAt(0);
   543     }
   545     /**
   546      * returns true if this predicate list is empty
   547     **/
   548     bool isEmpty()
   549     {
   550         return mPredicates.IsEmpty();
   551     }
   553 #ifdef TX_TO_STRING
   554     /**
   555      * Returns the String representation of this PredicateList.
   556      * @param dest the String to use when creating the String
   557      * representation. The String representation will be appended to
   558      * any data in the destination String, to allow cascading calls to
   559      * other #toString() methods for Expressions.
   560      * @return the String representation of this PredicateList.
   561     **/
   562     void toString(nsAString& dest);
   563 #endif
   565 protected:
   566     bool isSensitiveTo(Expr::ContextSensitivity aContext);
   567     Expr* getSubExprAt(uint32_t aPos)
   568     {
   569         return mPredicates.SafeElementAt(aPos);
   570     }
   571     void setSubExprAt(uint32_t aPos, Expr* aExpr)
   572     {
   573         NS_ASSERTION(aPos < mPredicates.Length(),
   574                      "setting bad subexpression index");
   575         mPredicates[aPos] = aExpr;
   576     }
   578     //-- list of predicates
   579     txOwningArray<Expr> mPredicates;
   580 }; //-- PredicateList
   582 class LocationStep : public Expr,
   583                      public PredicateList
   584 {
   585 public:
   586     enum LocationStepType {
   587         ANCESTOR_AXIS = 0,
   588         ANCESTOR_OR_SELF_AXIS,
   589         ATTRIBUTE_AXIS,
   590         CHILD_AXIS,
   591         DESCENDANT_AXIS,
   592         DESCENDANT_OR_SELF_AXIS,
   593         FOLLOWING_AXIS,
   594         FOLLOWING_SIBLING_AXIS,
   595         NAMESPACE_AXIS,
   596         PARENT_AXIS,
   597         PRECEDING_AXIS,
   598         PRECEDING_SIBLING_AXIS,
   599         SELF_AXIS
   600     };
   602     /**
   603      * Creates a new LocationStep using the given NodeExpr and Axis Identifier
   604      * @param nodeExpr the NodeExpr to use when matching Nodes
   605      * @param axisIdentifier the Axis Identifier in which to search for nodes
   606     **/
   607     LocationStep(txNodeTest* aNodeTest,
   608                  LocationStepType aAxisIdentifier)
   609         : mNodeTest(aNodeTest),
   610           mAxisIdentifier(aAxisIdentifier)
   611     {
   612     }
   614     TX_DECL_OPTIMIZABLE_EXPR
   616     txNodeTest* getNodeTest()
   617     {
   618         return mNodeTest;
   619     }
   620     void setNodeTest(txNodeTest* aNodeTest)
   621     {
   622         mNodeTest.forget();
   623         mNodeTest = aNodeTest;
   624     }
   625     LocationStepType getAxisIdentifier()
   626     {
   627         return mAxisIdentifier;
   628     }
   629     void setAxisIdentifier(LocationStepType aAxisIdentifier)
   630     {
   631         mAxisIdentifier = aAxisIdentifier;
   632     }
   634 private:
   635     void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs,
   636                          txNodeSet* aNodes);
   637     void fromDescendantsRev(const txXPathNode& aNode, txIMatchContext* aCs,
   638                             txNodeSet* aNodes);
   640     nsAutoPtr<txNodeTest> mNodeTest;
   641     LocationStepType mAxisIdentifier;
   642 };
   644 class FilterExpr : public Expr,
   645                    public PredicateList
   646 {
   647 public:
   649     /**
   650      * Creates a new FilterExpr using the given Expr
   651      * @param expr the Expr to use for evaluation
   652      */
   653     FilterExpr(Expr* aExpr)
   654         : expr(aExpr)
   655     {
   656     }
   658     TX_DECL_EXPR
   660 private:
   661     nsAutoPtr<Expr> expr;
   663 }; //-- FilterExpr
   666 class txLiteralExpr : public Expr {
   667 public:
   668     txLiteralExpr(double aDbl)
   669         : mValue(new NumberResult(aDbl, nullptr))
   670     {
   671     }
   672     txLiteralExpr(const nsAString& aStr)
   673         : mValue(new StringResult(aStr, nullptr))
   674     {
   675     }
   676     txLiteralExpr(txAExprResult* aValue)
   677         : mValue(aValue)
   678     {
   679     }
   681     TX_DECL_EXPR
   683 private:
   684     nsRefPtr<txAExprResult> mValue;
   685 };
   687 /**
   688  * Represents an UnaryExpr. Returns the negative value of its expr.
   689 **/
   690 class UnaryExpr : public Expr {
   692 public:
   694     UnaryExpr(Expr* aExpr)
   695         : expr(aExpr)
   696     {
   697     }
   699     TX_DECL_EXPR
   701 private:
   702     nsAutoPtr<Expr> expr;
   703 }; //-- UnaryExpr
   705 /**
   706  * Represents a BooleanExpr, a binary expression that
   707  * performs a boolean operation between its lvalue and rvalue.
   708 **/
   709 class BooleanExpr : public Expr
   710 {
   711 public:
   713     //-- BooleanExpr Types
   714     enum _BooleanExprType { AND = 1, OR };
   716      BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
   717          : leftExpr(aLeftExpr),
   718            rightExpr(aRightExpr),
   719            op(aOp)
   720     {
   721     }
   723     TX_DECL_EXPR
   725 private:
   726     nsAutoPtr<Expr> leftExpr, rightExpr;
   727     short op;
   728 }; //-- BooleanExpr
   730 /**
   731  * Represents a MultiplicativeExpr, a binary expression that
   732  * performs a multiplicative operation between its lvalue and rvalue:
   733  *  *   : multiply
   734  * mod  : modulus
   735  * div  : divide
   736  *
   737 **/
   738 class txNumberExpr : public Expr
   739 {
   740 public:
   742     enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
   744     txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
   745         : mLeftExpr(aLeftExpr),
   746           mRightExpr(aRightExpr),
   747           mOp(aOp)
   748     {
   749     }
   751     TX_DECL_EXPR
   753 private:
   754     nsAutoPtr<Expr> mLeftExpr, mRightExpr;
   755     eOp mOp;
   756 }; //-- MultiplicativeExpr
   758 /**
   759  * Represents a RelationalExpr, an expression that compares its lvalue
   760  * to its rvalue using:
   761  * =  : equal to
   762  * <  : less than
   763  * >  : greater than
   764  * <= : less than or equal to
   765  * >= : greater than or equal to
   766  *
   767 **/
   768 class RelationalExpr : public Expr
   769 {
   770 public:
   771     enum RelationalExprType {
   772         EQUAL,
   773         NOT_EQUAL,
   774         LESS_THAN,
   775         GREATER_THAN,
   776         LESS_OR_EQUAL,
   777         GREATER_OR_EQUAL
   778     };
   780     RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
   781         : mLeftExpr(aLeftExpr),
   782           mRightExpr(aRightExpr),
   783           mOp(aOp)
   784     {
   785     }
   788     TX_DECL_EXPR
   790 private:
   791     bool compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
   792                           txAExprResult* aRight);
   794     nsAutoPtr<Expr> mLeftExpr;
   795     nsAutoPtr<Expr> mRightExpr;
   796     RelationalExprType mOp;
   797 };
   799 /**
   800  * VariableRefExpr
   801  * Represents a variable reference ($refname)
   802 **/
   803 class VariableRefExpr : public Expr {
   805 public:
   807     VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID);
   809     TX_DECL_EXPR
   811 private:
   812     nsCOMPtr<nsIAtom> mPrefix;
   813     nsCOMPtr<nsIAtom> mLocalName;
   814     int32_t mNamespace;
   815 };
   817 /**
   818  *  Represents a PathExpr
   819 **/
   820 class PathExpr : public Expr {
   822 public:
   824     //-- Path Operators
   825     //-- RELATIVE_OP is the default
   826     //-- LF, changed from static const short to enum
   827     enum PathOperator { RELATIVE_OP, DESCENDANT_OP };
   829     /**
   830      * Adds the Expr to this PathExpr
   831      * The ownership of the given Expr is passed over the PathExpr,
   832      * even on failure.
   833      * @param aExpr the Expr to add to this PathExpr
   834      * @return nsresult indicating out of memory
   835      */
   836     nsresult addExpr(Expr* aExpr, PathOperator pathOp);
   838     /**
   839      * Removes and deletes the expression at the given index.
   840      */
   841     void deleteExprAt(uint32_t aPos)
   842     {
   843         NS_ASSERTION(aPos < mItems.Length(),
   844                      "killing bad expression index");
   845         mItems.RemoveElementAt(aPos);
   846     }
   848     TX_DECL_OPTIMIZABLE_EXPR
   850     PathOperator getPathOpAt(uint32_t aPos)
   851     {
   852         NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index");
   853         return mItems[aPos].pathOp;
   854     }
   855     void setPathOpAt(uint32_t aPos, PathOperator aPathOp)
   856     {
   857         NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index");
   858         mItems[aPos].pathOp = aPathOp;
   859     }
   861 private:
   862     class PathExprItem {
   863     public:
   864         nsAutoPtr<Expr> expr;
   865         PathOperator pathOp;
   866     };
   868     nsTArray<PathExprItem> mItems;
   870     /*
   871      * Selects from the descendants of the context node
   872      * all nodes that match the Expr
   873      */
   874     nsresult evalDescendants(Expr* aStep, const txXPathNode& aNode,
   875                              txIMatchContext* aContext,
   876                              txNodeSet* resNodes);
   877 };
   879 /**
   880  * This class represents a RootExpr, which only matches the Document node
   881 **/
   882 class RootExpr : public Expr {
   883 public:
   884     /**
   885      * Creates a new RootExpr
   886      */
   887     RootExpr()
   888 #ifdef TX_TO_STRING
   889         : mSerialize(true)
   890 #endif
   891     {
   892     }
   894     TX_DECL_EXPR
   896 #ifdef TX_TO_STRING
   897 public:
   898     void setSerialize(bool aSerialize)
   899     {
   900         mSerialize = aSerialize;
   901     }
   903 private:
   904     // When a RootExpr is used in a PathExpr it shouldn't be serialized
   905     bool mSerialize;
   906 #endif
   907 }; //-- RootExpr
   909 /**
   910  *  Represents a UnionExpr
   911 **/
   912 class UnionExpr : public Expr {
   913 public:
   914     /**
   915      * Adds the PathExpr to this UnionExpr
   916      * The ownership of the given Expr is passed over the UnionExpr,
   917      * even on failure.
   918      * @param aExpr the Expr to add to this UnionExpr
   919      * @return nsresult indicating out of memory
   920      */
   921     nsresult addExpr(Expr* aExpr)
   922     {
   923         return mExpressions.AppendElement(aExpr) ?
   924             NS_OK : NS_ERROR_OUT_OF_MEMORY;
   925     }
   927     /**
   928      * Removes and deletes the expression at the given index.
   929      */
   930     void deleteExprAt(uint32_t aPos)
   931     {
   932         NS_ASSERTION(aPos < mExpressions.Length(),
   933                      "killing bad expression index");
   935         delete mExpressions[aPos];
   936         mExpressions.RemoveElementAt(aPos);
   937     }
   939     TX_DECL_OPTIMIZABLE_EXPR
   941 private:
   943    txOwningArray<Expr> mExpressions;
   945 }; //-- UnionExpr
   947 /**
   948  * Class specializing in executing expressions like "@foo" where we are
   949  * interested in different result-types, and expressions like "@foo = 'hi'"
   950  */
   951 class txNamedAttributeStep : public Expr
   952 {
   953 public:
   954     txNamedAttributeStep(int32_t aNsID, nsIAtom* aPrefix,
   955                          nsIAtom* aLocalName);
   957     TX_DECL_EXPR
   959 private:
   960     int32_t mNamespace;
   961     nsCOMPtr<nsIAtom> mPrefix;
   962     nsCOMPtr<nsIAtom> mLocalName;
   963 };
   965 /**
   966  *
   967  */
   968 class txUnionNodeTest : public txNodeTest
   969 {
   970 public:
   971     nsresult addNodeTest(txNodeTest* aNodeTest)
   972     {
   973         return mNodeTests.AppendElement(aNodeTest) ?
   974             NS_OK : NS_ERROR_OUT_OF_MEMORY;
   975     }
   977     TX_DECL_NODE_TEST
   979 private:
   980     txOwningArray<txNodeTest> mNodeTests;
   981 };
   983 /**
   984  *  Expression that failed to parse
   985  */
   986 class txErrorExpr : public Expr
   987 {
   988 public:
   989 #ifdef TX_TO_STRING
   990     txErrorExpr(const nsAString& aStr)
   991       : mStr(aStr)
   992     {
   993     }
   994 #endif
   996     TX_DECL_EXPR
   998 #ifdef TX_TO_STRING
   999 private:
  1000     nsString mStr;
  1001 #endif
  1002 };
  1004 #endif

mercurial