GME  13
QName.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  * 
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  * 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: QName.cpp 810580 2009-09-02 15:52:22Z amassari $
00020  */
00021 
00022 #include <xercesc/util/Janitor.hpp>
00023 #include <xercesc/util/QName.hpp>
00024 #include <xercesc/util/OutOfMemoryException.hpp>
00025 
00026 XERCES_CPP_NAMESPACE_BEGIN
00027 
00028 // ---------------------------------------------------------------------------
00029 //  QName: Constructors and Destructor
00030 // ---------------------------------------------------------------------------
00031 QName::QName(MemoryManager* const manager)
00032 :fPrefixBufSz(0)
00033 ,fLocalPartBufSz(0)
00034 ,fRawNameBufSz(0)
00035 ,fURIId(0)
00036 ,fPrefix(0)
00037 ,fLocalPart(0)
00038 ,fRawName(0)
00039 ,fMemoryManager(manager)
00040 {
00041 }
00042 
00043 typedef JanitorMemFunCall<QName>    CleanupType;
00044 
00045 QName::QName( const XMLCh* const   prefix
00046             , const XMLCh* const   localPart
00047             , const unsigned int   uriId
00048             , MemoryManager* const manager)
00049 :fPrefixBufSz(0)
00050 ,fLocalPartBufSz(0)
00051 ,fRawNameBufSz(0)
00052 ,fURIId(0)
00053 ,fPrefix(0)
00054 ,fLocalPart(0)
00055 ,fRawName(0)
00056 ,fMemoryManager(manager)
00057 {
00058     CleanupType cleanup(this, &QName::cleanUp);
00059 
00060     try
00061     {
00062         //
00063         //  Just call the local setters to set up everything. Too much
00064         //  work is required to replicate that functionality here.
00065         //
00066         setName(prefix, localPart, uriId);
00067     }
00068     catch(const OutOfMemoryException&)
00069     {
00070         cleanup.release();
00071 
00072         throw;
00073     }
00074 
00075     cleanup.release();
00076 }
00077 
00078 QName::QName( const XMLCh* const rawName
00079             , const unsigned int uriId
00080             , MemoryManager* const manager)
00081 :fPrefixBufSz(0)
00082 ,fLocalPartBufSz(0)
00083 ,fRawNameBufSz(0)
00084 ,fURIId(0)
00085 ,fPrefix(0)
00086 ,fLocalPart(0)
00087 ,fRawName(0)
00088 ,fMemoryManager(manager)
00089 {
00090     CleanupType cleanup(this, &QName::cleanUp);
00091 
00092     try
00093     {
00094         //
00095         //  Just call the local setters to set up everything. Too much
00096         //  work is required to replicate that functionality here.
00097         //
00098         setName(rawName, uriId);
00099     }
00100     catch(const OutOfMemoryException&)
00101     {
00102         cleanup.release();
00103 
00104         throw;
00105     }
00106 
00107     cleanup.release();
00108 }
00109 
00110 QName::~QName()
00111 {
00112         cleanUp();
00113 }
00114 
00115 // ---------------------------------------------------------------------------
00116 //  QName: Copy Constructors
00117 // ---------------------------------------------------------------------------
00118 QName::QName(const QName& qname)
00119 :XSerializable(qname)
00120 ,XMemory(qname)
00121 ,fPrefixBufSz(0)
00122 ,fLocalPartBufSz(0)
00123 ,fRawNameBufSz(0)
00124 ,fURIId(0)
00125 ,fPrefix(0)
00126 ,fLocalPart(0)
00127 ,fRawName(0)
00128 ,fMemoryManager(qname.fMemoryManager)
00129 {
00130     XMLSize_t newLen;
00131 
00132     newLen = XMLString::stringLen(qname.getLocalPart());
00133     fLocalPartBufSz = newLen + 8;
00134     fLocalPart = (XMLCh*) fMemoryManager->allocate
00135     (
00136         (fLocalPartBufSz + 1) * sizeof(XMLCh)
00137     ); //new XMLCh[fLocalPartBufSz + 1];
00138     XMLString::moveChars(fLocalPart, qname.getLocalPart(), newLen + 1);
00139 
00140     newLen = XMLString::stringLen(qname.getPrefix());
00141     fPrefixBufSz = newLen + 8;
00142     fPrefix = (XMLCh*) fMemoryManager->allocate
00143     (
00144         (fPrefixBufSz + 1) * sizeof(XMLCh)
00145     ); //new XMLCh[fPrefixBufSz + 1];
00146     XMLString::moveChars(fPrefix, qname.getPrefix(), newLen + 1);
00147 
00148     fURIId = qname.getURI();
00149 }
00150 
00151 // ---------------------------------------------------------------------------
00152 //  QName: Getter methods
00153 // ---------------------------------------------------------------------------
00154 const XMLCh* QName::getRawName() const
00155 {
00156     //
00157     //  If there is no buffer, or if there is but we've not faulted in the
00158     //  value yet, then we have to do that now.
00159     //
00160     if (!fRawName || !*fRawName)
00161     {
00162         //
00163         //  If we have a prefix, then do the prefix:name version. Else, its
00164         //  just the name.
00165         //
00166         if (*fPrefix)
00167         {
00168             //
00169             //  Calculate the worst case size buffer we will need. We use the
00170             //  current high water marks of the prefix and name buffers, so it
00171             //  might be a little wasteful of memory but we don't have to do
00172             //  string len operations on the two strings.
00173             //
00174             const XMLSize_t neededLen = fPrefixBufSz + fLocalPartBufSz + 1;
00175 
00176             //
00177             //  If no buffer, or the current one is too small, then allocate one
00178             //  and get rid of any old one.
00179             //
00180             if (!fRawName || (neededLen > fRawNameBufSz))
00181             {
00182                 fMemoryManager->deallocate(fRawName); //delete [] fRawName;
00183 
00184                 ((QName*)this)->fRawName = 0;
00185                 // We have to cast off the const'ness to do this
00186                 ((QName*)this)->fRawNameBufSz = neededLen;
00187                 ((QName*)this)->fRawName = (XMLCh*) fMemoryManager->allocate
00188                 (
00189                     (neededLen + 1) * sizeof(XMLCh)
00190                 ); //new XMLCh[neededLen + 1];
00191 
00192                 // Make sure its initially empty
00193                 *fRawName = 0;
00194             }
00195 
00196             const XMLSize_t prefixLen = XMLString::stringLen(fPrefix);
00197 
00198             XMLString::moveChars(fRawName, fPrefix, prefixLen);
00199             fRawName[prefixLen] = chColon;
00200             XMLString::copyString(&fRawName[prefixLen+1], fLocalPart);
00201         }
00202          else
00203         {
00204             return fLocalPart;
00205         }
00206     }
00207     return fRawName;
00208 }
00209 
00210 XMLCh* QName::getRawName()
00211 {
00212     //
00213     //  If there is no buffer, or if there is but we've not faulted in the
00214     //  value yet, then we have to do that now.
00215     //
00216     if (!fRawName || !*fRawName)
00217     {
00218         //
00219         //  If we have a prefix, then do the prefix:name version. Else, its
00220         //  just the name.
00221         //
00222         if (*fPrefix)
00223         {
00224             //
00225             //  Calculate the worst case size buffer we will need. We use the
00226             //  current high water marks of the prefix and name buffers, so it
00227             //  might be a little wasteful of memory but we don't have to do
00228             //  string len operations on the two strings.
00229             //
00230             const XMLSize_t neededLen = fPrefixBufSz + fLocalPartBufSz + 1;
00231 
00232             //
00233             //  If no buffer, or the current one is too small, then allocate one
00234             //  and get rid of any old one.
00235             //
00236             if (!fRawName || (neededLen > fRawNameBufSz))
00237             {
00238                 fMemoryManager->deallocate(fRawName); //delete [] fRawName;
00239                 
00240                 fRawName = 0;
00241                 // We have to cast off the const'ness to do this
00242                 ((QName*)this)->fRawNameBufSz = neededLen;
00243                 ((QName*)this)->fRawName = (XMLCh*) fMemoryManager->allocate
00244                 (
00245                     (neededLen + 1) * sizeof(XMLCh)
00246                 ); //new XMLCh[neededLen + 1];
00247 
00248                 // Make sure its initially empty
00249                 *fRawName = 0;
00250             }
00251 
00252 
00253             const XMLSize_t prefixLen = XMLString::stringLen(fPrefix);
00254 
00255             XMLString::moveChars(fRawName, fPrefix, prefixLen);
00256             fRawName[prefixLen] = chColon;
00257             XMLString::copyString(&fRawName[prefixLen+1], fLocalPart);
00258         }
00259          else
00260         {
00261             return fLocalPart;
00262         }
00263     }
00264     return fRawName;
00265 }
00266 
00267 // ---------------------------------------------------------------------------
00268 //  QName: Setter methods
00269 // ---------------------------------------------------------------------------
00270 void QName::setName(const XMLCh* const    prefix
00271                   , const XMLCh* const    localPart
00272                   , const unsigned int    uriId)
00273 {
00274     setPrefix(prefix);
00275     setLocalPart(localPart);
00276 
00277     // And clean up any QName and leave it undone until/if asked for again
00278     if (fRawName)
00279         *fRawName = 0;
00280 
00281     // And finally store the URI id parameter
00282     fURIId = uriId;
00283 }
00284 
00285 void QName::setName(const XMLCh* const    rawName
00286                   , const unsigned int    uriId)
00287 {
00288     //set the rawName
00289     XMLSize_t newLen = XMLString::stringLen(rawName);
00290     //find out the prefix and localPart from the rawName
00291     const int colonInd = XMLString::indexOf(rawName, chColon);
00292 
00293     if (colonInd >= 0)
00294     {
00295         if (!fRawNameBufSz || (newLen > fRawNameBufSz))
00296         {
00297             fMemoryManager->deallocate(fRawName); //delete [] fRawName;
00298             fRawName = 0;
00299             fRawNameBufSz = newLen + 8;
00300             fRawName = (XMLCh*) fMemoryManager->allocate
00301             (
00302                 (fRawNameBufSz + 1) * sizeof(XMLCh)
00303             ); //new XMLCh[fRawNameBufSz + 1];
00304         }
00305         XMLString::moveChars(fRawName, rawName, newLen + 1);
00306         setNPrefix(rawName, colonInd);
00307     }
00308     else
00309     {
00310         // No colon, so we just have a name with no prefix
00311         setNPrefix(XMLUni::fgZeroLenString, 0);
00312 
00313         // And clean up any QName and leave it undone until/if asked for again
00314         if (fRawName)
00315             *fRawName = 0;
00316     }
00317 
00318     setNLocalPart(&rawName[colonInd+1], newLen-colonInd-1);
00319 
00320     // And finally store the URI id parameter
00321     fURIId = uriId;
00322 }
00323 
00324 void QName::setNPrefix(const XMLCh* prefix, const XMLSize_t newLen)
00325 {
00326     if (!fPrefixBufSz || (newLen > fPrefixBufSz))
00327     {
00328         fMemoryManager->deallocate(fPrefix); //delete [] fPrefix;
00329         fPrefix = 0;
00330         fPrefixBufSz = newLen + 8;
00331         fPrefix = (XMLCh*) fMemoryManager->allocate
00332         (
00333             (fPrefixBufSz + 1) * sizeof(XMLCh)
00334         ); //new XMLCh[fPrefixBufSz + 1];
00335     }
00336     XMLString::moveChars(fPrefix, prefix, newLen);
00337     fPrefix[newLen] = chNull;
00338 }
00339 
00340 void QName::setNLocalPart(const XMLCh* localPart, const XMLSize_t newLen)
00341 {
00342     if (!fLocalPartBufSz || (newLen > fLocalPartBufSz))
00343     {
00344         fMemoryManager->deallocate(fLocalPart); //delete [] fLocalPart;
00345         fLocalPart = 0;
00346         fLocalPartBufSz = newLen + 8;
00347         fLocalPart = (XMLCh*) fMemoryManager->allocate
00348         (
00349             (fLocalPartBufSz + 1) * sizeof(XMLCh)
00350         ); //new XMLCh[fLocalPartBufSz + 1];
00351     }
00352     XMLString::moveChars(fLocalPart, localPart, newLen);
00353     fLocalPart[newLen] = chNull;
00354 }
00355 
00356 void QName::setValues(const QName& qname)
00357 {
00358     setPrefix(qname.getPrefix());
00359     setLocalPart(qname.getLocalPart());
00360     setURI(qname.getURI());
00361 }
00362 
00363 // -----------------------------------------------------------------------
00364 //  comparison
00365 // -----------------------------------------------------------------------
00366 bool QName::operator==(const QName& qname) const
00367 {
00368     // if we are an unitialized QName, check that the other is unitialized too
00369     if (!fLocalPart && !fPrefix)
00370         return !qname.fLocalPart && !qname.fPrefix;
00371 
00372     if (fURIId == 0) // null URI
00373         return (XMLString::equals(getRawName(),qname.getRawName()));
00374 
00375     return ((fURIId == qname.getURI()) &&
00376            (XMLString::equals(fLocalPart, qname.getLocalPart())));
00377 }
00378 
00379 // ---------------------------------------------------------------------------
00380 //  QName: Private, helper methods
00381 // ---------------------------------------------------------------------------
00382 void QName::cleanUp()
00383 {
00384     fMemoryManager->deallocate(fLocalPart); //delete [] fLocalPart;
00385     fMemoryManager->deallocate(fPrefix); //delete [] fPrefix;
00386     fMemoryManager->deallocate(fRawName); //delete [] fRawName;
00387     fLocalPart = fPrefix = fRawName = 0;
00388 }
00389 
00390 /***
00391  * Support for Serialization/De-serialization
00392  ***/
00393 
00394 IMPL_XSERIALIZABLE_TOCREATE(QName)
00395 
00396 void QName::serialize(XSerializeEngine& serEng)
00397 {
00398 
00399     if (serEng.isStoring())
00400     {
00401         serEng.writeString(fPrefix, fPrefixBufSz, XSerializeEngine::toWriteBufferLen);
00402 
00403         serEng.writeString(fLocalPart, fLocalPartBufSz, XSerializeEngine::toWriteBufferLen);
00404 
00405         //do not serialize rawName
00406 
00407         serEng<<fURIId;
00408     }
00409     else
00410     {
00411         XMLSize_t dataLen = 0;
00412 
00413         serEng.readString(fPrefix, fPrefixBufSz, dataLen, XSerializeEngine::toReadBufferLen);
00414 
00415         serEng.readString(fLocalPart, fLocalPartBufSz, dataLen, XSerializeEngine::toReadBufferLen);
00416 
00417         //force raw name rebuilt
00418         fRawNameBufSz = 0;        
00419         fRawName = 0;
00420 
00421         serEng>>fURIId;
00422     }
00423 
00424 }
00425 
00426 XERCES_CPP_NAMESPACE_END