GME  13
DOMCharacterDataImpl.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: DOMCharacterDataImpl.cpp 678766 2008-07-22 14:00:16Z borisk $
00020  */
00021 
00022 #include "DOMCharacterDataImpl.hpp"
00023 #include <xercesc/dom/DOMException.hpp>
00024 #include <xercesc/dom/DOMNode.hpp>
00025 #include "DOMRangeImpl.hpp"
00026 #include "DOMDocumentImpl.hpp"
00027 #include "DOMCasts.hpp"
00028 #include "DOMStringPool.hpp"
00029 #include <xercesc/util/XMLUniDefs.hpp>
00030 
00031 XERCES_CPP_NAMESPACE_BEGIN
00032 
00033 DOMCharacterDataImpl::DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat)
00034 {
00035     fDoc = (DOMDocumentImpl*)doc;
00036 
00037     XMLSize_t len=XMLString::stringLen(dat);
00038     fDataBuf = fDoc->popBuffer(len+1);
00039     if (!fDataBuf)
00040         fDataBuf = new (fDoc) DOMBuffer(fDoc, len+15);
00041     fDataBuf->set(dat, len);
00042 }
00043 
00044 DOMCharacterDataImpl::
00045 DOMCharacterDataImpl(DOMDocument *doc, const XMLCh* dat, XMLSize_t len)
00046 {
00047     fDoc = (DOMDocumentImpl*)doc;
00048 
00049     fDataBuf = fDoc->popBuffer(len+1);
00050 
00051     if (!fDataBuf)
00052         fDataBuf = new (fDoc) DOMBuffer(fDoc, len+15);
00053 
00054     fDataBuf->set(dat, len);
00055 }
00056 
00057 DOMCharacterDataImpl::DOMCharacterDataImpl(const DOMCharacterDataImpl &other)
00058 {
00059     fDoc = (DOMDocumentImpl*)other.fDoc;
00060 
00061     XMLSize_t len=other.getLength();
00062     fDataBuf = fDoc->popBuffer(len+1);
00063     if (!fDataBuf)
00064         fDataBuf = new (fDoc) DOMBuffer(fDoc, len+15);
00065     fDataBuf->set(other.fDataBuf->getRawBuffer(), len);
00066 }
00067 
00068 
00069 DOMCharacterDataImpl::~DOMCharacterDataImpl() {
00070 }
00071 
00072 
00073 const XMLCh * DOMCharacterDataImpl::getNodeValue() const
00074 {
00075     return fDataBuf->getRawBuffer();
00076 }
00077 
00078 
00079 void DOMCharacterDataImpl::setNodeValue(const DOMNode *node, const XMLCh *value)
00080 {
00081     if (castToNodeImpl(node)->isReadOnly())
00082         throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00083     fDataBuf->set(value);
00084 
00085     DOMDocumentImpl *doc = (DOMDocumentImpl *)node->getOwnerDocument();
00086     if (doc != 0) {
00087         Ranges* ranges = doc->getRanges();
00088         if (ranges != 0) {
00089             XMLSize_t sz = ranges->size();
00090             if (sz != 0) {
00091                 for (XMLSize_t i =0; i<sz; i++) {
00092                     ranges->elementAt(i)->receiveReplacedText((DOMNode*)node);
00093                 }
00094             }
00095         }
00096     }
00097 }
00098 
00099 
00100 void DOMCharacterDataImpl::appendData(const DOMNode *node, const XMLCh *dat)
00101 {
00102     if(castToNodeImpl(node)->isReadOnly())
00103         throw DOMException(
00104         DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00105 
00106     fDataBuf->append(dat);
00107 }
00108 
00109 void DOMCharacterDataImpl::appendData(const DOMNode *node, const  XMLCh *dat, XMLSize_t n)
00110 {
00111   if(castToNodeImpl(node)->isReadOnly())
00112         throw DOMException(
00113         DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00114 
00115   fDataBuf->append(dat, n);
00116 }
00117 
00118 void DOMCharacterDataImpl::deleteData(const DOMNode *node, XMLSize_t offset, XMLSize_t count)
00119 {
00120     if (castToNodeImpl(node)->isReadOnly())
00121         throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00122 
00123     // Note: the C++ XMLCh * operation throws the correct DOMExceptions
00124     //       when parameter values are bad.
00125     //
00126 
00127     XMLSize_t len = this->fDataBuf->getLen();
00128     if (offset > len)
00129         throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00130 
00131 
00132 
00133     // Cap the value of delLength to avoid trouble with overflows
00134     //  in the following length computations.
00135     if (count > len)
00136         count = len;
00137 
00138     // If the length of data to be deleted would extend off the end
00139     //   of the string, cut it back to stop at the end of string.
00140     if (offset + count >= len)
00141         count = len - offset;
00142 
00143     XMLSize_t newLen = len - count;
00144 
00145     XMLCh* newString;
00146     XMLCh temp[4096];
00147     if (newLen >= 4095)
00148         newString = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate
00149         (
00150             (newLen+1) * sizeof(XMLCh)
00151         );//new XMLCh[newLen+1];
00152     else
00153         newString = temp;
00154 
00155     XMLString::copyNString(newString, fDataBuf->getRawBuffer(), offset);
00156     XMLString::copyString(newString+offset, fDataBuf->getRawBuffer()+offset+count);
00157 
00158     fDataBuf->set(newString);
00159 
00160     if (newLen >= 4095)
00161         XMLPlatformUtils::fgMemoryManager->deallocate(newString);//delete[] newString;
00162 
00163     // We don't delete the old string (doesn't work), or alter
00164     //   the old string (may be shared)
00165     //   It just hangs around, possibly orphaned.
00166 
00167     DOMDocumentImpl *doc = (DOMDocumentImpl *)node->getOwnerDocument();
00168     if (doc != 0) {
00169         Ranges* ranges = doc->getRanges();
00170         if (ranges != 0) {
00171             XMLSize_t sz = ranges->size();
00172             if (sz != 0) {
00173                 for (XMLSize_t i =0; i<sz; i++) {
00174                     ranges->elementAt(i)->updateRangeForDeletedText( (DOMNode*)node, offset, count);
00175                 }
00176             }
00177         }
00178     }
00179 }
00180 
00181 
00182 
00183 const XMLCh *DOMCharacterDataImpl::getData() const
00184 {
00185     return fDataBuf->getRawBuffer();
00186 }
00187 
00188 
00189 //
00190 //  getCharDataLength - return the length of the character data string.
00191 //
00192 XMLSize_t DOMCharacterDataImpl::getLength() const
00193 {
00194     return fDataBuf->getLen();
00195 }
00196 
00197 
00198 
00199 void DOMCharacterDataImpl::insertData(const DOMNode *node, XMLSize_t offset, const XMLCh *dat)
00200 {
00201     if (castToNodeImpl(node)->isReadOnly())
00202         throw DOMException(
00203         DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00204 
00205     // Note: the C++ XMLCh * operation throws the correct DOMExceptions
00206     //       when parameter values are bad.
00207     //
00208 
00209     XMLSize_t len = fDataBuf->getLen();
00210     if (offset > len)
00211         throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00212 
00213     XMLSize_t datLen = XMLString::stringLen(dat);
00214 
00215     XMLSize_t newLen = len + datLen;
00216 
00217     XMLCh* newString;
00218     XMLCh temp[4096];
00219     if (newLen >= 4095)
00220         newString = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate
00221         (
00222             (newLen + 1) * sizeof(XMLCh)
00223         );//new XMLCh[newLen+1];
00224     else
00225         newString = temp;
00226 
00227     XMLString::copyNString(newString, fDataBuf->getRawBuffer(), offset);
00228     XMLString::copyNString(newString+offset, dat, datLen);
00229     XMLString::copyString(newString+offset+datLen, fDataBuf->getRawBuffer()+offset);
00230 
00231     fDataBuf->set(newString);
00232 
00233     if (newLen >= 4095)
00234         XMLPlatformUtils::fgMemoryManager->deallocate(newString);//delete[] newString;
00235 
00236     DOMDocumentImpl *doc = (DOMDocumentImpl *)node->getOwnerDocument();
00237     if (doc != 0) {
00238         Ranges* ranges = doc->getRanges();
00239         if (ranges != 0) {
00240             XMLSize_t sz = ranges->size();
00241             if (sz != 0) {
00242                 for (XMLSize_t i =0; i<sz; i++) {
00243                     ranges->elementAt(i)->updateRangeForInsertedText( (DOMNode*)node, offset, datLen);
00244                 }
00245             }
00246         }
00247     }
00248 }
00249 
00250 
00251 
00252 void DOMCharacterDataImpl::replaceData(const DOMNode *node, XMLSize_t offset, XMLSize_t count,
00253                                     const XMLCh *dat)
00254 {
00255     if (castToNodeImpl(node)->isReadOnly())
00256         throw DOMException(
00257         DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00258 
00259     deleteData(node, offset, count);
00260     insertData(node, offset, dat);
00261 }
00262 
00263 
00264 
00265 
00266 void DOMCharacterDataImpl::setData(const DOMNode *node, const XMLCh *arg)
00267 {
00268     setNodeValue(node, arg);
00269 }
00270 
00271 
00272 
00273 
00274 
00275 const XMLCh * DOMCharacterDataImpl::substringData(const DOMNode *node, XMLSize_t offset,
00276                                            XMLSize_t count) const
00277 {
00278 
00279     // Note: the C++ XMLCh * operation throws the correct DOMExceptions
00280     //       when parameter values are bad.
00281     //
00282 
00283 
00284     XMLSize_t len = fDataBuf->getLen();
00285 
00286     if (offset > len)
00287         throw DOMException(DOMException::INDEX_SIZE_ERR, 0, GetDOMCharacterDataImplMemoryManager);
00288 
00289     DOMDocumentImpl *doc = (DOMDocumentImpl *)node->getOwnerDocument();
00290 
00291     XMLCh* newString;
00292     XMLCh temp[4096];
00293     if (len >= 4095)
00294       newString = (XMLCh*) doc->getMemoryManager()->allocate
00295         (
00296             (len + 1) * sizeof(XMLCh)
00297         );//new XMLCh[len+1];
00298     else
00299         newString = temp;
00300 
00301     XMLString::copyNString(newString, fDataBuf->getRawBuffer()+offset, count);
00302     newString[count] = chNull;
00303 
00304     const XMLCh* retString = doc->getPooledString(newString);
00305 
00306     if (len >= 4095)
00307       doc->getMemoryManager()->deallocate(newString);//delete[] newString;
00308 
00309     return retString;
00310 
00311 }
00312 
00313 
00314 void DOMCharacterDataImpl::releaseBuffer() {
00315     fDoc->releaseBuffer(fDataBuf);
00316 }
00317 
00318 XERCES_CPP_NAMESPACE_END