/* * Copyright 2005 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. */ /* * XSEC * * XSECXMLNSStack := NS Stack for simple canonicalisation * * $Id: XSECXMLNSStack.cpp 389735 2006-03-29 09:58:59Z blautenb $ * */ // XSEC #include #include #include #include // Xerces XERCES_CPP_NAMESPACE_USE // -------------------------------------------------------------------------------- // Holder structures // -------------------------------------------------------------------------------- typedef struct XSECNSHolderStruct { XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_ns; // Actual NS attribute XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_owner; // Owner Element struct XSECNSHolderStruct * mp_hides; // WHat does this NS hide? struct XSECNSHolderStruct * mp_next; // Next in list XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_printed; // Node at which it was printed bool m_isDefault; // Is this a default NS? } XSECNSHolder; typedef struct XSECNSElementStruct { XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_elt; // Element struct XSECNSHolderStruct * mp_firstNS; // WHat does this NS hide? } XSECNSElement; // -------------------------------------------------------------------------------- // Construct/Destruct // -------------------------------------------------------------------------------- XSECXMLNSStack::XSECXMLNSStack() { } XSECXMLNSStack::~XSECXMLNSStack() { // Need to iterate through the Stack to XSECNSElement * t; XSECNSHolder * u, *v; while (m_elements.size() > 0) { t = m_elements.top(); u = t->mp_firstNS; while (u != NULL) { v = u->mp_next; delete u; u = v; } delete t; m_elements.pop(); } } // -------------------------------------------------------------------------------- // Stack Functions // -------------------------------------------------------------------------------- void XSECXMLNSStack::pushElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * elt) { XSECNSElement * t; XSECnew(t, XSECNSElement); t->mp_elt = elt; t->mp_firstNS = NULL; m_elements.push(t); } void XSECXMLNSStack::popElement() { // First - are there any namespaces to remove from the currently visible list? XSECNSHolder * t, *u; XSECNSElement * e = m_elements.top(); // Iterate through the current namespaces vector XSECNSHolderVectorType::iterator it = m_currentNS.begin(); while (it != m_currentNS.end()) { t = *it; if (t->mp_owner == e->mp_elt) { // Need to delete this m_currentNS.erase(it); if (t->mp_hides != NULL) { m_currentNS.push_back(t->mp_hides); } // TODO - Fix this, it is naieve and slow it = m_currentNS.begin(); } else { if (t->mp_printed == e->mp_elt) t->mp_printed = NULL; it++; } } // OK - Now we delete the NS nodes t = e->mp_firstNS; while (t != NULL) { u = t->mp_next; delete t; t = u; } // Now delete the element holder itself m_elements.pop(); delete e; } // -------------------------------------------------------------------------------- // NS Addition // -------------------------------------------------------------------------------- void XSECXMLNSStack::addNamespace(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * ns) { // Create the new entry for this node XSECNSHolder * t, *u; XSECnew(t, XSECNSHolder); t->mp_hides = NULL; t->mp_next = NULL; t->mp_ns = ns; t->mp_owner = (m_elements.top())->mp_elt; t->mp_printed = NULL; t->m_isDefault = strEquals(ns->getNodeName(), DSIGConstants::s_unicodeStrXmlns); // Does this hide something in the current namespace list? XSECNSHolderVectorType::iterator it = m_currentNS.begin(); while (it != m_currentNS.end()) { u = (*it); if (strEquals(u->mp_ns->getNodeName(), ns->getNodeName())) { // This hides a current NS entry t->mp_hides = u; m_currentNS.erase(it); it = m_currentNS.end(); } else it++; } // Now push it onto the namespace vector m_currentNS.push_back(t); // Add me to the current element's namespaces XSECNSElement * e = m_elements.top(); t->mp_next = e->mp_firstNS; e->mp_firstNS = t; } void XSECXMLNSStack::printNamespace(DOMNode * ns, DOMNode * elt) { XSECNSHolder * t; XSECNSHolderVectorType::iterator it = m_currentNS.begin(); while (it != m_currentNS.end()) { t = (*it); if (t->mp_ns == ns && t->m_isDefault == false) { t->mp_printed = elt; break; } it++; } } // -------------------------------------------------------------------------------- // NS Searching // -------------------------------------------------------------------------------- DOMNode * XSECXMLNSStack::getFirstNamespace(void) { m_currentNSIterator = m_currentNS.begin(); while (m_currentNSIterator != m_currentNS.end() && (*m_currentNSIterator)->mp_printed != NULL) m_currentNSIterator++; if (m_currentNSIterator != m_currentNS.end()) return (*m_currentNSIterator)->mp_ns; return NULL; } DOMNode * XSECXMLNSStack::getNextNamespace(void) { if (m_currentNSIterator == m_currentNS.end()) return NULL; m_currentNSIterator++; while (m_currentNSIterator != m_currentNS.end() && (*m_currentNSIterator)->mp_printed != NULL) m_currentNSIterator++; if (m_currentNSIterator == m_currentNS.end()) return NULL; return (*m_currentNSIterator)->mp_ns; }