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: 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