Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.8

Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

XPathExpression.hpp

Go to the documentation of this file.
00001 /* 00002 * Copyright 1999-2004 The Apache Software Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #if !defined(XPATHEXPRESSION_HEADER_GUARD_1357924680) 00017 #define XPATHEXPRESSION_HEADER_GUARD_1357924680 00018 00019 00020 00021 // Base header file. Must be first. 00022 #include <xalanc/XPath/XPathDefinitions.hpp> 00023 00024 00025 00026 #include <vector> 00027 00028 #if defined(XALAN_CLASSIC_IOSTREAMS) 00029 #include <iostream.h> 00030 #else 00031 #include <iosfwd> 00032 #endif 00033 00034 00035 00036 #include <xalanc/XalanDOM/XalanDOMString.hpp> 00037 00038 00039 00040 #include <xalanc/PlatformSupport/DOMStringHelper.hpp> 00041 #include <xalanc/PlatformSupport/PrintWriter.hpp> 00042 00043 00044 00045 #include <xalanc/XPath/XToken.hpp> 00046 #include <xalanc/XPath/XalanXPathException.hpp> 00047 00048 00049 00050 XALAN_CPP_NAMESPACE_BEGIN 00051 00052 00053 00054 class XALAN_XPATH_EXPORT XPathExpression 00055 { 00056 public: 00057 00058 #if defined(XALAN_NO_STD_NAMESPACE) 00059 typedef ostream OstreamType; 00060 00061 typedef vector<int> OpCodeMapType; 00062 typedef vector<XToken> TokenQueueType; 00063 00064 typedef OpCodeMapType::value_type OpCodeMapValueType; 00065 typedef OpCodeMapValueType OpCodeMapSizeType; 00066 00067 typedef vector<OpCodeMapValueType> OpCodeMapValueVectorType; 00068 00069 typedef vector<double> NumberLiteralValueVectorType; 00070 #else 00071 typedef std::ostream OstreamType; 00072 00073 typedef std::vector<int> OpCodeMapType; 00074 typedef std::vector<XToken> TokenQueueType; 00075 00076 typedef OpCodeMapType::value_type OpCodeMapValueType; 00077 typedef OpCodeMapValueType OpCodeMapSizeType; 00078 00079 typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType; 00080 00081 typedef std::vector<double> NumberLiteralValueVectorType; 00082 #endif 00083 00084 #define XALAN_XPATH_EXPRESSION_USE_ITERATORS 00085 00086 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00087 typedef OpCodeMapType::const_iterator OpCodeMapPositionType; 00088 #else 00089 typedef OpCodeMapSizeType OpCodeMapPositionType; 00090 #endif 00091 typedef OpCodeMapType::difference_type OpCodeMapDifferenceType; 00092 typedef TokenQueueType::value_type TokenQueueValueType; 00093 typedef int TokenQueueSizeType; 00094 typedef TokenQueueSizeType TokenQueuePositionType; 00095 00114 enum eOpCodes 00115 { 00121 eELEMWILDCARD = -3, 00122 00127 eEMPTY = -2, 00128 00133 eENDOP = -1, 00134 00148 eOP_XPATH = 1, 00149 00159 eOP_OR = 2, 00160 00170 eOP_AND = 3, 00171 00181 eOP_NOTEQUALS = 4, 00182 00192 eOP_EQUALS = 5, 00193 00203 eOP_LTE = 6, 00204 00214 eOP_LT = 7, 00215 00225 eOP_GTE = 8, 00226 00236 eOP_GT = 9, 00237 00247 eOP_PLUS = 10, 00248 00258 eOP_MINUS = 11, 00259 00269 eOP_MULT = 12, 00270 00280 eOP_DIV = 13, 00281 00291 eOP_MOD = 14, 00292 00301 eOP_NEG = 15, 00302 00311 eOP_BOOL = 16, 00312 00321 eOP_UNION = 17, 00322 00331 eOP_LITERAL = 18, 00332 00341 eOP_VARIABLE = 19, 00342 00356 eOP_GROUP = 20, 00357 00366 eOP_NUMBERLIT = 21, 00367 00381 eOP_ARGUMENT = 22, 00382 00398 eOP_EXTFUNCTION = 23, 00399 00416 eOP_FUNCTION = 24, 00417 00431 eOP_LOCATIONPATH = 25, 00432 00442 eOP_PREDICATE = 26, 00443 00451 eNODETYPE_COMMENT = 27, 00452 00460 eNODETYPE_TEXT = 28, 00461 00469 eNODETYPE_PI = 29, 00470 00478 eNODETYPE_NODE = 30, 00479 00488 eNODENAME = 31, 00489 00497 eNODETYPE_ROOT = 32, 00498 00506 eNODETYPE_ANYELEMENT = 33, 00507 00518 eFROM_ANCESTORS = 34, 00519 eFROM_ANCESTORS_OR_SELF = 35, 00520 eFROM_ATTRIBUTES = 36, 00521 eFROM_CHILDREN = 37, 00522 eFROM_DESCENDANTS = 38, 00523 eFROM_DESCENDANTS_OR_SELF = 39, 00524 eFROM_FOLLOWING = 40, 00525 eFROM_FOLLOWING_SIBLINGS = 41, 00526 eFROM_PARENT = 42, 00527 eFROM_PRECEDING = 43, 00528 eFROM_PRECEDING_SIBLINGS = 44, 00529 eFROM_SELF = 45, 00530 eFROM_NAMESPACE = 46, 00531 eFROM_ROOT = 47, 00532 00541 eOP_MATCHPATTERN = 48, 00542 00551 eOP_LOCATIONPATHPATTERN = 49, 00552 00553 // For match patterns 00554 eMATCH_ATTRIBUTE = 50, 00555 eMATCH_ANY_ANCESTOR = 51, 00556 eMATCH_IMMEDIATE_ANCESTOR = 52, 00557 eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53, 00558 eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54, 00559 00569 eOP_PREDICATE_WITH_POSITION = 55, 00570 00575 eOP_FUNCTION_POSITION = 56, 00576 eOP_FUNCTION_LAST = 57, 00577 eOP_FUNCTION_COUNT = 58, 00578 eOP_FUNCTION_NOT = 59, 00579 eOP_FUNCTION_TRUE = 60, 00580 eOP_FUNCTION_FALSE = 61, 00581 eOP_FUNCTION_BOOLEAN = 62, 00582 eOP_FUNCTION_NAME_0 = 63, 00583 eOP_FUNCTION_NAME_1 = 64, 00584 eOP_FUNCTION_LOCALNAME_0 = 65, 00585 eOP_FUNCTION_LOCALNAME_1 = 66, 00586 eOP_FUNCTION_FLOOR = 67, 00587 eOP_FUNCTION_CEILING = 68, 00588 eOP_FUNCTION_ROUND = 69, 00589 eOP_FUNCTION_NUMBER_0 = 70, 00590 eOP_FUNCTION_NUMBER_1 = 71, 00591 eOP_FUNCTION_STRING_0 = 72, 00592 eOP_FUNCTION_STRING_1 = 73, 00593 eOP_FUNCTION_STRINGLENGTH_0 = 74, 00594 eOP_FUNCTION_STRINGLENGTH_1 = 75, 00595 eOP_FUNCTION_NAMESPACEURI_0 = 76, 00596 eOP_FUNCTION_NAMESPACEURI_1 = 77, 00597 eOP_FUNCTION_SUM = 78, 00598 eOP_FUNCTION_CONCAT = 79, 00599 00600 // Always add _before_ this one and update 00601 // s_opCodeLengthArray. 00602 eOpCodeNextAvailable 00603 }; // enum eOpCodes 00604 00608 class XALAN_XPATH_EXPORT XPathExpressionException : public XalanXPathException 00609 { 00610 public: 00611 00617 XPathExpressionException(const XalanDOMString& theMessage); 00618 00619 virtual~ 00620 XPathExpressionException(); 00621 }; 00622 00626 class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException 00627 { 00628 public: 00629 00635 InvalidOpCodeException(OpCodeMapValueType theOpCode); 00636 00637 virtual~ 00638 InvalidOpCodeException(); 00639 00640 private: 00641 00642 static XalanDOMString 00643 FormatErrorMessage(OpCodeMapValueType theOpCode); 00644 }; 00645 00650 class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException 00651 { 00652 public: 00653 00661 InvalidArgumentCountException( 00662 OpCodeMapValueType theOpCode, 00663 OpCodeMapValueType theExpectedCount, 00664 OpCodeMapValueType theSuppliedCount); 00665 00666 virtual~ 00667 InvalidArgumentCountException(); 00668 00669 private: 00670 00671 static XalanDOMString 00672 FormatErrorMessage( 00673 OpCodeMapValueType theOpCode, 00674 OpCodeMapValueType theExpectedCount, 00675 OpCodeMapValueType theSuppliedCount); 00676 }; 00677 00681 class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException 00682 { 00683 public: 00684 00691 InvalidArgumentException( 00692 OpCodeMapValueType theOpCode, 00693 OpCodeMapValueType theValue); 00694 00695 virtual~ 00696 InvalidArgumentException(); 00697 00698 private: 00699 00700 static XalanDOMString 00701 FormatErrorMessage( 00702 OpCodeMapValueType theOpCode, 00703 OpCodeMapValueType theValue); 00704 }; 00705 00706 00713 #if defined(XALAN_INLINE_INITIALIZATION) 00714 static const TokenQueueSizeType s_opCodeMapLengthIndex = 1; 00715 #else 00716 enum eDummy 00717 { 00718 s_opCodeMapLengthIndex = 1 00719 }; 00720 #endif 00721 00722 explicit 00723 XPathExpression(); 00724 00725 ~XPathExpression(); 00726 00730 void 00731 reset(); 00732 00736 void 00737 shrink(); 00738 00744 OpCodeMapSizeType 00745 opCodeMapSize() const 00746 { 00747 return OpCodeMapSizeType(m_opMap.size()); 00748 } 00749 00761 OpCodeMapValueType 00762 opCodeMapLength() const 00763 { 00764 const OpCodeMapSizeType theSize = opCodeMapSize(); 00765 00766 if (theSize > s_opCodeMapLengthIndex) 00767 { 00768 assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex])); 00769 00770 return m_opMap[s_opCodeMapLengthIndex]; 00771 } 00772 else 00773 { 00774 assert(theSize == OpCodeMapValueType(theSize)); 00775 00776 return OpCodeMapValueType(theSize); 00777 } 00778 } 00779 00780 OpCodeMapPositionType 00781 getInitialOpCodePosition() const 00782 { 00783 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00784 return m_opMap.begin(); 00785 #else 00786 return 0; 00787 #endif 00788 } 00789 00790 bool 00791 isValidOpCodePosition(OpCodeMapPositionType opPos) const 00792 { 00793 const OpCodeMapDifferenceType theDifference = 00794 OpCodeMapDifferenceType(opPos - getInitialOpCodePosition()); 00795 00796 return theDifference >= 0 && 00797 theDifference < opCodeMapSize(); 00798 } 00799 00800 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00801 bool 00802 isValidOpCodePosition(OpCodeMapSizeType theIndex) const 00803 { 00804 return theIndex >= 0 && theIndex < opCodeMapSize(); 00805 } 00806 00814 OpCodeMapValueType 00815 getOpCodeMapValue(OpCodeMapSizeType theIndex) const 00816 { 00817 assert(theIndex < opCodeMapLength()); 00818 00819 return m_opMap[theIndex]; 00820 } 00821 #endif 00822 00830 OpCodeMapValueType 00831 getOpCodeMapValue(OpCodeMapPositionType opPos) const 00832 { 00833 assert(opPos < getInitialOpCodePosition() + opCodeMapLength()); 00834 00835 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00836 return *opPos; 00837 #else 00838 00839 return m_opMap[opPos]; 00840 #endif 00841 } 00842 00850 void 00851 setOpCodeMapValue( 00852 OpCodeMapSizeType theOpCodeMapIndex, 00853 const OpCodeMapValueType& theValue) 00854 { 00855 assert(theOpCodeMapIndex < opCodeMapLength()); 00856 00857 m_opMap[theOpCodeMapIndex] = theValue; 00858 } 00859 00860 OpCodeMapValueType 00861 getOpCodeArgumentLength(OpCodeMapPositionType opPos) const 00862 { 00863 return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3; 00864 } 00865 00873 OpCodeMapValueType 00874 getOpCodeLengthFromOpMap(OpCodeMapPositionType opPos) const; 00875 00876 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00877 00884 OpCodeMapValueType 00885 getOpCodeLengthFromOpMap(OpCodeMapSizeType theIndex) const; 00886 #endif 00887 00888 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00889 00896 OpCodeMapPositionType 00897 getNextOpCodePosition(OpCodeMapPositionType opPos) const 00898 { 00899 assert(opPos < getInitialOpCodePosition() + opCodeMapLength()); 00900 00901 return opPos + *(opPos + s_opCodeMapLengthIndex); 00902 } 00903 #endif 00904 00912 OpCodeMapSizeType 00913 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00914 getNextOpCodePosition(OpCodeMapSizeType theIndex) const 00915 #else 00916 getNextOpCodePosition(OpCodeMapPositionType theIndex) const 00917 #endif 00918 { 00919 assert(theIndex < opCodeMapLength()); 00920 00921 assert(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex] == 00922 OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex])); 00923 00924 return OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex]); 00925 } 00926 00936 void 00937 setOpCodeArgs( 00938 eOpCodes theOpCode, 00939 OpCodeMapSizeType theIndex, 00940 const OpCodeMapValueVectorType& theArgs); 00941 00948 OpCodeMapSizeType 00949 appendOpCode(eOpCodes theOpCode); 00950 00957 OpCodeMapSizeType 00958 appendOpCode( 00959 eOpCodes theOpCode, 00960 const OpCodeMapValueVectorType& theArgs) 00961 { 00962 const OpCodeMapSizeType thePosition = appendOpCode(theOpCode); 00963 00964 setOpCodeArgs(theOpCode, 00965 thePosition, 00966 theArgs); 00967 00968 return thePosition; 00969 } 00970 00978 void 00979 replaceOpCode( 00980 OpCodeMapSizeType theIndex, 00981 eOpCodes theOldOpCode, 00982 eOpCodes theNewOpCode); 00983 00990 OpCodeMapValueType 00991 insertOpCode( 00992 eOpCodes theOpCode, 00993 OpCodeMapSizeType theIndex); 00994 01004 void 01005 updateOpCodeLength(OpCodeMapSizeType theIndex) 01006 { 01007 assert(theIndex < opCodeMapSize()); 01008 01009 updateOpCodeLength(m_opMap[theIndex], theIndex); 01010 } 01011 01020 void 01021 updateShiftedOpCodeLength( 01022 OpCodeMapValueType theOpCode, 01023 OpCodeMapSizeType theOriginalIndex, 01024 OpCodeMapSizeType theNewIndex); 01025 01036 void 01037 updateOpCodeLength( 01038 OpCodeMapValueType theOpCode, 01039 OpCodeMapSizeType theIndex); 01040 01048 static bool 01049 isNodeTestOpCode(OpCodeMapValueType theOpCode); 01050 01056 void 01057 updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType theIndex); 01058 01064 bool 01065 hasMoreTokens() const 01066 { 01067 return tokenQueueSize() > m_currentPosition ? true : false; 01068 } 01069 01075 TokenQueueSizeType 01076 tokenQueueSize() const 01077 { 01078 return TokenQueueSizeType(m_tokenQueue.size()); 01079 } 01080 01081 bool 01082 isValidTokenQueuePosition(TokenQueueSizeType thePosition) const 01083 { 01084 return thePosition < tokenQueueSize(); 01085 } 01086 01092 TokenQueueSizeType 01093 getTokenPosition() const 01094 { 01095 return m_currentPosition; 01096 } 01097 01101 void 01102 resetTokenPosition() 01103 { 01104 m_currentPosition = 0; 01105 } 01106 01113 const XToken* 01114 getToken(TokenQueuePositionType thePosition) const 01115 { 01116 assert(thePosition < tokenQueueSize()); 01117 01118 return &m_tokenQueue[thePosition]; 01119 } 01120 01126 const XToken* 01127 getNextToken() 01128 { 01129 if (hasMoreTokens() == true) 01130 { 01131 return getToken(m_currentPosition++); 01132 } 01133 else 01134 { 01135 return 0; 01136 } 01137 } 01138 01144 const XToken* 01145 getPreviousToken() 01146 { 01147 if (m_currentPosition > 0) 01148 { 01149 return getToken(--m_currentPosition); 01150 } 01151 else 01152 { 01153 return 0; 01154 } 01155 } 01156 01157 enum eRelativeDirection 01158 { 01159 eRelativeBackward, 01160 eRelativeForward 01161 }; 01162 01171 const XToken* 01172 getRelativeToken( 01173 TokenQueuePositionType theOffset, 01174 eRelativeDirection theDirection) const 01175 { 01176 const TokenQueuePositionType thePosition = 01177 calculateRelativePosition(theOffset, theDirection); 01178 01179 if (thePosition == tokenQueueSize()) 01180 { 01181 return 0; 01182 } 01183 else 01184 { 01185 return getToken(thePosition); 01186 } 01187 } 01188 01194 void 01195 pushToken(const XalanDOMString& theToken) 01196 { 01197 m_tokenQueue.push_back(XToken(theToken)); 01198 } 01199 01206 void 01207 pushToken( 01208 double theNumber, 01209 const XalanDOMString& theString) 01210 { 01211 m_tokenQueue.push_back(XToken(theNumber, theString)); 01212 } 01213 01220 void 01221 insertToken(const XalanDOMString& theToken) 01222 { 01223 m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken)); 01224 } 01225 01233 void 01234 insertToken( 01235 double theNumber, 01236 const XalanDOMString& theString) 01237 { 01238 m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theNumber, theString)); 01239 } 01240 01247 void 01248 replaceRelativeToken( 01249 TokenQueuePositionType theOffset, 01250 eRelativeDirection theDirection, 01251 const XalanDOMString& theString) 01252 { 01253 const TokenQueuePositionType thePosition = 01254 calculateRelativePosition(theOffset, theDirection); 01255 assert(thePosition < tokenQueueSize()); 01256 01257 m_tokenQueue[thePosition].set(theString); 01258 } 01259 01266 void 01267 dumpOpCodeMap( 01268 PrintWriter& thePrintWriter, 01269 OpCodeMapSizeType theStartPosition = 0) const; 01270 01277 void 01278 dumpOpCodeMap( 01279 OstreamType& theStream, 01280 OpCodeMapSizeType theStartPosition = 0) const; 01281 01288 void 01289 dumpTokenQueue( 01290 PrintWriter& thePrintWriter, 01291 TokenQueueSizeType theStartPosition = 0) const; 01292 01299 void 01300 dumpTokenQueue( 01301 OstreamType& theStream, 01302 TokenQueueSizeType theStartPosition = 0) const; 01303 01309 void 01310 dumpRemainingTokenQueue(PrintWriter& thePrintWriter) const; 01311 01317 void 01318 dumpRemainingTokenQueue(OstreamType& theStream) const; 01319 01326 void 01327 pushValueOnOpCodeMap(const OpCodeMapType::value_type& theValue) 01328 { 01329 // Push the index onto the op map. 01330 m_opMap.push_back(theValue); 01331 01332 // Update the op map length. 01333 ++m_opMap[s_opCodeMapLengthIndex]; 01334 } 01335 01342 void 01343 pushArgumentOnOpCodeMap(const XToken& theXToken); 01344 01351 void 01352 pushArgumentOnOpCodeMap(const XalanDOMString& theString); 01353 01361 void 01362 pushArgumentOnOpCodeMap( 01363 double theNumber, 01364 const XalanDOMString& theString); 01365 01372 void 01373 pushNumberLiteralOnOpCodeMap(double theNumber); 01374 01380 double 01381 getNumberLiteral(int theIndex) const 01382 { 01383 assert(theIndex >= 0 && 01384 NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size()); 01385 01386 return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)]; 01387 } 01388 01393 void 01394 pushCurrentTokenOnOpCodeMap(); 01395 01401 void 01402 setCurrentPattern(const XalanDOMString& thePattern) 01403 { 01404 m_currentPattern = &thePattern; 01405 } 01406 01412 const XalanDOMString& 01413 getCurrentPattern() const 01414 { 01415 assert(m_currentPattern != 0); 01416 01417 return *m_currentPattern; 01418 } 01419 01420 private: 01421 01431 TokenQueuePositionType 01432 calculateRelativePosition( 01433 TokenQueuePositionType theOffset, 01434 eRelativeDirection theDirection) const 01435 { 01436 if (theDirection == eRelativeBackward && 01437 theOffset <= m_currentPosition) 01438 { 01439 return m_currentPosition - theOffset; 01440 } 01441 else if (theDirection == eRelativeForward && 01442 m_currentPosition + theOffset < tokenQueueSize()) 01443 { 01444 return m_currentPosition + theOffset; 01445 } 01446 else 01447 { 01448 return tokenQueueSize(); 01449 } 01450 } 01451 01458 OpCodeMapType m_opMap; 01459 01464 OpCodeMapSizeType m_lastOpCodeIndex; 01465 01471 TokenQueueType m_tokenQueue; 01472 01476 TokenQueueSizeType m_currentPosition; 01477 01481 const XalanDOMString* m_currentPattern; 01482 01483 // Default vector allocation sizes. 01484 enum 01485 { 01486 eDefaultOpMapSize = 100, 01487 eDefaultTokenQueueSize = 30 01488 }; 01489 01490 NumberLiteralValueVectorType m_numberLiteralValues; 01491 }; 01492 01493 01494 01495 XALAN_CPP_NAMESPACE_END 01496 01497 01498 01499 #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++ XSLT Processor Version 1.8
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.