| /* |
| * Copyright 1999-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #if !defined(XALAN_XALANNAMESPACESSTACK_HEADER_GUARD) |
| #define XALAN_XALANNAMESPACESSTACK_HEADER_GUARD |
| |
| |
| |
| // Base include file. Must be first. |
| #include <xalanc/DOMSupport/DOMSupportDefinitions.hpp> |
| |
| |
| |
| #include <deque> |
| #include <vector> |
| |
| |
| |
| #include <xalanc/PlatformSupport/PrefixResolver.hpp> |
| #include <xalanc/PlatformSupport/XalanNamespace.hpp> |
| |
| |
| |
| XALAN_CPP_NAMESPACE_BEGIN |
| |
| |
| |
| class XalanDOMString; |
| |
| |
| |
| class XALAN_DOMSUPPORT_EXPORT XalanNamespacesStack |
| { |
| public: |
| |
| class XALAN_DOMSUPPORT_EXPORT PrefixResolverProxy : public PrefixResolver |
| { |
| public: |
| |
| /** |
| * Construct a PrefixResolver from a XalanNamespaceStack |
| * instance. |
| * |
| * @param theStack The stack to use for prefix resolution |
| * @param theURI The namespace URI of the resolver, if any. Only a reference is kept, so this cannot be a temporary |
| * @return pointer to the string value if found, otherwise 0. |
| */ |
| PrefixResolverProxy( |
| const XalanNamespacesStack& theStack, |
| const XalanDOMString& theURI); |
| |
| virtual |
| ~PrefixResolverProxy(); |
| |
| virtual const XalanDOMString* |
| getNamespaceForPrefix(const XalanDOMString& prefix) const; |
| |
| virtual const XalanDOMString& |
| getURI() const; |
| |
| private: |
| |
| const XalanNamespacesStack& m_stack; |
| |
| const XalanDOMString& m_uri; |
| }; |
| |
| class XALAN_DOMSUPPORT_EXPORT XalanNamespacesStackEntry |
| { |
| public: |
| |
| typedef XalanNamespace value_type; |
| |
| #if defined(XALAN_NO_STD_NAMESPACE) |
| typedef deque<value_type> NamespaceCollectionType; |
| #else |
| typedef std::deque<value_type> NamespaceCollectionType; |
| #endif |
| |
| typedef const XalanDOMString& (value_type::*MemberFunctionType)() const; |
| |
| typedef NamespaceCollectionType::iterator iterator; |
| typedef NamespaceCollectionType::reverse_iterator reverse_iterator; |
| typedef NamespaceCollectionType::const_iterator const_iterator; |
| typedef NamespaceCollectionType::const_reverse_iterator const_reverse_iterator; |
| |
| XalanNamespacesStackEntry(); |
| |
| XalanNamespacesStackEntry(const XalanNamespacesStackEntry& theSource); |
| |
| ~XalanNamespacesStackEntry(); |
| |
| XalanNamespacesStackEntry& |
| operator=(const XalanNamespacesStackEntry& theRHS); |
| |
| void |
| addDeclaration( |
| const XalanDOMString& thePrefix, |
| const XalanDOMChar* theNamespaceURI, |
| XalanDOMString::size_type theLength); |
| |
| /** |
| * Get the namespace for a prefix. |
| * |
| * @param thePrefix The prefix to find |
| * @return pointer to the string value if found, otherwise 0. |
| */ |
| const XalanDOMString* |
| getNamespaceForPrefix(const XalanDOMString& thePrefix) const |
| { |
| return findEntry(thePrefix, &XalanNamespace::getPrefix, &XalanNamespace::getURI); |
| } |
| |
| /** |
| * Get the prefix for a namespace. |
| * |
| * @param theURI The namespace URI to find |
| * @return pointer to the string value if found, otherwise 0. |
| */ |
| const XalanDOMString* |
| getPrefixForNamespace(const XalanDOMString& theURI) const |
| { |
| return findEntry(theURI, &XalanNamespace::getURI, &XalanNamespace::getPrefix); |
| } |
| |
| bool |
| isPrefixPresent(const XalanDOMString& thePrefix) const |
| { |
| return getNamespaceForPrefix(thePrefix) == 0 ? false : true; |
| } |
| |
| iterator |
| begin() |
| { |
| return m_namespaces.begin(); |
| } |
| |
| const_iterator |
| begin() const |
| { |
| return m_namespaces.begin(); |
| } |
| |
| iterator |
| end() |
| { |
| return m_position; |
| } |
| |
| const_iterator |
| end() const |
| { |
| return const_iterator(m_position); |
| } |
| |
| reverse_iterator |
| rbegin() |
| { |
| return reverse_iterator(end()); |
| } |
| |
| const_reverse_iterator |
| rbegin() const |
| { |
| return const_reverse_iterator(end()); |
| } |
| |
| reverse_iterator |
| rend() |
| { |
| return reverse_iterator(begin()); |
| } |
| |
| const_reverse_iterator |
| rend() const |
| { |
| return const_reverse_iterator(begin()); |
| } |
| |
| void |
| clear(); |
| |
| void |
| reset() |
| { |
| m_position = m_namespaces.begin(); |
| } |
| |
| void |
| swap(XalanNamespacesStackEntry& theOther); |
| |
| private: |
| |
| const XalanDOMString* |
| findEntry( |
| const XalanDOMString& theKey, |
| MemberFunctionType theKeyFunction, |
| MemberFunctionType theValueFunction) const; |
| |
| NamespaceCollectionType m_namespaces; |
| |
| iterator m_position; |
| }; |
| |
| |
| typedef XalanNamespacesStackEntry value_type; |
| |
| #if defined(XALAN_NO_STD_NAMESPACE) |
| typedef deque<value_type> NamespacesStackType; |
| #if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL) |
| typedef deque<bool> BoolVectorType; |
| #else |
| typedef vector<bool> BoolVectorType; |
| #endif |
| #else |
| typedef std::deque<value_type> NamespacesStackType; |
| #if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL) |
| typedef std::deque<bool> BoolVectorType; |
| #else |
| typedef std::vector<bool> BoolVectorType; |
| #endif |
| #endif |
| |
| typedef NamespacesStackType::iterator iterator; |
| typedef NamespacesStackType::reverse_iterator reverse_iterator; |
| typedef NamespacesStackType::const_iterator const_iterator; |
| typedef NamespacesStackType::const_reverse_iterator const_reverse_iterator; |
| |
| typedef NamespacesStackType::size_type size_type; |
| |
| typedef const XalanDOMString* (value_type::*MemberFunctionType)(const XalanDOMString&) const; |
| |
| |
| explicit |
| XalanNamespacesStack(); |
| |
| ~XalanNamespacesStack(); |
| |
| void |
| addDeclaration( |
| const XalanDOMString& thePrefix, |
| const XalanDOMString& theURI) |
| { |
| addDeclaration( |
| thePrefix, |
| theURI.c_str(), |
| theURI.length()); |
| } |
| |
| void |
| addDeclaration( |
| const XalanDOMString& thePrefix, |
| const XalanDOMChar* theURI) |
| { |
| addDeclaration( |
| thePrefix, |
| theURI, |
| length(theURI)); |
| } |
| |
| void |
| addDeclaration( |
| const XalanDOMString& thePrefix, |
| const XalanDOMChar* theURI, |
| XalanDOMString::size_type theLength); |
| |
| void |
| pushContext(); |
| |
| void |
| popContext(); |
| |
| const XalanDOMString* |
| getNamespaceForPrefix(const XalanDOMString& thePrefix) const; |
| |
| const XalanDOMString* |
| getPrefixForNamespace(const XalanDOMString& theURI) const |
| { |
| return findEntry(theURI, &value_type::getPrefixForNamespace); |
| } |
| |
| /** |
| * See if the prefix has been mapped to a namespace in the current |
| * context, without looking down the stack of namespaces. |
| */ |
| bool |
| prefixIsPresentLocal(const XalanDOMString& thePrefix); |
| |
| void |
| clear(); |
| |
| iterator |
| begin() |
| { |
| return m_stackBegin + 1; |
| } |
| |
| const_iterator |
| begin() const |
| { |
| return const_iterator(m_stackBegin + 1); |
| } |
| |
| iterator |
| end() |
| { |
| return m_stackPosition + 1; |
| } |
| |
| const_iterator |
| end() const |
| { |
| return const_iterator(m_stackPosition + 1); |
| } |
| |
| reverse_iterator |
| rbegin() |
| { |
| return reverse_iterator(end()); |
| } |
| |
| const_reverse_iterator |
| rbegin() const |
| { |
| return const_reverse_iterator(end()); |
| } |
| |
| reverse_iterator |
| rend() |
| { |
| return reverse_iterator(begin()); |
| } |
| |
| const_reverse_iterator |
| rend() const |
| { |
| return const_reverse_iterator(begin()); |
| } |
| |
| size_type |
| size() const |
| { |
| return m_resultNamespaces.size() - 1; |
| } |
| |
| bool |
| empty() const |
| { |
| return NamespacesStackType::const_iterator(m_stackPosition) == m_resultNamespaces.begin() ? true : false; |
| } |
| |
| private: |
| |
| // not implemented |
| XalanNamespacesStack(const XalanNamespacesStack&); |
| |
| bool |
| operator==(const XalanNamespacesStack&) const; |
| |
| XalanNamespacesStack& |
| operator=(const XalanNamespacesStack&); |
| |
| enum { eDefaultCreateNewContextStackSize = 25 }; |
| |
| const XalanDOMString* |
| findEntry( |
| const XalanDOMString& theKey, |
| MemberFunctionType theFunction) const; |
| |
| /** |
| * A stack to keep track of the result tree namespaces. |
| */ |
| NamespacesStackType m_resultNamespaces; |
| |
| NamespacesStackType::iterator m_stackBegin; |
| |
| NamespacesStackType::iterator m_stackPosition; |
| |
| BoolVectorType m_createNewContextStack; |
| }; |
| |
| |
| |
| XALAN_CPP_NAMESPACE_END |
| |
| |
| |
| #endif // XALAN_XALANNAMESPACESSTACK_HEADER_GUARD |