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 <xalanc/Include/XalanVector.hpp> 00027 00028 00029 00030 #if defined(XALAN_CLASSIC_IOSTREAMS) 00031 #include <iostream.h> 00032 #else 00033 #include <iosfwd> 00034 #endif 00035 00036 00037 00038 #include <xalanc/XalanDOM/XalanDOMString.hpp> 00039 00040 00041 00042 #include <xalanc/PlatformSupport/DOMStringHelper.hpp> 00043 #include <xalanc/PlatformSupport/PrintWriter.hpp> 00044 00045 00046 00047 #include <xalanc/XPath/XToken.hpp> 00048 #include <xalanc/XPath/XalanXPathException.hpp> 00049 00050 00051 00052 XALAN_CPP_NAMESPACE_BEGIN 00053 00054 00055 00056 XALAN_USING_XERCES(MemoryManager) 00057 00058 00059 00060 class XALAN_XPATH_EXPORT XPathExpression 00061 { 00062 public: 00063 00064 typedef XALAN_STD_QUALIFIER ostream OstreamType; 00065 00066 typedef XalanVector<int> OpCodeMapType; 00067 typedef XalanVector<XToken> TokenQueueType; 00068 00069 typedef OpCodeMapType::value_type OpCodeMapValueType; 00070 typedef OpCodeMapValueType OpCodeMapSizeType; 00071 00072 typedef XalanVector<OpCodeMapValueType> OpCodeMapValueVectorType; 00073 00074 typedef XalanVector<double> NumberLiteralValueVectorType; 00075 00076 #define XALAN_XPATH_EXPRESSION_USE_ITERATORS 00077 00078 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00079 typedef OpCodeMapType::const_iterator OpCodeMapPositionType; 00080 #else 00081 typedef OpCodeMapSizeType OpCodeMapPositionType; 00082 #endif 00083 typedef OpCodeMapType::difference_type OpCodeMapDifferenceType; 00084 typedef TokenQueueType::value_type TokenQueueValueType; 00085 typedef int TokenQueueSizeType; 00086 typedef TokenQueueSizeType TokenQueuePositionType; 00087 00106 enum eOpCodes 00107 { 00113 eELEMWILDCARD = -3, 00114 00119 eEMPTY = -2, 00120 00125 eENDOP = -1, 00126 00140 eOP_XPATH = 1, 00141 00151 eOP_OR = 2, 00152 00162 eOP_AND = 3, 00163 00173 eOP_NOTEQUALS = 4, 00174 00184 eOP_EQUALS = 5, 00185 00195 eOP_LTE = 6, 00196 00206 eOP_LT = 7, 00207 00217 eOP_GTE = 8, 00218 00228 eOP_GT = 9, 00229 00239 eOP_PLUS = 10, 00240 00250 eOP_MINUS = 11, 00251 00261 eOP_MULT = 12, 00262 00272 eOP_DIV = 13, 00273 00283 eOP_MOD = 14, 00284 00293 eOP_NEG = 15, 00294 00303 eOP_BOOL = 16, 00304 00313 eOP_UNION = 17, 00314 00323 eOP_LITERAL = 18, 00324 00333 eOP_VARIABLE = 19, 00334 00348 eOP_GROUP = 20, 00349 00358 eOP_NUMBERLIT = 21, 00359 00373 eOP_ARGUMENT = 22, 00374 00390 eOP_EXTFUNCTION = 23, 00391 00408 eOP_FUNCTION = 24, 00409 00423 eOP_LOCATIONPATH = 25, 00424 00434 eOP_PREDICATE = 26, 00435 00443 eNODETYPE_COMMENT = 27, 00444 00452 eNODETYPE_TEXT = 28, 00453 00461 eNODETYPE_PI = 29, 00462 00470 eNODETYPE_NODE = 30, 00471 00480 eNODENAME = 31, 00481 00489 eNODETYPE_ROOT = 32, 00490 00498 eNODETYPE_ANYELEMENT = 33, 00499 00510 eFROM_ANCESTORS = 34, 00511 eFROM_ANCESTORS_OR_SELF = 35, 00512 eFROM_ATTRIBUTES = 36, 00513 eFROM_CHILDREN = 37, 00514 eFROM_DESCENDANTS = 38, 00515 eFROM_DESCENDANTS_OR_SELF = 39, 00516 eFROM_FOLLOWING = 40, 00517 eFROM_FOLLOWING_SIBLINGS = 41, 00518 eFROM_PARENT = 42, 00519 eFROM_PRECEDING = 43, 00520 eFROM_PRECEDING_SIBLINGS = 44, 00521 eFROM_SELF = 45, 00522 eFROM_NAMESPACE = 46, 00523 eFROM_ROOT = 47, 00524 00533 eOP_MATCHPATTERN = 48, 00534 00543 eOP_LOCATIONPATHPATTERN = 49, 00544 00545 // For match patterns 00546 eMATCH_ATTRIBUTE = 50, 00547 eMATCH_ANY_ANCESTOR = 51, 00548 eMATCH_IMMEDIATE_ANCESTOR = 52, 00549 eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53, 00550 eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54, 00551 00561 eOP_PREDICATE_WITH_POSITION = 55, 00562 00567 eOP_FUNCTION_POSITION = 56, 00568 eOP_FUNCTION_LAST = 57, 00569 eOP_FUNCTION_COUNT = 58, 00570 eOP_FUNCTION_NOT = 59, 00571 eOP_FUNCTION_TRUE = 60, 00572 eOP_FUNCTION_FALSE = 61, 00573 eOP_FUNCTION_BOOLEAN = 62, 00574 eOP_FUNCTION_NAME_0 = 63, 00575 eOP_FUNCTION_NAME_1 = 64, 00576 eOP_FUNCTION_LOCALNAME_0 = 65, 00577 eOP_FUNCTION_LOCALNAME_1 = 66, 00578 eOP_FUNCTION_FLOOR = 67, 00579 eOP_FUNCTION_CEILING = 68, 00580 eOP_FUNCTION_ROUND = 69, 00581 eOP_FUNCTION_NUMBER_0 = 70, 00582 eOP_FUNCTION_NUMBER_1 = 71, 00583 eOP_FUNCTION_STRING_0 = 72, 00584 eOP_FUNCTION_STRING_1 = 73, 00585 eOP_FUNCTION_STRINGLENGTH_0 = 74, 00586 eOP_FUNCTION_STRINGLENGTH_1 = 75, 00587 eOP_FUNCTION_NAMESPACEURI_0 = 76, 00588 eOP_FUNCTION_NAMESPACEURI_1 = 77, 00589 eOP_FUNCTION_SUM = 78, 00590 eOP_FUNCTION_CONCAT = 79, 00591 00592 // Always add _before_ this one and update 00593 // s_opCodeLengthArray. 00594 eOpCodeNextAvailable 00595 }; // enum eOpCodes 00596 00600 class XALAN_XPATH_EXPORT XPathExpressionException : public XalanXPathException 00601 { 00602 public: 00603 00609 XPathExpressionException(const XalanDOMString& theMessage, 00610 MemoryManagerType& theManager); 00611 00612 virtual~ 00613 XPathExpressionException(); 00614 }; 00615 00619 class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException 00620 { 00621 public: 00622 00628 InvalidOpCodeException(OpCodeMapValueType theOpCode, 00629 XalanDOMString& theResult); 00630 00631 virtual~ 00632 InvalidOpCodeException(); 00633 00634 private: 00635 00636 static XalanDOMString& 00637 FormatErrorMessage(OpCodeMapValueType theOpCode, 00638 XalanDOMString& theResult); 00639 }; 00640 00645 class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException 00646 { 00647 public: 00648 00656 InvalidArgumentCountException( 00657 OpCodeMapValueType theOpCode, 00658 OpCodeMapValueType theExpectedCount, 00659 OpCodeMapValueType theSuppliedCount, 00660 XalanDOMString& theResult); 00661 00662 virtual~ 00663 InvalidArgumentCountException(); 00664 00665 private: 00666 00667 static XalanDOMString& 00668 FormatErrorMessage( 00669 OpCodeMapValueType theOpCode, 00670 OpCodeMapValueType theExpectedCount, 00671 OpCodeMapValueType theSuppliedCount, 00672 XalanDOMString& theResult); 00673 }; 00674 00678 class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException 00679 { 00680 public: 00681 00688 InvalidArgumentException( 00689 OpCodeMapValueType theOpCode, 00690 OpCodeMapValueType theValue, 00691 XalanDOMString& theResult); 00692 00693 virtual~ 00694 InvalidArgumentException(); 00695 00696 private: 00697 00698 static XalanDOMString& 00699 FormatErrorMessage( 00700 OpCodeMapValueType theOpCode, 00701 OpCodeMapValueType theValue, 00702 XalanDOMString& theResult); 00703 }; 00704 00705 00712 #if defined(XALAN_INLINE_INITIALIZATION) 00713 static const TokenQueueSizeType s_opCodeMapLengthIndex = 1; 00714 #else 00715 enum eDummy 00716 { 00717 s_opCodeMapLengthIndex = 1 00718 }; 00719 #endif 00720 00721 explicit 00722 XPathExpression(MemoryManagerType& theManager); 00723 00724 ~XPathExpression(); 00725 00726 MemoryManagerType& 00727 getMemoryManager() 00728 { 00729 return m_opMap.getMemoryManager(); 00730 } 00734 void 00735 reset(); 00736 00740 void 00741 shrink(); 00742 00748 OpCodeMapSizeType 00749 opCodeMapSize() const 00750 { 00751 return OpCodeMapSizeType(m_opMap.size()); 00752 } 00753 00765 OpCodeMapValueType 00766 opCodeMapLength() const 00767 { 00768 const OpCodeMapSizeType theSize = opCodeMapSize(); 00769 00770 if (theSize > s_opCodeMapLengthIndex) 00771 { 00772 assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex])); 00773 00774 return m_opMap[s_opCodeMapLengthIndex]; 00775 } 00776 else 00777 { 00778 assert(theSize == OpCodeMapValueType(theSize)); 00779 00780 return OpCodeMapValueType(theSize); 00781 } 00782 } 00783 00784 OpCodeMapPositionType 00785 getInitialOpCodePosition() const 00786 { 00787 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00788 return m_opMap.begin(); 00789 #else 00790 return 0; 00791 #endif 00792 } 00793 00794 bool 00795 isValidOpCodePosition(OpCodeMapPositionType opPos) const 00796 { 00797 const OpCodeMapDifferenceType theDifference = 00798 OpCodeMapDifferenceType(opPos - getInitialOpCodePosition()); 00799 00800 return theDifference >= 0 && 00801 theDifference < opCodeMapSize(); 00802 } 00803 00804 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00805 bool 00806 isValidOpCodePosition(OpCodeMapSizeType theIndex) const 00807 { 00808 return theIndex >= 0 && theIndex < opCodeMapSize(); 00809 } 00810 00818 OpCodeMapValueType 00819 getOpCodeMapValue(OpCodeMapSizeType theIndex) const 00820 { 00821 assert(theIndex < opCodeMapLength()); 00822 00823 return m_opMap[theIndex]; 00824 } 00825 #endif 00826 00834 OpCodeMapValueType 00835 getOpCodeMapValue(OpCodeMapPositionType opPos) const 00836 { 00837 assert(opPos < getInitialOpCodePosition() + opCodeMapLength()); 00838 00839 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00840 return *opPos; 00841 #else 00842 00843 return m_opMap[opPos]; 00844 #endif 00845 } 00846 00854 void 00855 setOpCodeMapValue( 00856 OpCodeMapSizeType theOpCodeMapIndex, 00857 const OpCodeMapValueType& theValue) 00858 { 00859 assert(theOpCodeMapIndex < opCodeMapLength()); 00860 00861 m_opMap[theOpCodeMapIndex] = theValue; 00862 } 00863 00864 OpCodeMapValueType 00865 getOpCodeArgumentLength(OpCodeMapPositionType opPos) const 00866 { 00867 return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3; 00868 } 00869 00877 OpCodeMapValueType 00878 getOpCodeLengthFromOpMap(OpCodeMapPositionType opPos, 00879 MemoryManagerType& theManager) const; 00880 00881 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00882 00889 OpCodeMapValueType 00890 getOpCodeLengthFromOpMap(OpCodeMapSizeType theIndex, 00891 MemoryManagerType& theManager) const; 00892 #endif 00893 00894 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00895 00902 OpCodeMapPositionType 00903 getNextOpCodePosition(OpCodeMapPositionType opPos) const 00904 { 00905 assert(opPos < getInitialOpCodePosition() + opCodeMapLength()); 00906 00907 return opPos + *(opPos + s_opCodeMapLengthIndex); 00908 } 00909 #endif 00910 00918 OpCodeMapSizeType 00919 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS) 00920 getNextOpCodePosition(OpCodeMapSizeType theIndex) const 00921 #else 00922 getNextOpCodePosition(OpCodeMapPositionType theIndex) const 00923 #endif 00924 { 00925 assert(theIndex < opCodeMapLength()); 00926 00927 assert(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex] == 00928 OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex])); 00929 00930 return OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex]); 00931 } 00932 00942 void 00943 setOpCodeArgs( 00944 eOpCodes theOpCode, 00945 OpCodeMapSizeType theIndex, 00946 const OpCodeMapValueVectorType& theArgs); 00947 00954 OpCodeMapSizeType 00955 appendOpCode(eOpCodes theOpCode); 00956 00963 OpCodeMapSizeType 00964 appendOpCode( 00965 eOpCodes theOpCode, 00966 const OpCodeMapValueVectorType& theArgs) 00967 { 00968 const OpCodeMapSizeType thePosition = appendOpCode(theOpCode); 00969 00970 setOpCodeArgs(theOpCode, 00971 thePosition, 00972 theArgs); 00973 00974 return thePosition; 00975 } 00976 00984 void 00985 replaceOpCode( 00986 OpCodeMapSizeType theIndex, 00987 eOpCodes theOldOpCode, 00988 eOpCodes theNewOpCode); 00989 00996 OpCodeMapValueType 00997 insertOpCode( 00998 eOpCodes theOpCode, 00999 OpCodeMapSizeType theIndex); 01000 01010 void 01011 updateOpCodeLength(OpCodeMapSizeType theIndex) 01012 { 01013 assert(theIndex < opCodeMapSize()); 01014 01015 updateOpCodeLength(m_opMap[theIndex], theIndex); 01016 } 01017 01026 void 01027 updateShiftedOpCodeLength( 01028 OpCodeMapValueType theOpCode, 01029 OpCodeMapSizeType theOriginalIndex, 01030 OpCodeMapSizeType theNewIndex); 01031 01042 void 01043 updateOpCodeLength( 01044 OpCodeMapValueType theOpCode, 01045 OpCodeMapSizeType theIndex); 01046 01054 static bool 01055 isNodeTestOpCode(OpCodeMapValueType theOpCode); 01056 01062 void 01063 updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType theIndex); 01064 01070 bool 01071 hasMoreTokens() const 01072 { 01073 return tokenQueueSize() > m_currentPosition ? true : false; 01074 } 01075 01081 TokenQueueSizeType 01082 tokenQueueSize() const 01083 { 01084 return TokenQueueSizeType(m_tokenQueue.size()); 01085 } 01086 01087 bool 01088 isValidTokenQueuePosition(TokenQueueSizeType thePosition) const 01089 { 01090 return thePosition < tokenQueueSize(); 01091 } 01092 01098 TokenQueueSizeType 01099 getTokenPosition() const 01100 { 01101 return m_currentPosition; 01102 } 01103 01107 void 01108 resetTokenPosition() 01109 { 01110 m_currentPosition = 0; 01111 } 01112 01119 const XToken* 01120 getToken(TokenQueuePositionType thePosition) const 01121 { 01122 assert(thePosition < tokenQueueSize()); 01123 01124 return &m_tokenQueue[thePosition]; 01125 } 01126 01132 const XToken* 01133 getNextToken() 01134 { 01135 if (hasMoreTokens() == true) 01136 { 01137 return getToken(m_currentPosition++); 01138 } 01139 else 01140 { 01141 return 0; 01142 } 01143 } 01144 01150 const XToken* 01151 getPreviousToken() 01152 { 01153 if (m_currentPosition > 0) 01154 { 01155 return getToken(--m_currentPosition); 01156 } 01157 else 01158 { 01159 return 0; 01160 } 01161 } 01162 01163 enum eRelativeDirection 01164 { 01165 eRelativeBackward, 01166 eRelativeForward 01167 }; 01168 01177 const XToken* 01178 getRelativeToken( 01179 TokenQueuePositionType theOffset, 01180 eRelativeDirection theDirection) const 01181 { 01182 const TokenQueuePositionType thePosition = 01183 calculateRelativePosition(theOffset, theDirection); 01184 01185 if (thePosition == 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, getMemoryManager())); 01204 } 01205 01212 void 01213 pushToken( 01214 double theNumber, 01215 const XalanDOMString& theString) 01216 { 01217 m_tokenQueue.push_back(XToken(theNumber, theString)); 01218 } 01219 01226 void 01227 insertToken(const XalanDOMString& theToken) 01228 { 01229 m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken, getMemoryManager())); 01230 } 01231 01239 void 01240 insertToken( 01241 double theNumber, 01242 const XalanDOMString& theString) 01243 { 01244 m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theNumber, theString)); 01245 } 01246 01253 void 01254 replaceRelativeToken( 01255 TokenQueuePositionType theOffset, 01256 eRelativeDirection theDirection, 01257 const XalanDOMString& theString) 01258 { 01259 const TokenQueuePositionType thePosition = 01260 calculateRelativePosition(theOffset, theDirection); 01261 assert(thePosition < tokenQueueSize()); 01262 01263 m_tokenQueue[thePosition].set(theString, getMemoryManager()); 01264 } 01265 01272 void 01273 dumpOpCodeMap( 01274 PrintWriter& thePrintWriter, 01275 OpCodeMapSizeType theStartPosition = 0) const; 01276 01283 void 01284 dumpOpCodeMap( 01285 OstreamType& theStream, 01286 OpCodeMapSizeType theStartPosition = 0) const; 01287 01294 void 01295 dumpTokenQueue( 01296 PrintWriter& thePrintWriter, 01297 TokenQueueSizeType theStartPosition = 0) const; 01298 01305 void 01306 dumpTokenQueue( 01307 OstreamType& theStream, 01308 TokenQueueSizeType theStartPosition = 0) const; 01309 01315 void 01316 dumpRemainingTokenQueue(PrintWriter& thePrintWriter) const; 01317 01324 void 01325 dumpRemainingTokenQueue( 01326 OstreamType& theStream, 01327 MemoryManager& theMemoryManager) const; 01328 01335 void 01336 pushValueOnOpCodeMap(const OpCodeMapType::value_type& theValue) 01337 { 01338 // Push the index onto the op map. 01339 m_opMap.push_back(theValue); 01340 01341 // Update the op map length. 01342 ++m_opMap[s_opCodeMapLengthIndex]; 01343 } 01344 01351 void 01352 pushArgumentOnOpCodeMap(const XToken& theXToken); 01353 01360 void 01361 pushArgumentOnOpCodeMap(const XalanDOMString& theString); 01362 01370 void 01371 pushArgumentOnOpCodeMap( 01372 double theNumber, 01373 const XalanDOMString& theString); 01374 01381 void 01382 pushNumberLiteralOnOpCodeMap(double theNumber); 01383 01389 double 01390 getNumberLiteral(int theIndex) const 01391 { 01392 assert(theIndex >= 0 && 01393 NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size()); 01394 01395 return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)]; 01396 } 01397 01402 void 01403 pushCurrentTokenOnOpCodeMap(); 01404 01410 void 01411 setCurrentPattern(const XalanDOMString& thePattern) 01412 { 01413 m_currentPattern = &thePattern; 01414 } 01415 01421 const XalanDOMString& 01422 getCurrentPattern() const 01423 { 01424 assert(m_currentPattern != 0); 01425 01426 return *m_currentPattern; 01427 } 01428 01429 private: 01430 01440 TokenQueuePositionType 01441 calculateRelativePosition( 01442 TokenQueuePositionType theOffset, 01443 eRelativeDirection theDirection) const 01444 { 01445 if (theDirection == eRelativeBackward && 01446 theOffset <= m_currentPosition) 01447 { 01448 return m_currentPosition - theOffset; 01449 } 01450 else if (theDirection == eRelativeForward && 01451 m_currentPosition + theOffset < tokenQueueSize()) 01452 { 01453 return m_currentPosition + theOffset; 01454 } 01455 else 01456 { 01457 return tokenQueueSize(); 01458 } 01459 } 01460 01467 OpCodeMapType m_opMap; 01468 01473 OpCodeMapSizeType m_lastOpCodeIndex; 01474 01480 TokenQueueType m_tokenQueue; 01481 01485 TokenQueueSizeType m_currentPosition; 01486 01490 const XalanDOMString* m_currentPattern; 01491 01492 // Default vector allocation sizes. 01493 enum 01494 { 01495 eDefaultOpMapSize = 100, 01496 eDefaultTokenQueueSize = 30 01497 }; 01498 01499 NumberLiteralValueVectorType m_numberLiteralValues; 01500 }; 01501 01502 01503 01504 XALAN_CPP_NAMESPACE_END 01505 01506 01507 01508 #endif // XPATHEXPRESSION_HEADER_GUARD_1357924680
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
Xalan-C++ XSLT Processor Version 1.10 |
|