source: icXML/icXML-devel/src/xercesc/validators/schema/NamespaceScope.cpp @ 2734

Last change on this file since 2734 was 2722, checked in by cameron, 7 years ago

Original Xerces files with import mods for icxercesc

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