source: icXML/icXML-devel/src/icxercesc/util/QName.cpp @ 3150

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

Updates for various icxercesc modified files.

File size: 10.3 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: QName.cpp 810580 2009-09-02 15:52:22Z amassari $
11 */
12
13#include <xercesc/util/Janitor.hpp>
14#include <icxercesc/util/QName.hpp>
15#include <xercesc/util/OutOfMemoryException.hpp>
16#include <icxmlc/XMLConfig.hpp>
17
18XERCES_CPP_NAMESPACE_BEGIN
19
20#pragma warning if we can map identical prefixes to one pool and indentical suffixes to another, it would make qualified comparisons easier
21
22// #define USE_SHALLOW_CLONES
23
24// ---------------------------------------------------------------------------
25//  QName: Constructors and Destructor
26// ---------------------------------------------------------------------------
27QName::QName(MemoryManager* const manager)
28: fNameBuf(0)
29, fURIId(-1)
30, fPrefix(0)
31, fPrefixLen(0)
32, fLocalPart(0)
33, fLocalPartLen(0)
34, fRawName(0)
35, fMemoryManager(manager)
36{
37    assert (fMemoryManager);
38}
39
40typedef JanitorMemFunCall<QName>    CleanupType;
41
42QName::QName
43(
44          const XMLCh* const   prefix
45        , const XMLCh* const   localPart
46        , const unsigned int   uriId
47        , MemoryManager* const manager
48)
49        :fNameBuf(0)   
50        ,fURIId(-1)
51        ,fPrefix(0)
52        ,fPrefixLen(0)
53        ,fLocalPart(0)
54        ,fLocalPartLen(0)
55        ,fRawName(0)
56        ,fMemoryManager(manager)
57{
58        CleanupType cleanup(this, &QName::cleanUp);
59
60        try
61        {
62                //
63                //  Just call the local setters to set up everything. Too much
64                //  work is required to replicate that functionality here.
65                //
66                setName(prefix, localPart, uriId);
67        }
68        catch(const OutOfMemoryException&)
69        {
70                cleanup.release();
71                throw;
72        }
73
74        cleanup.release();
75}
76
77QName::QName
78(
79          const XMLCh* const   rawName
80        , const unsigned int   uriId
81        , MemoryManager* const manager
82)
83        :fNameBuf(0)
84        ,fURIId(-1)
85        ,fPrefix(0)
86        ,fPrefixLen(0)
87        ,fLocalPart(0)
88        ,fLocalPartLen(0)
89        ,fRawName(0)
90        ,fMemoryManager(manager)
91{
92        CleanupType cleanup(this, &QName::cleanUp);
93
94        try
95        {
96                //
97                //  Just call the local setters to set up everything. Too much
98                //  work is required to replicate that functionality here.
99                //
100                setName(rawName, uriId);
101        }
102        catch(const OutOfMemoryException&)
103        {
104                cleanup.release();
105
106                throw;
107        }
108
109        cleanup.release();
110}
111
112/** Constructs a specified qname using prefix, and localpart. */
113QName::QName
114(
115          const XMLCh* const   rawName
116        , const int            colonInd
117        , const unsigned int   uriId
118        , MemoryManager* const manager
119)
120        :fNameBuf(0)
121        ,fURIId(-1)
122        ,fPrefix(0)
123        ,fPrefixLen(0)
124        ,fLocalPart(0)
125        ,fLocalPartLen(0)
126        ,fRawName(0)
127        ,fMemoryManager(manager)
128{
129        CleanupType cleanup(this, &QName::cleanUp);
130
131        try
132        {
133                //
134                //  Just call the local setters to set up everything. Too much
135                //  work is required to replicate that functionality here.
136                //
137                setName(rawName, colonInd, uriId);
138        }
139        catch (const OutOfMemoryException&)
140        {
141                cleanup.release();
142                throw;
143        }
144
145        cleanup.release();
146}
147
148QName::~QName()
149{
150    DEBUG_MESSAGE(" --- ~QName() 0x" << std::hex << (size_t)(this) << " fNameBuf=0x" << (size_t)(fNameBuf) << std::dec);
151        cleanUp();
152}
153
154// ---------------------------------------------------------------------------
155//  QName: Copy Constructors
156// ---------------------------------------------------------------------------
157#ifdef USE_SHALLOW_CLONES
158QName::QName(const QName & qName)
159: XSerializable(qName)
160, XMemory(qName)
161, fURIId(qName.fURIId)
162, fPrefix(qName.fPrefix)
163, fPrefixLen(qName.fPrefixLen)
164, fLocalPart(qName.fLocalPart)
165, fLocalPartLen(qName.fLocalPartLen)
166, fRawName(qName.fRawName)
167, fNameBuf(qName.fNameBuf)
168, fMemoryManager(qName.fMemoryManager)
169{
170    DEBUG_MESSAGE(" --- QName(qName) 0x" << std::hex << (size_t)(this) << " fNameBuf=0x" << (size_t)(fNameBuf) << std::dec);
171    // prevent the 'cloned' qname from deleting the memory for this qname
172    const_cast<QName&>(qName).fNameBuf = 0;
173}
174
175QName & QName::operator=(const QName & qName)
176{
177    DEBUG_MESSAGE(" --- QName=qName 0x" << std::hex << (size_t)(this) << " fNameBuf=0x" << (size_t)(fNameBuf) << std::dec);
178    // free up the original memory if need be
179    cleanUp();
180    // and 'clone' the supplied QName
181    fURIId = qName.fURIId;
182    fPrefix = qName.fPrefix;
183    fPrefixLen = qName.fPrefixLen;
184    fLocalPart = qName.fLocalPart;
185    fLocalPartLen = qName.fLocalPartLen;
186    fRawName = qName.fRawName;
187    fNameBuf = qName.fNameBuf;
188    fMemoryManager = qName.fMemoryManager;
189    // prevent the 'cloned' qname from deleting the memory for this qname
190    const_cast<QName&>(qName).fNameBuf = 0;
191    return *this;
192}
193#else
194QName::QName(const QName & qName)
195: XSerializable(qName)
196, XMemory(qName)
197, fNameBuf(0)
198, fURIId(-1)
199, fPrefix(0)
200, fPrefixLen(0)
201, fLocalPart(0)
202, fLocalPartLen(0)
203, fRawName(0)
204, fMemoryManager(qName.fMemoryManager)
205{
206    CleanupType cleanup(this, &QName::cleanUp);
207    try
208    {
209        //
210        //  Just call the local setters to set up everything. Too much
211        //  work is required to replicate that functionality here.
212        //
213        setName(qName.fRawName, qName.fURIId);
214    }
215    catch(const OutOfMemoryException&)
216    {
217        cleanup.release();
218        throw;
219    }
220
221    cleanup.release();
222}
223
224QName & QName::operator=(const QName & qName)
225{
226    CleanupType cleanup(this, &QName::cleanUp);
227    try
228    {
229        fMemoryManager = qName.fMemoryManager;
230        //
231        //  Just call the local setters to set up everything. Too much
232        //  work is required to replicate that functionality here.
233        //
234        setName(qName.fRawName, qName.fURIId);
235    }
236    catch(const OutOfMemoryException&)
237    {
238        cleanup.release();
239        throw;
240    }
241
242    cleanup.release();
243    return *this;
244}
245#endif
246
247
248
249// ---------------------------------------------------------------------------
250//  QName: Setter methods
251// ---------------------------------------------------------------------------
252
253// should we construct the transcoded QNames as "prefix"<null>"prefix:localPart" and
254// NCNames as <null>"localPart"? this may improve memory stride in the string pool.
255// Or should the prefix always point to the entry in the XMLNamespaceStack? that
256// would reduce memory consumption but potentially hurt memory stride.
257
258void QName::setName(const XMLCh* const    rawName
259                                  , const int             colonInd
260                                  , const unsigned int    uriId)
261{
262        fLocalPartLen = XMLString::stringLen(&rawName[colonInd + 1]);
263        XMLCh * nameBuf;
264        XMLSize_t nameBufSize;
265        if (colonInd == -1)
266        {
267                fPrefixLen = 0;
268                nameBufSize = fLocalPartLen + 2;
269                nameBuf = (XMLCh*)fMemoryManager->allocate(nameBufSize * sizeof(XMLCh));
270
271                fPrefix = &nameBuf[0];
272                fPrefix[0] = chNull;
273
274                fLocalPart = &fPrefix[1];
275                fRawName = &fPrefix[1];
276        }
277        else
278        {
279                fPrefixLen = colonInd;
280                nameBufSize = (fPrefixLen + 1) * 2 + fLocalPartLen + 1;
281                nameBuf = (XMLCh*)fMemoryManager->allocate(nameBufSize * sizeof(XMLCh));
282
283                fPrefix = &nameBuf[0];
284                XMLString::moveChars(fPrefix, rawName, fPrefixLen);
285                fPrefix[fPrefixLen] = chNull;
286
287                fRawName = &fPrefix[fPrefixLen + 1];
288                XMLString::moveChars(fRawName, rawName, fPrefixLen);
289                fRawName[fPrefixLen] = chColon;
290
291                fLocalPart = &fRawName[fPrefixLen + 1];
292        }
293
294        XMLString::moveChars(fLocalPart, &rawName[colonInd + 1], fLocalPartLen);
295        fLocalPart[fLocalPartLen] = chNull;
296
297        // And finally store the URI id parameter
298        fURIId = uriId;
299
300        // replace the internal buffer with the new one
301        fMemoryManager->deallocate(fNameBuf);
302        fNameBuf = nameBuf;
303
304    DEBUG_MESSAGE(" --- QName::setName(" << rawName << ',' << colonInd << ',' << uriId << ") 0x" << std::hex << (size_t)(this) << " fNameBuf=0x" << (size_t)(fNameBuf) << std::dec);
305}
306
307
308void QName::setName
309(
310    const XMLCh* const      prefix
311    , const XMLCh* const    localPart
312    , const unsigned int    uriId
313)
314{
315        fPrefixLen = XMLString::stringLen(prefix);
316        fLocalPartLen = XMLString::stringLen(localPart);
317
318        XMLCh * nameBuf;
319        XMLSize_t nameBufSize;
320        if (!fPrefixLen)
321        {
322                nameBufSize = fLocalPartLen + 2;
323                nameBuf = (XMLCh*)fMemoryManager->allocate(nameBufSize * sizeof(XMLCh));
324
325                fPrefix = &nameBuf[0];
326                fPrefix[0] = chNull;
327
328                fLocalPart = &fPrefix[1];
329                fRawName = &fPrefix[1];
330        }
331        else
332        {
333                nameBufSize = (fPrefixLen + 1) * 2 + fLocalPartLen + 1;
334                nameBuf = (XMLCh*)fMemoryManager->allocate(nameBufSize * sizeof(XMLCh));
335
336                fPrefix = &nameBuf[0];
337                XMLString::moveChars(fPrefix, prefix, fPrefixLen);
338                fPrefix[fPrefixLen] = chNull;
339
340                fRawName = &fPrefix[fPrefixLen + 1];
341                XMLString::moveChars(fRawName, prefix, fPrefixLen);
342                fRawName[fPrefixLen] = chColon;
343
344                fLocalPart = &fRawName[fPrefixLen + 1];
345        }
346
347        XMLString::moveChars(fLocalPart, localPart, fLocalPartLen);
348        fLocalPart[fLocalPartLen] = chNull;
349
350        // And finally store the URI id parameter
351        fURIId = uriId;
352
353        // replace the internal buffer with the new one
354        fMemoryManager->deallocate(fNameBuf);
355        fNameBuf = nameBuf;
356
357    DEBUG_MESSAGE(" --- QName::setName(" << prefix << ',' << localPart << ',' << uriId << ") 0x" << std::hex << (size_t)(this) << " fNameBuf=0x" << std::hex << (size_t)(fNameBuf) << std::dec);
358}
359
360void QName::setNPrefix(const XMLCh* prefix, const XMLSize_t newLen)
361{
362        setName(prefix, this->fLocalPart, this->fURIId);
363}
364
365void QName::setNLocalPart(const XMLCh* localPart, const XMLSize_t newLen)
366{
367        setName(this->fPrefix, localPart, this->fURIId);
368}
369
370void QName::setValues(const QName & qName)
371{
372        setName(qName.fPrefix, qName.fLocalPart, qName.fURIId);
373}
374
375// -----------------------------------------------------------------------
376//  comparison
377// -----------------------------------------------------------------------
378bool QName::operator==(const QName& qname) const
379{
380        // if we are an unitialized QName, check that the other is unitialized too
381        if (!fLocalPart && !fPrefix)
382        {
383                return !qname.fLocalPart && !qname.fPrefix;
384        }
385
386        if (fURIId == 0) // null URI
387        {
388                return (XMLString::equals(getRawName(),qname.getRawName()));
389        }
390
391        return (fURIId == qname.getURI()) && (XMLString::equals(fLocalPart, qname.getLocalPart()));
392}
393
394// ---------------------------------------------------------------------------
395//  QName: Private, helper methods
396// ---------------------------------------------------------------------------
397
398void QName::cleanUp()
399{
400    if (fNameBuf)
401    {
402        assert (fMemoryManager);
403        fMemoryManager->deallocate(fNameBuf);
404        fNameBuf = 0;
405    }
406}
407
408/***
409 * Support for Serialization/De-serialization
410 ***/
411IMPL_XSERIALIZABLE_TOCREATE(QName)
412
413void QName::serialize(XSerializeEngine&)
414{
415    DEPRECATED_FEATURE_IN_ICXML;
416}
417
418XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.