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 + -
显示快捷键?