You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@apache.org on 2002/10/11 03:55:47 UTC

cvs commit: xml-xalan/c/src/DOMSupport XalanNamespacesStack.cpp XalanNamespacesStack.hpp

dbertoni    2002/10/10 18:55:47

  Added:       c/src/DOMSupport XalanNamespacesStack.cpp
                        XalanNamespacesStack.hpp
  Log:
  Initial revision.
  
  Revision  Changes    Path
  1.1                  xml-xalan/c/src/DOMSupport/XalanNamespacesStack.cpp
  
  Index: XalanNamespacesStack.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  // Class header file...
  #include "XalanNamespacesStack.hpp"
  
  
  
  #include "DOMServices.hpp"
  
  
  
  XalanNamespacesStack::XalanNamespacesStackEntry::XalanNamespacesStackEntry() :
  	m_namespaces(),
  	m_position(m_namespaces.begin())
  {
  }
  
  
  
  XalanNamespacesStack::XalanNamespacesStackEntry::XalanNamespacesStackEntry(const XalanNamespacesStackEntry&		theSource) :
  	m_namespaces(theSource.m_namespaces),
  	m_position(m_namespaces.begin() + (const_iterator(theSource.m_position) - theSource.m_namespaces.begin()))
  {
  }
  
  
  
  XalanNamespacesStack::XalanNamespacesStackEntry&
  XalanNamespacesStack::XalanNamespacesStackEntry::operator=(const XalanNamespacesStackEntry&		theRHS)
  {
  	if (this != &theRHS)
  	{
  		XalanNamespacesStackEntry	theCopy(theRHS);
  
  		swap(theCopy);
  	}
  
  	return *this;
  }
  
  
  
  XalanNamespacesStack::XalanNamespacesStackEntry::~XalanNamespacesStackEntry()
  {
  }
  
  
  
  void
  XalanNamespacesStack::XalanNamespacesStackEntry::swap(XalanNamespacesStackEntry&	theOther)
  {
  	m_namespaces.swap(theOther.m_namespaces);
  
  	const iterator	theTemp = theOther.m_position;
  
  	theOther.m_position = m_position;
  
  	m_position = theTemp;
  }
  
  
  
  void
  XalanNamespacesStack::XalanNamespacesStackEntry::addDeclaration(
  				const XalanDOMString&		thePrefix,
  				const XalanDOMChar*			theURI,
  				XalanDOMString::size_type	theLength)
  {
  	if (m_position == m_namespaces.end())
  	{
  		m_namespaces.resize(m_namespaces.size() + 1);
  
  		m_position = m_namespaces.end() - 1;
  	}
  
  	XalanNamespace&		theNamespace = *m_position;
  
  	theNamespace.setPrefix(thePrefix);
  
  	theNamespace.setURI(theURI, theLength);
  
  	++m_position;
  }
  
  
  
  const XalanDOMString*
  XalanNamespacesStack::XalanNamespacesStackEntry::getNamespaceForPrefix(const XalanDOMString&	thePrefix) const
  {
  	if (m_namespaces.empty() == false)
  	{
  		const_iterator	i(m_position);
  
  		do
  		{
  			--i;
  
  			const XalanNamespace&	ns = (*i);
  
  			const XalanDOMString&	thisPrefix = ns.getPrefix();
  
  			if(equals(thePrefix, thisPrefix))
  			{
  				return &ns.getURI();
  			}
  		} while (i != m_namespaces.begin());
  	}
  
  	return 0;
  }
  
  
  
  const XalanDOMString*
  XalanNamespacesStack::XalanNamespacesStackEntry::getPrefixForNamespace(const XalanDOMString&	theURI) const
  {
  	if (m_namespaces.empty() == false)
  	{
  		const_iterator	i(m_position);
  
  		do
  		{
  			--i;
  
  			const XalanNamespace&	ns = (*i);
  
  			const XalanDOMString&	thisURI = ns.getURI();
  
  			if(equals(theURI, thisURI))
  			{
  				return &ns.getPrefix();
  			}
  		} while (i != m_namespaces.begin());
  	}
  
  	return 0;
  }
  
  
  
  void
  XalanNamespacesStack::XalanNamespacesStackEntry::clear()
  {
  	m_namespaces.clear();
  
  	m_position = m_namespaces.begin();
  }
  
  
  
  XalanNamespacesStack::XalanNamespacesStack() :
  	m_resultNamespaces(1),
  	m_stackBegin(m_resultNamespaces.begin()),
  	m_stackPosition(m_stackBegin),
  	m_createNewContextStack()
  {
  	// m_resultNamespaces is initialized to a size of
  	// 1, so we always have a dummy entry at the
  	// beginning.  This makes the implementation
  	// much simpler.
  }
  
  
  
  XalanNamespacesStack::~XalanNamespacesStack()
  {
  }
  
  
  
  void
  XalanNamespacesStack::addDeclaration(
  			const XalanDOMString&		thePrefix,
  	        const XalanDOMChar*			theURI,
  			XalanDOMString::size_type	theLength)
  {
  	assert(theURI != 0);
  	assert(m_createNewContextStack.size() != 0);
  
  	// Check to see if we need to create a new context and do so if necessary...
  	if (m_createNewContextStack.back() == true)
  	{
  		++m_stackPosition;
  
  		if (m_stackPosition == m_resultNamespaces.end())
  		{
  			m_resultNamespaces.resize(m_resultNamespaces.size() + 1);
  
  			m_stackPosition = m_resultNamespaces.end() - 1;
  			m_stackBegin = m_resultNamespaces.begin();
  		}
  
  		m_createNewContextStack.back() = false;
  	}
  
  	XalanNamespacesStackEntry&	theCurrentEntry = *m_stackPosition;
  
  	// Add a new namespace declaration...
  	theCurrentEntry.addDeclaration(thePrefix, theURI, theLength);
  }
  
  
  
  void
  XalanNamespacesStack::pushContext()
  {
  	if (m_createNewContextStack.empty() == true)
  	{
  		m_createNewContextStack.reserve(eDefaultCreateNewContextStackSize);
  	}
  
  	m_createNewContextStack.push_back(true);
  }
  
  
  
  void
  XalanNamespacesStack::popContext()
  {
  	assert(m_createNewContextStack.empty() == false);
  
  	if (m_createNewContextStack.back() == false)
  	{
  		assert(m_resultNamespaces.empty() == false &&
  			   m_stackPosition != m_resultNamespaces.begin());
  
  		(*m_stackPosition).reset();
  
  		--m_stackPosition;
  	}
  
  	m_createNewContextStack.pop_back();
  }
  
  
  
  const XalanDOMString*
  XalanNamespacesStack::getNamespaceForPrefix(const XalanDOMString&	thePrefix) const
  {
  	if(::equals(thePrefix, DOMServices::s_XMLString))
  	{
  		return &DOMServices::s_XMLNamespaceURI;
  	}
  	else if (::equals(thePrefix, DOMServices::s_XMLNamespace))
  	{
  		return &DOMServices::s_XMLNamespacePrefixURI;
  	}
  	else if (m_stackPosition == m_stackBegin)
  	{
  		return 0;
  	}
  	else
  	{
  		NamespacesStackType::const_iterator		theBegin(m_stackBegin);
  		NamespacesStackType::const_iterator		theEnd(m_stackPosition + 1);
  
  		const XalanDOMString*	nsURI = 0;
  
  		if (theBegin != theEnd)
  		{
  			do
  			{
  				nsURI = (*(--theEnd)).getNamespaceForPrefix(thePrefix);
  
  				if (nsURI != 0)
  				{
  					break;
  				}
  			} while(theBegin != theEnd);
  		}
  
  		return nsURI;
  	}
  }
  
  
  
  const XalanDOMString*
  XalanNamespacesStack::getPrefixForNamespace(const XalanDOMString&	theURI) const
  {
  	if (m_stackPosition == m_stackBegin)
  	{
  		return 0;
  	}
  	else
  	{
  		NamespacesStackType::const_iterator		theBegin(m_stackBegin);
  		NamespacesStackType::const_iterator		theEnd(m_stackPosition + 1);
  
  		const XalanDOMString*	prefix = 0;
  
  		if (theBegin != theEnd)
  		{
  			do
  			{
  				prefix = (*(--theEnd)).getPrefixForNamespace(theURI);
  
  				if (prefix != 0)
  				{
  					break;
  				}
  			} while(theBegin != theEnd);
  		}
  
  		return prefix;
  	}
  }
  
  
  
  bool
  XalanNamespacesStack::prefixIsPresentLocal(const XalanDOMString&	thePrefix)
  {
  	// Check to see if we need to create a new context.  If so, there are
  	// no prefixes mapped at this level, so return false...
  	if (m_createNewContextStack.back() == true)
  	{
  		return false;
  	}
  	else
  	{
  		const XalanNamespacesStackEntry&	theNamespaces =
  			*m_stackPosition;
  
  		return theNamespaces.isPrefixPresent(thePrefix);
  	}
  }
  
  
  
  void
  XalanNamespacesStack::clear()
  {
  	// Since we always keep one dummy entry at the beginning,
  	// swap with an OutputContextStackType instance of size 1.
  	NamespacesStackType(1).swap(m_resultNamespaces);
  
  	m_stackBegin = m_resultNamespaces.begin();
  
  	m_stackPosition = m_stackBegin;
  
  	m_createNewContextStack.clear();
  }
  
  
  
  const XalanDOMString*
  XalanNamespacesStack::getNamespaceForPrefix(
  			NamespacesStackType::const_iterator		theBegin,
  			NamespacesStackType::const_iterator		theEnd,
  			const XalanDOMString&					prefix)
  {
  	const XalanDOMString*	nsURI = 0;
  
  	if (theBegin != theEnd)
  	{
  		do
  		{
  			nsURI = (*(--theEnd)).getNamespaceForPrefix(prefix);
  
  			if (nsURI != 0)
  			{
  				break;
  			}
  		} while(theBegin != theEnd);
  	}
  
  	return nsURI;
  }
  
  
  
  1.1                  xml-xalan/c/src/DOMSupport/XalanNamespacesStack.hpp
  
  Index: XalanNamespacesStack.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  #if !defined(XALAN_XALANNAMESPACESSTACK_HEADER_GUARD)
  #define XALAN_XALANNAMESPACESSTACK_HEADER_GUARD
  
  
  
  // Base include file.  Must be first.
  #include <DOMSupport/DOMSupportDefinitions.hpp>
  
  
  
  #include <deque>
  #include <vector>
  
  
  
  #include <XalanDOM/XalanDOMString.hpp>
  
  
  
  #include <PlatformSupport/XalanNamespace.hpp>
  
  
  
  class XALAN_DOMSUPPORT_EXPORT XalanNamespacesStack
  {
  public:
  
  	class XALAN_DOMSUPPORT_EXPORT XalanNamespacesStackEntry
  	{
  	public:
  
  #if defined(XALAN_NO_NAMESPACES)
  		typedef	deque<XalanNamespace>		NamespaceCollectionType;
  #else
  		typedef	std::deque<XalanNamespace>	NamespaceCollectionType;
  #endif
  
  		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;
  
  		/**
  		 * 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;
  
  		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_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:
  
  		NamespaceCollectionType		m_namespaces;
  
  		iterator					m_position;
  	};
  
  #if defined(XALAN_NO_NAMESPACES)
  	typedef	deque<XalanNamespacesStackEntry>	NamespacesStackType;
  	typedef vector<bool>						BoolVectorType;
  #else
  	typedef	std::deque<XalanNamespacesStackEntry>	NamespacesStackType;
  	typedef std::vector<bool>						BoolVectorType;
  #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;
  
  
  	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;
  
  	/**
  	 * 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_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:
  
  	/**
  	 * Get the namespace for a prefix by searching a range of iterators.
  	 * The search is done in reverse, from the end of the range to the
  	 * beginning.
  	 *
  	 * @param theBegin The beginning iterator for the range
  	 * @param theBegin The ending iterator for the range
  	 * @param prefix  namespace prefix to find
  	 * @return pointer to the string value if found, otherwise null.
  	 */
  	static const XalanDOMString*
  	getNamespaceForPrefix(
  			NamespacesStackType::const_iterator		theBegin,
  			NamespacesStackType::const_iterator		theEnd,
  			const XalanDOMString&					prefix);
  
  	/**
  	 * Get the prefix for a namespace by searching a range of iterators.
  	 * The search is done in reverse, from the end of the range to the
  	 * beginning.
  	 *
  	 * @param theBegin The beginning iterator for the range to search
  	 * @param theBegin The ending iterator for the range to search
  	 * @param uri     URI string for namespace to find
  	 * @return pointer to the string value if found, otherwise null.
  	 */
  	static const XalanDOMString*
  	getPrefixForNamespace(
  			NamespacesStackType::const_iterator		theBegin,
  			NamespacesStackType::const_iterator		theEnd,
  			const XalanDOMString&					uri);
  
  	// not implemented
  	XalanNamespacesStack(const XalanNamespacesStack&);
  
  	bool
  	operator==(const XalanNamespacesStack&) const;
  
  	XalanNamespacesStack&
  	operator=(const XalanNamespacesStack&);
  
  	enum { eDefaultCreateNewContextStackSize = 25 };
  
  	/**
  	 * A stack to keep track of the result tree namespaces.
  	 */
  	NamespacesStackType				m_resultNamespaces;
  
  	NamespacesStackType::iterator	m_stackBegin;
  
  	NamespacesStackType::iterator	m_stackPosition;
  
  	BoolVectorType					m_createNewContextStack;
  };
  
  
  
  #endif	// XALAN_XALANNAMESPACESSTACK_HEADER_GUARD
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org