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

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

Initial check-in of icXML 0.8 source files

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