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
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSL Transformer Version 1.1 |
|