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 [EMAIL PROTECTED]
   *
   * 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 [EMAIL PROTECTED]
   *
   * 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to