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 00073 00074 #include <XalanDOM/XalanDOMString.hpp> 00075 00076 00077 00078 #include <PlatformSupport/DOMStringHelper.hpp> 00079 #include <PlatformSupport/PrintWriter.hpp> 00080 00081 00082 00083 #include <XPath/XObject.hpp> 00084 #include <XPath/XPathException.hpp> 00085 00086 00087 00088 class XALAN_XPATH_EXPORT XPathExpression 00089 { 00090 public: 00091 00110 enum eOpCodes 00111 { 00116 eENDOP = -1, 00117 00122 eEMPTY = -2, 00123 00129 eELEMWILDCARD = -3, 00130 00144 eOP_XPATH = 1, 00145 00155 eOP_OR = 2, 00156 00166 eOP_AND = 3, 00167 00177 eOP_NOTEQUALS = 4, 00178 00188 eOP_EQUALS = 5, 00189 00199 eOP_LTE = 6, 00200 00210 eOP_LT = 7, 00211 00221 eOP_GTE = 8, 00222 00232 eOP_GT = 9, 00233 00243 eOP_PLUS = 10, 00244 00254 eOP_MINUS = 11, 00255 00265 eOP_MULT = 12, 00266 00276 eOP_DIV = 13, 00277 00287 eOP_MOD = 14, 00288 00298 eOP_QUO = 15, 00299 00308 eOP_NEG = 16, 00309 00318 eOP_STRING = 17, 00319 00328 eOP_BOOL = 18, 00329 00338 eOP_NUMBER = 19, 00339 00348 eOP_UNION = 20, 00349 00358 eOP_LITERAL = 21, 00359 00368 eOP_VARIABLE = 22, 00369 00383 eOP_GROUP = 23, 00384 00393 eOP_NUMBERLIT = 24, 00394 00408 eOP_ARGUMENT = 25, 00409 00425 eOP_EXTFUNCTION = 26, 00426 00442 eOP_FUNCTION = 27, 00443 00457 eOP_LOCATIONPATH = 28, 00458 00468 eOP_PREDICATE = 29, 00469 00477 eNODETYPE_COMMENT = 1030, 00478 00486 eNODETYPE_TEXT = 1031, 00487 00495 eNODETYPE_PI = 1032, 00496 00504 eNODETYPE_NODE = 1033, 00505 00514 eNODENAME = 34, 00515 00523 eNODETYPE_ROOT = 35, 00524 00532 eNODETYPE_ANYELEMENT = 36, 00533 00544 eFROM_ANCESTORS = 37, 00545 eFROM_ANCESTORS_OR_SELF = 38, 00546 eFROM_ATTRIBUTES = 39, 00547 eFROM_CHILDREN = 40, 00548 eFROM_DESCENDANTS = 41, 00549 eFROM_DESCENDANTS_OR_SELF = 42, 00550 eFROM_FOLLOWING = 43, 00551 eFROM_FOLLOWING_SIBLINGS = 44, 00552 eFROM_PARENT = 45, 00553 eFROM_PRECEDING = 46, 00554 eFROM_PRECEDING_SIBLINGS = 47, 00555 eFROM_SELF = 48, 00556 eFROM_NAMESPACE = 49, 00557 // eFROM_ATTRIBUTE = 50, 00558 // eFROM_DOC = 51, 00559 // eFROM_DOCREF = 52, 00560 // eFROM_ID = 53, 00561 // eFROM_IDREF = 54, 00562 eFROM_ROOT = 55, 00563 00572 eOP_MATCHPATTERN = 92, 00573 00582 eOP_LOCATIONPATHPATTERN = 93, 00583 00584 // For match patterns 00585 eMATCH_ATTRIBUTE = 94, 00586 eMATCH_ANY_ANCESTOR = 95, 00587 eMATCH_IMMEDIATE_ANCESTOR = 96, 00588 eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 97, 00589 00590 // Always add _before_ this one. 00591 eOpCodeNextAvailable 00592 }; // enum eOpCodes 00593 00600 #if defined(XALAN_INLINE_INITIALIZATION) 00601 const int s__opCodeMapLengthIndex = 1; 00602 #else 00603 enum eDummy 00604 { 00605 s__opCodeMapLengthIndex = 1 00606 }; 00607 #endif 00608 00612 class XALAN_XPATH_EXPORT XPathExpressionException : public XPathException 00613 { 00614 public: 00615 00621 XPathExpressionException(const XalanDOMString& theMessage); 00622 00623 virtual~ 00624 XPathExpressionException(); 00625 }; 00626 00630 class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException 00631 { 00632 public: 00633 00639 InvalidOpCodeException(int theOpCode); 00640 00641 virtual~ 00642 InvalidOpCodeException(); 00643 00644 private: 00645 00646 static XalanDOMString 00647 FormatErrorMessage(int theOpCode); 00648 }; 00649 00654 class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException 00655 { 00656 public: 00657 00665 InvalidArgumentCountException( 00666 int theOpCode, 00667 int theExpectedCount, 00668 int theSuppliedCount); 00669 00670 virtual~ 00671 InvalidArgumentCountException(); 00672 00673 private: 00674 00675 static XalanDOMString 00676 FormatErrorMessage( 00677 int theOpCode, 00678 int theExpectedCount, 00679 int theSuppliedCount); 00680 }; 00681 00685 class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException 00686 { 00687 public: 00688 00695 InvalidArgumentException( 00696 int theOpCode, 00697 int theValue); 00698 00699 virtual~ 00700 InvalidArgumentException(); 00701 00702 private: 00703 00704 static XalanDOMString 00705 FormatErrorMessage( 00706 int theOpCode, 00707 int theValue); 00708 }; 00709 00713 class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public XPathExpressionException 00714 { 00715 public: 00716 00722 InvalidRelativeTokenPosition(int theOffset); 00723 00724 virtual~ 00725 InvalidRelativeTokenPosition(); 00726 00727 private: 00728 00729 static XalanDOMString 00730 FormatErrorMessage(int theOffset); 00731 }; 00732 00733 class XToken : public XObject 00734 { 00735 public: 00736 00737 explicit 00738 XToken(); 00739 00740 XToken(const XalanDOMString& theString); 00741 00742 XToken(double theNumber); 00743 00744 XToken(const XToken& theSource); 00745 00746 virtual 00747 ~XToken(); 00748 00749 #if defined(XALAN_NO_COVARIANT_RETURN_TYPE) 00750 virtual XObject* 00751 #else 00752 virtual XToken* 00753 #endif 00754 clone(void* theAddress = 0) const; 00755 00756 virtual XalanDOMString 00757 getTypeString() const; 00758 00759 virtual double 00760 num() const; 00761 00762 virtual const XalanDOMString& 00763 str() const; 00764 00765 virtual void 00766 ProcessXObjectTypeCallback(XObjectTypeCallback& theCallbackObject); 00767 00768 virtual void 00769 ProcessXObjectTypeCallback(XObjectTypeCallback& theCallbackObject) const; 00770 00771 XToken& 00772 operator=(const XToken& theRHS) 00773 { 00774 m_stringValue = theRHS.m_stringValue; 00775 00776 m_numberValue = theRHS.m_numberValue; 00777 00778 return *this; 00779 } 00780 00781 XToken& 00782 operator=(const XalanDOMString& theString); 00783 00784 XToken& 00785 operator=(double theNumber); 00786 00787 private: 00788 00789 // Not defined... 00790 bool 00791 operator==(const XToken&) const; 00792 00793 // Data members... 00794 XalanDOMString m_stringValue; 00795 00796 double m_numberValue; 00797 }; 00798 00799 00800 #if defined(XALAN_NO_NAMESPACES) 00801 00802 typedef vector<int> OpCodeMapType; 00803 typedef deque<XToken> TokenQueueType; 00804 typedef vector<int> PatternMapType; 00805 00806 typedef map<int, int, less<int> > OpCodeLengthMapType; 00807 00808 typedef OpCodeMapType::value_type OpCodeMapValueType; 00809 typedef OpCodeMapType::size_type OpCodeMapSizeType; 00810 00811 typedef set<OpCodeMapValueType, less<OpCodeMapValueType> > NodeTestSetType; 00812 00813 typedef vector<OpCodeMapValueType> OpCodeMapValueVectorType; 00814 00815 #else 00816 00817 typedef std::vector<int> OpCodeMapType; 00818 typedef std::deque<XToken> TokenQueueType; 00819 typedef std::vector<int> PatternMapType; 00820 typedef std::map<int, int> OpCodeLengthMapType; 00821 00822 typedef OpCodeMapType::value_type OpCodeMapValueType; 00823 typedef OpCodeMapType::size_type OpCodeMapSizeType; 00824 00825 typedef std::set<OpCodeMapValueType> NodeTestSetType; 00826 typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType; 00827 00828 #endif 00829 00830 typedef TokenQueueType::value_type TokenQueueValueType; 00831 typedef TokenQueueType::size_type TokenQueueSizeType; 00832 typedef PatternMapType::value_type PatternMapValueType; 00833 typedef PatternMapType::size_type PatternMapSizeType; 00834 00835 explicit 00836 XPathExpression(); 00837 00838 ~XPathExpression(); 00839 00843 void 00844 reset(); 00845 00849 void 00850 shrink(); 00851 00857 OpCodeMapSizeType 00858 opCodeMapSize() const 00859 { 00860 return m_opMap.size(); 00861 } 00862 00874 OpCodeMapValueType 00875 opCodeMapLength() const 00876 { 00877 const OpCodeMapSizeType theSize = opCodeMapSize(); 00878 00879 if (theSize > s__opCodeMapLengthIndex) 00880 { 00881 assert(theSize == 00882 OpCodeMapSizeType(m_opMap[s__opCodeMapLengthIndex])); 00883 00884 return m_opMap[s__opCodeMapLengthIndex]; 00885 } 00886 else 00887 { 00888 return theSize; 00889 } 00890 } 00891 00897 TokenQueueSizeType 00898 tokenQueueSize() const 00899 { 00900 return m_tokenQueue.size(); 00901 } 00902 00908 PatternMapSizeType 00909 patternMapSize() const 00910 { 00911 return m_patternMap.size(); 00912 } 00913 00921 OpCodeMapValueType 00922 getOpCodeMapValue(OpCodeMapSizeType opPos) const 00923 { 00924 return m_opMap[opPos]; 00925 } 00926 00934 OpCodeMapValueType 00935 getOpCodeLength(OpCodeMapSizeType opPos) const; 00936 00944 OpCodeMapValueType 00945 getNextOpCodePosition(OpCodeMapSizeType opPos) const 00946 { 00947 assert(opPos < opCodeMapSize()); 00948 00949 return opPos + m_opMap[opPos + s__opCodeMapLengthIndex]; 00950 } 00951 00961 void 00962 setOpCodeArgs( 00963 eOpCodes theOpCode, 00964 OpCodeMapSizeType theIndex, 00965 const OpCodeMapValueVectorType& theArgs); 00966 00972 void 00973 appendOpCode(eOpCodes theOpCode); 00974 00981 void 00982 appendOpCode(eOpCodes theOpCode, 00983 const OpCodeMapValueVectorType& theArgs) 00984 { 00985 appendOpCode(theOpCode); 00986 00987 setOpCodeArgs(theOpCode, 00988 m_lastOpCodeIndex, 00989 theArgs); 00990 } 00991 00998 OpCodeMapValueType 00999 insertOpCode( 01000 eOpCodes theOpCode, 01001 OpCodeMapSizeType theIndex); 01002 01012 void 01013 updateOpCodeLength(OpCodeMapSizeType theIndex) 01014 { 01015 assert(theIndex < opCodeMapSize()); 01016 01017 updateOpCodeLength(m_opMap[theIndex], theIndex); 01018 } 01019 01028 void 01029 updateShiftedOpCodeLength( 01030 OpCodeMapValueType theOpCode, 01031 OpCodeMapSizeType theOriginalIndex, 01032 OpCodeMapSizeType theNewIndex); 01033 01044 void 01045 updateOpCodeLength( 01046 OpCodeMapValueType theOpCode, 01047 OpCodeMapSizeType theIndex); 01048 01056 static bool 01057 isNodeTestOpCode(OpCodeMapValueType theOpCode); 01058 01064 void 01065 updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType theIndex); 01066 01072 bool 01073 hasMoreTokens() const 01074 { 01075 return tokenQueueSize() - m_currentPosition > 0 ? true : false; 01076 } 01077 01083 TokenQueueSizeType 01084 getTokenPosition() const 01085 { 01086 return m_currentPosition; 01087 } 01088 01092 void 01093 resetTokenPosition() 01094 { 01095 m_currentPosition = 0; 01096 } 01097 01103 void 01104 setTokenPosition(TokenQueueSizeType thePosition) 01105 { 01106 const TokenQueueSizeType theSize = tokenQueueSize(); 01107 01108 m_currentPosition = thePosition > theSize ? theSize : thePosition; 01109 } 01110 01116 void 01117 setTokenPosition(int thePosition) 01118 { 01119 setTokenPosition(thePosition > 0 ? TokenQueueSizeType(thePosition) : 0); 01120 } 01121 01128 const XObject* 01129 getToken(TokenQueueSizeType thePosition) const 01130 { 01131 assert(thePosition < tokenQueueSize()); 01132 01133 return &m_tokenQueue[thePosition]; 01134 } 01135 01141 const XObject* 01142 getNextToken() 01143 { 01144 if (hasMoreTokens() == true) 01145 { 01146 return getToken(m_currentPosition++); 01147 } 01148 else 01149 { 01150 return 0; 01151 } 01152 } 01153 01159 const XObject* 01160 getPreviousToken() 01161 { 01162 if (m_currentPosition > 0) 01163 { 01164 return getToken(--m_currentPosition); 01165 } 01166 else 01167 { 01168 return 0; 01169 } 01170 } 01171 01179 const XObject* 01180 getRelativeToken(int theOffset) const 01181 { 01182 const int thePosition = int(m_currentPosition) + theOffset; 01183 01184 if (thePosition < 0 || 01185 thePosition >= int(tokenQueueSize())) 01186 { 01187 return 0; 01188 } 01189 else 01190 { 01191 return getToken(thePosition); 01192 } 01193 } 01194 01200 void 01201 pushToken(const XalanDOMString& theToken) 01202 { 01203 m_tokenQueue.push_back(XToken(theToken)); 01204 } 01205 01211 void 01212 pushToken(double theToken) 01213 { 01214 m_tokenQueue.push_back(XToken(theToken)); 01215 } 01216 01223 void 01224 insertToken(const XalanDOMString& theToken) 01225 { 01226 m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken)); 01227 } 01228 01235 void 01236 insertToken(double theToken) 01237 { 01238 m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken)); 01239 } 01240 01247 void 01248 replaceRelativeToken( 01249 int theOffset, 01250 const XalanDOMString& theToken) 01251 { 01252 assert(theToken != 0); 01253 01254 const int thePosition = int(m_currentPosition) + theOffset; 01255 01256 if (thePosition < 0 || 01257 thePosition >= int(tokenQueueSize())) 01258 { 01259 throw InvalidRelativeTokenPosition(theOffset); 01260 } 01261 01262 m_tokenQueue[thePosition] = theToken; 01263 } 01264 01271 void 01272 replaceRelativeToken( 01273 int theOffset, 01274 double theToken) 01275 { 01276 assert(theToken != 0); 01277 01278 const int thePosition = int(m_currentPosition) + theOffset; 01279 01280 if (thePosition < 0 || thePosition >= int(tokenQueueSize())) 01281 { 01282 throw InvalidRelativeTokenPosition(theOffset); 01283 } 01284 01285 m_tokenQueue[thePosition] = theToken; 01286 } 01287 01294 void 01295 dumpOpCodeMap(PrintWriter& thePrintWriter, 01296 OpCodeMapSizeType theStartPosition = 0) const; 01297 01304 void 01305 dumpTokenQueue(PrintWriter& thePrintWriter, 01306 TokenQueueSizeType theStartPosition = 0) const; 01307 01313 void 01314 dumpRemainingTokenQueue(PrintWriter& thePrintWriter) const; 01315 01322 void 01323 pushArgumentOnOpCodeMap(const XalanDOMString& theToken); 01324 01331 void 01332 pushArgumentOnOpCodeMap(double theToken); 01333 01338 void 01339 pushCurrentTokenOnOpCodeMap(); 01340 01348 PatternMapValueType 01349 getPattern(int thePatternPosition) const 01350 { 01351 assert(int(patternMapSize()) > thePatternPosition); 01352 01353 return m_patternMap[thePatternPosition]; 01354 } 01355 01363 PatternMapValueType 01364 getPattern(PatternMapSizeType thePatternPosition) const 01365 { 01366 assert(patternMapSize() > thePatternPosition); 01367 01368 return m_patternMap[thePatternPosition]; 01369 } 01370 01376 void 01377 pushPattern(PatternMapValueType thePattern) 01378 { 01379 m_patternMap.push_back(thePattern); 01380 } 01381 01388 void 01389 adjustPattern( 01390 OpCodeMapSizeType theIndex, 01391 PatternMapValueType theAdjustment) 01392 { 01393 m_patternMap[theIndex] += theAdjustment; 01394 } 01395 01401 void 01402 setCurrentPattern(const XalanDOMString& thePattern) 01403 { 01404 m_currentPattern = thePattern; 01405 } 01406 01412 const XalanDOMString& 01413 getCurrentPattern() const 01414 { 01415 return m_currentPattern; 01416 } 01417 01424 OpCodeMapType m_opMap; 01425 01430 OpCodeMapSizeType m_lastOpCodeIndex; 01431 01437 TokenQueueType m_tokenQueue; 01438 01442 TokenQueueSizeType m_currentPosition; 01443 01451 // Ignore this, it is going away. 01452 PatternMapType m_patternMap; 01453 01457 XalanDOMString m_currentPattern; 01458 01459 private: 01460 01461 // Default vector allocation sizes. 01462 enum 01463 { 01464 eDefaultOpMapSize = 100, 01465 eDefaultPatternMapSize = 100 01466 }; 01467 01468 // A map of Op codes to op code lengths. 01469 const static OpCodeLengthMapType s_opCodeLengths; 01470 01471 static OpCodeLengthMapType 01472 IntializeOpCodeLengthMap(); 01473 01474 // A static set of Op codes that are node tests. 01475 const static NodeTestSetType s_NodeTestOpCodes; 01476 01477 static NodeTestSetType 01478 InitializeNodeTestSet(); 01479 }; 01480 01481 01482 01483 #endif // XPATHEXPRESSION_HEADER_GUARD_1357924680
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSL Transformer Version 1.0 |
|