GME
13
|
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