2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
13 #include "VariableScope.hxx"
14 #include "XMLObject.hxx"
15 #include "XMLNodeList.hxx"
17 namespace org_modules_xml
19 xmlFreeFunc VariableScope::XMLFreeFunc = 0;
20 std::map < void *, XMLObject * > VariableScope::mapLibXMLToXMLObject = std::map < void *, XMLObject * >();
21 std::map < void *, XMLNodeList * > VariableScope::mapLibXMLToXMLNodeList = std::map < void *, XMLNodeList * >();
22 std::map < const XMLObject *, std::vector < const XMLObject *>*> VariableScope::parentToChildren = std::map < const XMLObject *, std::vector < const XMLObject *>*>();
24 VariableScope::VariableScope(int _initialSize)
27 initialSize = _initialSize;
28 scope = new std::vector < XMLObject * >();
29 freePlaces = new std::stack < int >();
33 VariableScope::~VariableScope()
35 for (unsigned int i = 0; i < scope->size(); i++)
47 * To avoid unused place in the vector, we use a stack which contains the empty places.
49 int VariableScope::getVariableId(const XMLObject & obj)
52 const XMLObject *parent = obj.getXMLObjectParent();
54 if (freePlaces->size() != 0)
56 returnValue = freePlaces->top();
58 (*scope)[returnValue] = const_cast < XMLObject * >(&obj);
62 returnValue = (int)scope->size();
63 scope->push_back(const_cast < XMLObject * >(&obj));
68 std::map < const XMLObject *, std::vector < const XMLObject *>*>::const_iterator it = parentToChildren.find(parent);
70 if (it != parentToChildren.end())
72 it->second->push_back(&obj);
76 parentToChildren[parent] = new std::vector < const XMLObject *>();
78 parentToChildren[parent]->push_back(&obj);
85 XMLObject *VariableScope::getVariableFromId(int id)
87 if (id >= 0 && id < (int)scope->size())
96 * There are two motivations to register libxml pointers:
97 * i) if a XMLObject is associated to a libxml node, then when this node will be removed
98 * the XMLObject must be destroyed. This job is done in _xmlFreeFunc which is called
99 * by libxml when a libxml node is freed.
100 * ii) To avoid multiple instances of a XMLObject which wraps the same node, the function
101 * getXMLObjectFromLibXMLPtr is used to know if a XMLObject already exists for the
104 void VariableScope::registerPointers(void *libxml, XMLObject * obj)
108 mapLibXMLToXMLObject[libxml] = obj;
112 void VariableScope::registerPointers(void *libxml, XMLNodeList * nodeList)
116 mapLibXMLToXMLNodeList[libxml] = nodeList;
120 void VariableScope::unregisterPointer(void *libxml)
124 mapLibXMLToXMLObject.erase(libxml);
128 void VariableScope::unregisterNodeListPointer(void *libxml)
132 mapLibXMLToXMLNodeList.erase(libxml);
136 XMLObject *VariableScope::getXMLObjectFromLibXMLPtr(void *libxml) const
140 std::map < void *, XMLObject * >::const_iterator it = mapLibXMLToXMLObject.find(libxml);
141 if (it != mapLibXMLToXMLObject.end())
150 XMLNodeList *VariableScope::getXMLNodeListFromLibXMLPtr(void *libxml)const
154 std::map < void *, XMLNodeList * >::const_iterator it = mapLibXMLToXMLNodeList.find(libxml);
155 if (it != mapLibXMLToXMLNodeList.end())
164 void VariableScope::removeId(int id)
166 if (id >= 0 && id < (int)scope->size() && (*scope)[id])
168 removeChildFromParent((*scope)[id]);
169 removeDependencies((*scope)[id]);
171 freePlaces->push(id);
175 void VariableScope::removeDependencies(XMLObject * obj)
177 std::map < const XMLObject *, std::vector < const XMLObject *>*>::const_iterator it = parentToChildren.find(obj);
179 if (it != parentToChildren.end())
181 for (unsigned int i = 0; i < it->second->size(); i++)
183 const XMLObject *child = (*(it->second))[i];
185 if (child && getVariableFromId(child->getId()) == child)
192 parentToChildren.erase(obj);
196 void VariableScope::initXMLMemory()
198 xmlFreeFunc freeFunc;
199 xmlMallocFunc mallocFunc;
200 xmlReallocFunc reallocFunc;
201 xmlStrdupFunc strdupFunc;
203 xmlMemGet(&freeFunc, &mallocFunc, &reallocFunc, &strdupFunc);
204 freeFunc = getFreeFunc(freeFunc);
205 xmlMemSetup(freeFunc, mallocFunc, reallocFunc, strdupFunc);
208 xmlFreeFunc VariableScope::getFreeFunc(xmlFreeFunc freeFunc)
212 XMLFreeFunc = freeFunc;
215 return &_xmlFreeFunc;
218 void VariableScope::_xmlFreeFunc(void *mem)
220 std::map < void *, XMLObject * >::const_iterator it = mapLibXMLToXMLObject.find(mem);
222 if (it != mapLibXMLToXMLObject.end())
226 mapLibXMLToXMLObject.erase(mem);
229 std::map < void *, XMLNodeList * >::const_iterator itnl = mapLibXMLToXMLNodeList.find(mem);
231 if (itnl != mapLibXMLToXMLNodeList.end())
235 mapLibXMLToXMLNodeList.erase(mem);
241 inline void VariableScope::removeChildFromParent(const XMLObject * child)
243 const XMLObject *parent = child->getXMLObjectParent();
244 std::map < const XMLObject *, std::vector < const XMLObject *>*>::const_iterator it = parentToChildren.find(parent);
246 if (it != parentToChildren.end())
248 for (unsigned int i = 0; i < it->second->size(); i++)
250 if (child == (*(it->second))[i])
252 (*(it->second))[i] = 0;