domstring.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,182 行 · 第 1/3 页
CPP
1,182 行
if (srcLen == 0) return; // The charsNeeded normally is same as srcLen. To enhance performance, // we start with this estimate, and if overflow, then call calcRequiredSize for actual size fHandle = DOMStringHandle::createNewStringHandle(srcLen + 1); XMLCh *strData = fHandle->fDSData->fData; if (!uniConverter->transcode(srcString, strData, srcLen) || (XMLString::stringLen(strData) != srcLen)) { // conversion failed, so try again if (fHandle) fHandle->removeRef(); fHandle = 0; srcLen = uniConverter->calcRequiredSize(srcString); fHandle = DOMStringHandle::createNewStringHandle(srcLen + 1); XMLCh *strData2 = fHandle->fDSData->fData; if (!uniConverter->transcode(srcString, strData2, srcLen)) { // <TBD> We should throw something here? } } fHandle->fLength = srcLen; }};DOMString::DOMString(int nullValue){ assert(nullValue == 0); fHandle = 0;};DOMString::~DOMString(){ if (fHandle) fHandle->removeRef(); fHandle = 0;};DOMString & DOMString::operator =(const DOMString &other){ if (this == &other) return *this; if (fHandle) fHandle->removeRef(); fHandle = other.fHandle; if (fHandle) fHandle->addRef(); return *this;};DOMString & DOMString::operator = (DOM_NullPtr *arg){ assert(arg == 0); if (fHandle) fHandle->removeRef(); fHandle = 0; return *this;};bool DOMString::operator ==(const DOMString &other) const{ return this->fHandle == other.fHandle;};bool DOMString::operator !=(const DOMString &other) const{ return this->fHandle != other.fHandle;};bool DOMString::operator == (const DOM_NullPtr *p) const{ return (fHandle == 0);};bool DOMString::operator != (const DOM_NullPtr *p) const{ return (fHandle != 0);};void DOMString::reserve(unsigned int size){ if (fHandle == 0) { if (size > 0) fHandle = DOMStringHandle::createNewStringHandle(size); }}void DOMString::appendData(const DOMString &other){ if (other.fHandle == 0 || other.fHandle->fLength == 0) return; // If this string is empty and this string does not have an // already allocated buffer sufficient to hold the string being // appended, return a clone of the other string. // if (fHandle == 0 || (fHandle->fLength == 0 && fHandle->fDSData->fBufferLength < other.fHandle->fLength)) { if (fHandle) fHandle->removeRef(); this->fHandle = other.fHandle->cloneStringHandle(); return; } unsigned int newLength = fHandle->fLength + other.fHandle->fLength; if (newLength >= fHandle->fDSData->fBufferLength || fHandle->fDSData->fRefCount > 1) { // We can't stick the data to be added onto the end of the // existing string, either because there is not space in // the buffer, or because the buffer is being shared with // some other string. So, make a new buffer. DOMStringData *newBuf = DOMStringData::allocateBuffer(newLength); XMLCh *newP = newBuf->fData; XMLCh *oldP = fHandle->fDSData->fData; unsigned int i; for (i=0; i<fHandle->fLength; ++i) newP[i] = oldP[i]; fHandle->fDSData->removeRef(); fHandle->fDSData = newBuf; } // // This string now had enough buffer room to hold the data to // be appended. Go ahead and copy it in. XMLCh *srcP = other.fHandle->fDSData->fData; XMLCh *destP = &fHandle->fDSData->fData[fHandle->fLength]; unsigned int i; for (i=0; i<other.fHandle->fLength; i++) destP[i] = srcP[i]; fHandle->fLength += other.fHandle->fLength;}void DOMString::appendData(XMLCh ch){ unsigned int newLength = 0; if (fHandle == 0) { fHandle = DOMStringHandle::createNewStringHandle(1); newLength = 1; } else newLength = fHandle->fLength + 1; if (newLength >= fHandle->fDSData->fBufferLength || fHandle->fDSData->fRefCount > 1) { // We can't stick the data to be added onto the end of the // existing string, either because there is not space in // the buffer, or because the buffer is being shared with // some other string. So, make a new buffer. DOMStringData *newBuf = DOMStringData::allocateBuffer(newLength); XMLCh *newP = newBuf->fData; XMLCh *oldP = fHandle->fDSData->fData; unsigned int i; for (i=0; i<fHandle->fLength; ++i) newP[i] = oldP[i]; fHandle->fDSData->removeRef(); fHandle->fDSData = newBuf; } XMLCh *destP = &fHandle->fDSData->fData[fHandle->fLength]; destP[0] = ch; fHandle->fLength ++;}// TODO: A custom version could be written more efficiently, avoiding// the creation of the temporary DOMStringvoid DOMString::appendData(const XMLCh* other){ appendData(DOMString(other));}DOMString& DOMString::operator +=(const DOMString &other){ appendData(other); return *this;}DOMString& DOMString::operator +=(const XMLCh *str){ appendData(str); return *this;}DOMString& DOMString::operator +=(XMLCh ch){ appendData(ch); return *this;}XMLCh DOMString::charAt(unsigned int index) const{ XMLCh retCh = 0; if ((fHandle != 0) && (index < fHandle->fLength)) retCh = fHandle->fDSData->fData[index]; return retCh;};DOMString DOMString::clone() const{ DOMString retString; if (fHandle != 0) retString.fHandle = this->fHandle->cloneStringHandle(); return retString;};void DOMString::deleteData(unsigned int offset, unsigned int delLength){ unsigned int stringLen = this->length(); if (offset > stringLen || offset < 0 || delLength < 0) throw DOM_DOMException(DOM_DOMException::INDEX_SIZE_ERR, 0); // Cap the value of delLength to avoid trouble with overflows // in the following length computations. if (delLength > stringLen) delLength = stringLen; // If the length of data to be deleted would extend off the end // of the string, cut it back to stop at the end of string. if (offset + delLength >= stringLen) delLength = stringLen - offset; if (delLength == 0) return; unsigned int newStringLength = stringLen - delLength; if (fHandle->fDSData->fRefCount > 1 && offset+delLength < stringLen) { // The deletion is of a range in the middle of the string // and there's another string handle using the buffer so // we need to make a new buffer before moving characters // around. DOMStringData *newBuf = DOMStringData::allocateBuffer(newStringLength); XMLCh *newP = newBuf->fData; XMLCh *oldP = fHandle->fDSData->fData; unsigned int i; for (i=0; i<offset; i++) newP[i] = oldP[i]; for (i=offset; i<newStringLength; i++) newP[i] = oldP[i+delLength]; fHandle->fLength = newStringLength; fHandle->fDSData->removeRef(); fHandle->fDSData = newBuf; } else if (offset+delLength < stringLen) { // The deletion is of a range in the middle of the string, // but no other string is sharing the buffer, so we can // just delete in place. unsigned int i; XMLCh *bufP = fHandle->fDSData->fData; for (i=offset; i<newStringLength; i++) bufP[i] = bufP[i+delLength]; fHandle->fLength = newStringLength; } else { // The deletion continues to the end of the string. // Simply reset the length. We don't need to worry // about other strings sharing the buffer because // no characters are moved. fHandle->fLength = newStringLength; }};bool DOMString::equals(const DOMString &other) const{ bool retVal = true; if (this->fHandle != 0 && other.fHandle != 0) { if (this->fHandle->fLength != other.fHandle->fLength) { retVal = false; } else { XMLCh *thisP = this->fHandle->fDSData->fData; XMLCh *otherP = other.fHandle->fDSData->fData; unsigned int i; for (i=0; i<this->fHandle->fLength; i++) { if (thisP[i] != otherP[i]) { retVal = false; break; } } } } else { // At this point, one or more of the fHandle // pointers is known to be zero. if (fHandle && fHandle->fLength != 0 || other.fHandle && other.fHandle->fLength != 0) retVal = false; } return retVal;};bool DOMString::equals(const XMLCh *other) const{ if (this->fHandle != 0 && other != 0) { // Both strings have non-null data pointers, so // we can go ahead and actually compare them. XMLCh *thisP = this->fHandle->fDSData->fData; unsigned int len = this->fHandle->fLength; unsigned int i; for (i=0; i<len; i++) { if (other[i] == 0) // "other" is null terminated. return false; // (If there were no chance of a DOM // string having a 0 char in the middle of // it, this test could be omitted.) if (thisP[i] != other[i]) return false; } if (other[len] != 0) // This test for the end of the other return false; // string can't be done without first // checking that we haven't walked off the // end. (It has actually happened - off end // of string, page, and valid memory.) return true; } // At this point, we know that at least one of the strings had a null // data pointer. if (fHandle && fHandle->fLength != 0) return false; if (other && *other != 0) return false; return true; // Both strings are empty. DOMString treats zero-length // and a null data pointer as equivalent.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?