Xalan-C++ API Documentation

The Xalan C++ XSL Transformer Version 1.1

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

XPathExpression.hpp

Go to the documentation of this file.
00001 /*
00002  * The Apache Software License, Version 1.1
00003  *
00004  *
00005  * Copyright (c) 1999 The Apache Software Foundation.  All rights 
00006  * reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer. 
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in
00017  *    the documentation and/or other materials provided with the
00018  *    distribution.
00019  *
00020  * 3. The end-user documentation included with the redistribution,
00021  *    if any, must include the following acknowledgment:  
00022  *       "This product includes software developed by the
00023  *        Apache Software Foundation (http://www.apache.org/)."
00024  *    Alternately, this acknowledgment may appear in the software itself,
00025  *    if and wherever such third-party acknowledgments normally appear.
00026  *
00027  * 4. The names "Xalan" and "Apache Software Foundation" must
00028  *    not be used to endorse or promote products derived from this
00029  *    software without prior written permission. For written 
00030  *    permission, please contact apache@apache.org.
00031  *
00032  * 5. Products derived from this software may not be called "Apache",
00033  *    nor may "Apache" appear in their name, without prior written
00034  *    permission of the Apache Software Foundation.
00035  *
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00039  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00040  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00041  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00042  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00043  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00044  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00045  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00046  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00047  * SUCH DAMAGE.
00048  * ====================================================================
00049  *
00050  * This software consists of voluntary contributions made by many
00051  * individuals on behalf of the Apache Software Foundation and was
00052  * originally based on software copyright (c) 1999, International
00053  * Business Machines, Inc., http://www.ibm.com.  For more
00054  * information on the Apache Software Foundation, please see
00055  * <http://www.apache.org/>.
00056  */
00057 #if !defined(XPATHEXPRESSION_HEADER_GUARD_1357924680)
00058 #define XPATHEXPRESSION_HEADER_GUARD_1357924680
00059 
00060 
00061 
00062 // Base header file.  Must be first.
00063 #include <XPath/XPathDefinitions.hpp>
00064 
00065 
00066 
00067 #include <deque>
00068 #include <map>
00069 #include <set>
00070 #include <vector>
00071 
00072 #if defined(XALAN_NO_IOSFWD)
00073 #if defined(XALAN_OLD_STREAM_HEADERS)
00074 #include <iostream.h>
00075 #else
00076 #include <ostream>
00077 #endif
00078 #else
00079 #include <iosfwd>
00080 #endif
00081 
00082 
00083 
00084 #include <XalanDOM/XalanDOMString.hpp>
00085 
00086 
00087 
00088 #include <PlatformSupport/DOMStringHelper.hpp>
00089 #include <PlatformSupport/PrintWriter.hpp>
00090 
00091 
00092 
00093 #include <XPath/XToken.hpp>
00094 #include <XPath/XPathException.hpp>
00095 
00096 
00097 
00098 class XALAN_XPATH_EXPORT XPathExpression
00099 {
00100 public:
00101 
00120     enum eOpCodes
00121     {
00126         eENDOP = -1,
00127 
00132         eEMPTY = -2,
00133 
00139         eELEMWILDCARD = -3,
00140 
00154         eOP_XPATH = 1,
00155 
00165         eOP_OR = 2,
00166 
00176         eOP_AND = 3,
00177 
00187         eOP_NOTEQUALS = 4,
00188 
00198         eOP_EQUALS = 5,
00199 
00209         eOP_LTE = 6,
00210 
00220         eOP_LT = 7,
00221 
00231         eOP_GTE = 8,
00232 
00242         eOP_GT = 9,
00243 
00253         eOP_PLUS = 10,
00254 
00264         eOP_MINUS = 11,
00265 
00275         eOP_MULT = 12,
00276 
00286         eOP_DIV = 13,
00287 
00297         eOP_MOD = 14,
00298 
00308         eOP_QUO = 15,
00309 
00318         eOP_NEG = 16,
00319 
00328         eOP_STRING = 17,
00329 
00338         eOP_BOOL = 18,
00339 
00348         eOP_NUMBER = 19,
00349 
00358         eOP_UNION = 20,
00359 
00368         eOP_LITERAL = 21,
00369 
00378         eOP_VARIABLE = 22,
00379 
00393         eOP_GROUP = 23,
00394 
00403         eOP_NUMBERLIT = 24,
00404 
00418         eOP_ARGUMENT = 25,
00419 
00435         eOP_EXTFUNCTION = 26,
00436 
00452         eOP_FUNCTION = 27,
00453 
00467         eOP_LOCATIONPATH = 28,
00468 
00478         eOP_PREDICATE = 29,
00479   
00487         eNODETYPE_COMMENT = 1030,
00488         
00496         eNODETYPE_TEXT = 1031,
00497         
00505         eNODETYPE_PI = 1032,
00506         
00514         eNODETYPE_NODE = 1033,
00515         
00524         eNODENAME = 34,
00525         
00533         eNODETYPE_ROOT = 35,
00534         
00542         eNODETYPE_ANYELEMENT = 36,
00543 
00554         eFROM_ANCESTORS = 37,
00555         eFROM_ANCESTORS_OR_SELF = 38,
00556         eFROM_ATTRIBUTES = 39,
00557         eFROM_CHILDREN = 40,
00558         eFROM_DESCENDANTS = 41,
00559         eFROM_DESCENDANTS_OR_SELF = 42,
00560         eFROM_FOLLOWING = 43,
00561         eFROM_FOLLOWING_SIBLINGS = 44,
00562         eFROM_PARENT = 45,
00563         eFROM_PRECEDING = 46,
00564         eFROM_PRECEDING_SIBLINGS = 47,
00565         eFROM_SELF = 48,
00566         eFROM_NAMESPACE = 49,
00567         // eFROM_ATTRIBUTE = 50,
00568         // eFROM_DOC = 51,
00569         // eFROM_DOCREF = 52,
00570         // eFROM_ID = 53,
00571         // eFROM_IDREF = 54,
00572         eFROM_ROOT = 55,
00573 
00582         eOP_MATCHPATTERN = 92,
00583 
00592         eOP_LOCATIONPATHPATTERN = 93,
00593 
00594         // For match patterns
00595         eMATCH_ATTRIBUTE = 94,
00596         eMATCH_ANY_ANCESTOR = 95,
00597         eMATCH_IMMEDIATE_ANCESTOR = 96,
00598         eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 97,
00599         eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 98,
00600 
00601         // Always add _before_ this one.
00602         eOpCodeNextAvailable
00603     };  // enum eOpCodes
00604 
00611 #if defined(XALAN_INLINE_INITIALIZATION)
00612     const int   s__opCodeMapLengthIndex = 1;
00613 #else
00614     enum eDummy
00615     {
00616         s__opCodeMapLengthIndex = 1
00617     };
00618 #endif
00619 
00623     class XALAN_XPATH_EXPORT XPathExpressionException : public XPathException
00624     {
00625     public:
00626 
00632         XPathExpressionException(const XalanDOMString&  theMessage);
00633 
00634         virtual~
00635         XPathExpressionException();
00636     };
00637 
00641     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00642     {
00643     public:
00644 
00650         InvalidOpCodeException(int  theOpCode);
00651 
00652         virtual~
00653         InvalidOpCodeException();
00654 
00655     private:
00656 
00657         static XalanDOMString
00658         FormatErrorMessage(int  theOpCode);
00659     };
00660 
00665     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00666     {
00667     public:
00668 
00676         InvalidArgumentCountException(
00677             int     theOpCode,
00678             int     theExpectedCount,
00679             int     theSuppliedCount);
00680 
00681         virtual~
00682         InvalidArgumentCountException();
00683 
00684     private:
00685 
00686         static XalanDOMString
00687         FormatErrorMessage(
00688             int     theOpCode,
00689             int     theExpectedCount,
00690             int     theSuppliedCount);
00691     };
00692 
00696     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00697     {
00698     public:
00699 
00706         InvalidArgumentException(
00707             int theOpCode,
00708             int theValue);
00709 
00710         virtual~
00711         InvalidArgumentException();
00712 
00713     private:
00714 
00715         static XalanDOMString
00716         FormatErrorMessage(
00717                 int     theOpCode,
00718                 int     theValue);
00719     };
00720 
00724     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException
00725     {
00726     public:
00727 
00733         InvalidRelativeTokenPosition(int    theOffset);
00734 
00735         virtual~
00736         InvalidRelativeTokenPosition();
00737 
00738     private:
00739 
00740         static XalanDOMString
00741         FormatErrorMessage(int  theOffset);
00742     };
00743 
00744 
00745 #if defined(XALAN_NO_NAMESPACES)
00746 
00747     typedef vector<int>                     OpCodeMapType;
00748     typedef deque<XToken>                   TokenQueueType;
00749     typedef vector<int>                     PatternMapType;
00750 
00751     typedef map<int, int, less<int> >       OpCodeLengthMapType;
00752 
00753     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00754     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00755 
00756     typedef set<OpCodeMapValueType, less<OpCodeMapValueType> >  NodeTestSetType;
00757 
00758     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00759 
00760 #else
00761 
00762     typedef std::vector<int>                OpCodeMapType;
00763     typedef std::deque<XToken>              TokenQueueType;
00764     typedef std::vector<int>                PatternMapType;
00765     typedef std::map<int, int>              OpCodeLengthMapType;
00766 
00767     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00768     typedef OpCodeMapType::size_type        OpCodeMapSizeType;
00769 
00770     typedef std::set<OpCodeMapValueType>    NodeTestSetType;
00771     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00772 
00773 #endif
00774 
00775     typedef TokenQueueType::value_type      TokenQueueValueType;
00776     typedef TokenQueueType::size_type       TokenQueueSizeType;
00777     typedef PatternMapType::value_type      PatternMapValueType;
00778     typedef PatternMapType::size_type       PatternMapSizeType;
00779 
00780     explicit
00781     XPathExpression();
00782 
00783     ~XPathExpression();
00784 
00788     void
00789     reset();
00790 
00794     void
00795     shrink();
00796 
00802     OpCodeMapSizeType
00803     opCodeMapSize() const
00804     {
00805         return m_opMap.size();
00806     }
00807 
00819     OpCodeMapValueType
00820     opCodeMapLength() const
00821     {
00822         const OpCodeMapSizeType     theSize = opCodeMapSize();
00823 
00824         if (theSize > s__opCodeMapLengthIndex)
00825         {
00826             assert(theSize ==
00827                 OpCodeMapSizeType(m_opMap[s__opCodeMapLengthIndex]));
00828 
00829             return m_opMap[s__opCodeMapLengthIndex];
00830         }
00831         else
00832         {
00833             return theSize;
00834         }
00835     }
00836 
00842     TokenQueueSizeType
00843     tokenQueueSize() const
00844     {
00845         return m_tokenQueue.size();
00846     }
00847 
00853     PatternMapSizeType
00854     patternMapSize() const
00855     {
00856         return m_patternMap.size();
00857     }
00858 
00866     OpCodeMapValueType
00867     getOpCodeMapValue(OpCodeMapSizeType     opPos) const
00868     {
00869         return m_opMap[opPos];
00870     }
00871 
00879     OpCodeMapValueType
00880     getOpCodeLength(OpCodeMapSizeType   opPos) const;
00881 
00889     OpCodeMapValueType
00890     getNextOpCodePosition(OpCodeMapSizeType     opPos) const
00891     {
00892         assert(opPos < opCodeMapSize());
00893 
00894         return opPos + m_opMap[opPos + s__opCodeMapLengthIndex];
00895     }
00896 
00906     void
00907     setOpCodeArgs(
00908             eOpCodes                            theOpCode,
00909             OpCodeMapSizeType                   theIndex,
00910             const OpCodeMapValueVectorType&     theArgs);
00911 
00917     void
00918     appendOpCode(eOpCodes   theOpCode);
00919 
00926     void
00927     appendOpCode(eOpCodes                           theOpCode,
00928                  const OpCodeMapValueVectorType&    theArgs)
00929     {
00930         appendOpCode(theOpCode);
00931 
00932         setOpCodeArgs(theOpCode,
00933                       m_lastOpCodeIndex,
00934                       theArgs);
00935     }
00936 
00943     OpCodeMapValueType
00944     insertOpCode(
00945             eOpCodes            theOpCode,
00946             OpCodeMapSizeType   theIndex);
00947 
00957     void
00958     updateOpCodeLength(OpCodeMapSizeType    theIndex)
00959     {
00960         assert(theIndex < opCodeMapSize());
00961 
00962         updateOpCodeLength(m_opMap[theIndex], theIndex);
00963     }
00964 
00973     void
00974     updateShiftedOpCodeLength(
00975             OpCodeMapValueType  theOpCode,
00976             OpCodeMapSizeType   theOriginalIndex,
00977             OpCodeMapSizeType   theNewIndex);
00978 
00989     void
00990     updateOpCodeLength(
00991             OpCodeMapValueType  theOpCode,
00992             OpCodeMapSizeType   theIndex);
00993 
01001     static bool
01002     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
01003 
01009     void
01010     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
01011 
01017     bool
01018     hasMoreTokens() const
01019     {
01020         return tokenQueueSize() - m_currentPosition > 0 ? true : false;
01021     }
01022 
01028     TokenQueueSizeType
01029     getTokenPosition() const
01030     {
01031         return m_currentPosition;
01032     }
01033 
01037     void
01038     resetTokenPosition()
01039     {
01040         m_currentPosition = 0;
01041     }
01042 
01048     void
01049     setTokenPosition(TokenQueueSizeType     thePosition)
01050     {
01051         const TokenQueueSizeType    theSize = tokenQueueSize();
01052 
01053         m_currentPosition = thePosition > theSize ? theSize : thePosition;
01054     }
01055 
01061     void
01062     setTokenPosition(int    thePosition)
01063     {
01064         setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0);
01065     }
01066 
01073     const XObject*
01074     getToken(TokenQueueSizeType     thePosition) const
01075     {
01076         assert(thePosition < tokenQueueSize());
01077 
01078         return &m_tokenQueue[thePosition];
01079     }
01080 
01086     const XObject*
01087     getNextToken()
01088     {
01089         if (hasMoreTokens() == true)
01090         {
01091             return getToken(m_currentPosition++);
01092         }
01093         else
01094         {
01095             return 0;
01096         }
01097     }
01098 
01104     const XObject*
01105     getPreviousToken()
01106     {
01107         if (m_currentPosition > 0)
01108         {
01109             return getToken(--m_currentPosition);
01110         }
01111         else
01112         {
01113             return 0;
01114         }
01115     }
01116 
01124     const XObject*
01125     getRelativeToken(int    theOffset) const
01126     {
01127         const int   thePosition = int(m_currentPosition) + theOffset;
01128 
01129         if (thePosition < 0 ||
01130             thePosition >= int(tokenQueueSize()))
01131         {
01132             return 0;
01133         }
01134         else
01135         {
01136             return getToken(thePosition);
01137         }
01138     }
01139 
01145     void
01146     pushToken(const XalanDOMString&     theToken)
01147     {
01148         m_tokenQueue.push_back(XToken(theToken));
01149     }
01150 
01156     void
01157     pushToken(double    theToken)
01158     {
01159         m_tokenQueue.push_back(XToken(theToken));
01160     }
01161 
01168     void
01169     insertToken(const XalanDOMString&   theToken)
01170     {
01171         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01172     }
01173 
01180     void
01181     insertToken(double  theToken)
01182     {
01183         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01184     }
01185 
01192     void
01193     replaceRelativeToken(
01194             int                     theOffset,
01195             const XalanDOMString&   theToken)
01196     {
01197         assert(c_wstr(theToken) != 0);
01198 
01199         const int   thePosition = int(m_currentPosition) + theOffset;
01200 
01201         if (thePosition < 0 ||
01202             thePosition >= int(tokenQueueSize()))
01203         {
01204             throw InvalidRelativeTokenPosition(theOffset);
01205         }
01206 
01207         m_tokenQueue[thePosition] = theToken;
01208     }
01209 
01216     void
01217     replaceRelativeToken(
01218             int     theOffset,
01219             double  theToken)
01220     {
01221         assert(theToken != 0);
01222 
01223         const int   thePosition = int(m_currentPosition) + theOffset;
01224 
01225         if (thePosition < 0 || thePosition >= int(tokenQueueSize()))
01226         {
01227             throw InvalidRelativeTokenPosition(theOffset);
01228         }
01229 
01230         m_tokenQueue[thePosition] = theToken;
01231     }
01232 
01239     void
01240     dumpOpCodeMap(PrintWriter&          thePrintWriter,
01241                   OpCodeMapSizeType     theStartPosition = 0) const;
01242 
01249     void
01250     dumpOpCodeMap(
01251 #if defined(XALAN_NO_NAMESPACES)
01252             ostream&            theStream,
01253 #else
01254             std::ostream&       theStream,
01255 #endif
01256             OpCodeMapSizeType   theStartPosition = 0) const;
01257 
01264     void
01265     dumpTokenQueue(PrintWriter&         thePrintWriter,
01266                    TokenQueueSizeType   theStartPosition = 0) const;
01267 
01274     void
01275     dumpTokenQueue(
01276 #if defined(XALAN_NO_NAMESPACES)
01277             ostream&            theStream,
01278 #else
01279             std::ostream&       theStream,
01280 #endif
01281             TokenQueueSizeType  theStartPosition = 0) const;
01282 
01288     void
01289     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01290 
01296     void
01297 #if defined(XALAN_NO_NAMESPACES)
01298     dumpRemainingTokenQueue(ostream&        theStream) const;
01299 #else
01300     dumpRemainingTokenQueue(std::ostream&   theStream) const;
01301 #endif
01302 
01309     void
01310     pushArgumentOnOpCodeMap(const XalanDOMString&   theToken);
01311 
01318     void
01319     pushArgumentOnOpCodeMap(double  theToken);
01320 
01325     void
01326     pushCurrentTokenOnOpCodeMap();
01327 
01335     PatternMapValueType
01336     getPattern(int  thePatternPosition) const
01337     {
01338         assert(int(patternMapSize()) > thePatternPosition);
01339 
01340         return m_patternMap[thePatternPosition];
01341     }
01342 
01350     PatternMapValueType
01351     getPattern(PatternMapSizeType   thePatternPosition) const
01352     {
01353         assert(patternMapSize() > thePatternPosition);
01354 
01355         return m_patternMap[thePatternPosition];
01356     }
01357 
01363     void
01364     pushPattern(PatternMapValueType thePattern)
01365     {
01366         m_patternMap.push_back(thePattern);
01367     }
01368 
01375     void
01376     adjustPattern(
01377             OpCodeMapSizeType   theIndex,
01378             PatternMapValueType theAdjustment)
01379     {
01380         m_patternMap[theIndex] += theAdjustment;
01381     }
01382 
01388     void
01389     setCurrentPattern(const XalanDOMString&     thePattern)
01390     {
01391         m_currentPattern = thePattern;
01392     }
01393 
01399     const XalanDOMString&
01400     getCurrentPattern() const
01401     {
01402         return m_currentPattern;
01403     }
01404 
01411     OpCodeMapType           m_opMap;
01412 
01417     OpCodeMapSizeType       m_lastOpCodeIndex;
01418 
01424     TokenQueueType          m_tokenQueue;
01425 
01429     TokenQueueSizeType      m_currentPosition;
01430 
01438      // Ignore this, it is going away.
01439     PatternMapType          m_patternMap;
01440 
01444     XalanDOMString          m_currentPattern;
01445 
01446 private:
01447 
01448     // Default vector allocation sizes.
01449     enum
01450     {
01451         eDefaultOpMapSize = 100,
01452         eDefaultPatternMapSize = 100
01453     };
01454 
01455     // A map of Op codes to op code lengths.
01456     const static OpCodeLengthMapType    s_opCodeLengths;
01457 
01458     static OpCodeLengthMapType
01459     IntializeOpCodeLengthMap();
01460 
01461     // A static set of Op codes that are node tests.
01462     const static NodeTestSetType        s_NodeTestOpCodes;
01463 
01464     static NodeTestSetType
01465     InitializeNodeTestSet();
01466 };
01467 
01468 
01469 
01470 #endif  // XPATHEXPRESSION_HEADER_GUARD_1357924680

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

Xalan-C++ XSL Transformer Version 1.1
Copyright © 2000, 2001 The Apache Software Foundation. All Rights Reserved.