source: icXML/icXML-devel/src/icxercesc/validators/schema/NamespaceScope.cpp @ 3152

Last change on this file since 3152 was 3152, checked in by cameron, 6 years ago

New custom icxercesc files

File size: 8.6 KB
Line 
1/*
2 * Unless required by applicable law or agreed to in writing, software
3 * distributed under the License is distributed on an "AS IS" BASIS,
4 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 * See the License for the specific language governing permissions and
6 * limitations under the License.
7 */
8
9/*
10 * $Id: NamespaceScope.cpp 729944 2008-12-29 17:03:32Z amassari $
11 */
12
13// ---------------------------------------------------------------------------
14//  Includes
15// ---------------------------------------------------------------------------
16#include <string.h>
17#include <xercesc/util/EmptyStackException.hpp>
18#include <xercesc/validators/schema/NamespaceScope.hpp>
19
20XERCES_CPP_NAMESPACE_BEGIN
21
22NamespaceScope::NamespaceScope(MemoryManager* const manager /*= XMLPlatformUtils::fgMemoryManager*/) :
23        fEmptyNamespaceId(0)
24        , fStackCapacity(8)
25        , fStackTop(0)
26        , fPrefixPool(109, manager)
27        , fStack(0)
28        , fMemoryManager(manager)
29{
30        // Do an initial allocation of the stack and zero it out
31        fStack = (StackElem**) fMemoryManager->allocate
32        (
33                fStackCapacity * sizeof(StackElem*)
34        );//new StackElem*[fStackCapacity];
35        memset(fStack, 0, fStackCapacity * sizeof(StackElem*));
36}
37
38NamespaceScope::NamespaceScope(const NamespaceScope* const initialize, MemoryManager* const manager /*= XMLPlatformUtils::fgMemoryManager*/) :
39        fEmptyNamespaceId(0)
40        , fStackCapacity(8)
41        , fStackTop(0)
42        , fPrefixPool(109, manager)
43        , fStack(0)
44        , fMemoryManager(manager)
45{
46        // Do an initial allocation of the stack and zero it out
47        fStack = (StackElem**) fMemoryManager->allocate
48        (
49                fStackCapacity * sizeof(StackElem*)
50        );//new StackElem*[fStackCapacity];
51        memset(fStack, 0, fStackCapacity * sizeof(StackElem*));
52
53        if(initialize)
54        {
55                reset(initialize->fEmptyNamespaceId);
56
57                // copy the existing bindings
58                for (unsigned int index = initialize->fStackTop; index > 0; index--)
59                {
60                        // Get a convenience pointer to the current element
61                        StackElem* curRow = initialize->fStack[index-1];
62
63                        // If no prefixes mapped at this level, then go the next one
64                        if (!curRow->fMapCount)
65                                continue;
66
67                        for (unsigned int mapIndex = 0; mapIndex < curRow->fMapCount; mapIndex++)
68                        {
69                                // go from the id to the prefix
70                                const XMLCh* prefix = initialize->fPrefixPool.getValueForId(curRow->fMap[mapIndex].fPrefId);
71
72                                // if the prefix is not already known, add it
73                                if (getNamespaceForPrefix(prefix)==fEmptyNamespaceId)
74                                        addPrefix(prefix, curRow->fMap[mapIndex].fURIId);
75                        }
76                }
77        }
78}
79
80NamespaceScope::~NamespaceScope()
81{
82        //
83        //  Start working from the bottom of the stack and clear it out as we
84        //  go up. Once we hit an uninitialized one, we can break out.
85        //
86        for (unsigned int stackInd = 0; stackInd < fStackCapacity; stackInd++)
87        {
88                // If this entry has been set, then lets clean it up
89                if (!fStack[stackInd])
90                        break;
91
92                // Delete the row for this entry, then delete the row structure
93                fMemoryManager->deallocate(fStack[stackInd]->fMap);//delete [] fStack[stackInd]->fMap;
94                delete fStack[stackInd];
95        }
96
97        // Delete the stack array itself now
98        fMemoryManager->deallocate(fStack);//delete [] fStack;
99}
100
101
102// ---------------------------------------------------------------------------
103//  NamespaceScope: Stack access
104// ---------------------------------------------------------------------------
105unsigned int NamespaceScope::increaseDepth()
106{
107        // See if we need to expand the stack
108        if (fStackTop == fStackCapacity)
109                expandStack();
110
111        // If this element has not been initialized yet, then initialize it
112        if (!fStack[fStackTop])
113        {
114                fStack[fStackTop] = new (fMemoryManager) StackElem;
115                fStack[fStackTop]->fMapCapacity = 0;
116                fStack[fStackTop]->fMap = 0;
117        }
118
119        // Set up the new top row
120        fStack[fStackTop]->fMapCount = 0;
121
122        // Bump the top of stack
123        fStackTop++;
124
125        return fStackTop-1;
126}
127
128unsigned int NamespaceScope::decreaseDepth()
129{
130        if (!fStackTop)
131        {
132                ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_StackUnderflow, fMemoryManager);
133        }
134
135        fStackTop--;
136
137        return fStackTop;
138}
139
140
141// ---------------------------------------------------------------------------
142//  NamespaceScope: Prefix map methods
143// ---------------------------------------------------------------------------
144void NamespaceScope::addPrefix(const XMLCh* const prefixToAdd,
145                                                           const unsigned int uriId) {
146
147        if (!fStackTop)
148                ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);
149
150        // Get a convenience pointer to the stack top row
151        StackElem* curRow = fStack[fStackTop - 1];
152
153        // Map the prefix to its unique id
154        const unsigned int prefId = fPrefixPool.addOrFind(prefixToAdd);
155
156        // Search the map at this level for the passed prefix
157        for (unsigned int mapIndex = 0; mapIndex < curRow->fMapCount; mapIndex++)
158        {
159                if (curRow->fMap[mapIndex].fPrefId == prefId)
160                {
161                        curRow->fMap[mapIndex].fURIId = uriId;
162                        return;
163                }
164        }
165
166        //
167        //  Add a new element to the prefix map for this element. If its full,
168        //  then expand it out.
169        //
170        if (curRow->fMapCount == curRow->fMapCapacity)
171                expandMap(curRow);
172
173        //
174        //  And now add a new element for this prefix.
175        //
176        curRow->fMap[curRow->fMapCount].fPrefId = prefId;
177        curRow->fMap[curRow->fMapCount].fURIId = uriId;
178
179        // Bump the map count now
180        curRow->fMapCount++;
181}
182
183unsigned int
184NamespaceScope::getNamespaceForPrefix(const XMLCh* const prefixToMap) const
185{
186
187        //
188        //  Map the prefix to its unique id, from the prefix string pool. If its
189        //  not a valid prefix, then its a failure.
190        //
191        unsigned int prefixId = fPrefixPool.getId(prefixToMap);
192
193        if (!prefixId)
194        {
195                return fEmptyNamespaceId;
196        }
197
198        //
199        //  Start at the stack top and work backwards until we come to some
200        //  element that mapped this prefix.
201        //
202        for (unsigned int index = fStackTop; index > 0; index--)
203        {
204                // Get a convenience pointer to the current element
205                StackElem* curRow = fStack[index-1];
206
207                // If no prefixes mapped at this level, then go the next one
208                if (!curRow->fMapCount)
209                        continue;
210
211                // Search the map at this level for the passed prefix
212                for (unsigned int mapIndex = 0; mapIndex < curRow->fMapCount; mapIndex++)
213                {
214                        if (curRow->fMap[mapIndex].fPrefId == prefixId)
215                                return curRow->fMap[mapIndex].fURIId;
216                }
217        }
218
219        return fEmptyNamespaceId;
220}
221
222
223// ---------------------------------------------------------------------------
224//  NamespaceScope: Miscellaneous methods
225// ---------------------------------------------------------------------------
226void NamespaceScope::reset(const unsigned int emptyId)
227{
228        // Flush the prefix pool and put back in the standard prefixes
229        fPrefixPool.flushAll();
230
231        // Reset the stack top to clear the stack
232        fStackTop = 0;
233
234        // And store the new special URI ids
235        fEmptyNamespaceId = emptyId;
236
237        // add the first storage
238        increaseDepth();
239}
240
241
242// ---------------------------------------------------------------------------
243//  Namespace: Private helpers
244// ---------------------------------------------------------------------------
245void NamespaceScope::expandMap(StackElem* const toExpand)
246{
247        // For convenience get the old map size
248        const unsigned int oldCap = toExpand->fMapCapacity;
249
250        //
251        //  Expand the capacity by 25%, or initialize it to 16 if its currently
252        //  empty. Then allocate a new temp buffer.
253        //
254        const unsigned int newCapacity = oldCap ?
255                                                                         (unsigned int)(oldCap * 1.25) : 16;
256        PrefMapElem* newMap = (PrefMapElem*) fMemoryManager->allocate
257        (
258                newCapacity * sizeof(PrefMapElem)
259        );//new PrefMapElem[newCapacity];
260
261        //
262        //  Copy over the old stuff. We DON'T have to zero out the new stuff
263        //  since this is a by value map and the current map index controls what
264        //  is relevant.
265        //
266        memcpy(newMap, toExpand->fMap, oldCap * sizeof(PrefMapElem));
267
268        // Delete the old map and store the new stuff
269        fMemoryManager->deallocate(toExpand->fMap);//delete [] toExpand->fMap;
270        toExpand->fMap = newMap;
271        toExpand->fMapCapacity = newCapacity;
272}
273
274void NamespaceScope::expandStack()
275{
276        // Expand the capacity by 25% and allocate a new buffer
277        const unsigned int newCapacity = (unsigned int)(fStackCapacity * 1.25);
278        StackElem** newStack = (StackElem**) fMemoryManager->allocate
279        (
280                newCapacity * sizeof(StackElem*)
281        );//new StackElem*[newCapacity];
282
283        // Copy over the old stuff
284        memcpy(newStack, fStack, fStackCapacity * sizeof(StackElem*));
285
286        //
287        //  And zero out the new stuff. Though we use a stack top, we reuse old
288        //  stack contents so we need to know if elements have been initially
289        //  allocated or not as we push new stuff onto the stack.
290        //
291        memset
292        (
293                &newStack[fStackCapacity]
294                , 0
295                , (newCapacity - fStackCapacity) * sizeof(StackElem*)
296        );
297
298        // Delete the old array and update our members
299        fMemoryManager->deallocate(fStack);//delete [] fStack;
300        fStack = newStack;
301        fStackCapacity = newCapacity;
302}
303
304XERCES_CPP_NAMESPACE_END
305
306/**
307  * End of file NamespaceScope.cpp
308  */
309
Note: See TracBrowser for help on using the repository browser.