DwString::DwString(const DwString &aStr, size_t aPos, size_t aLen) { assert(aPos <= aStr.mLength); if(sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(aStr.CheckInvariants()) size_t pos = DW_MIN(aPos, aStr.mLength); size_t len = DW_MIN(aLen, aStr.mLength - pos); if(len > 0) { mRep = new_rep_reference(aStr.mRep); mStart = aStr.mStart + pos; mLength = len; } else /* if (len == 0) */ { mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } }
DwString::DwString(char *aBuf, size_t aSize, size_t aStart, size_t aLen) { assert(aBuf != 0); assert(aSize > 0); assert(aLen < aSize); assert(aStart < aSize - aLen); if(sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; DwStringRep *rep = new DwStringRep(aBuf, aSize); assert(rep != 0); if(rep != 0) { mRep = rep; mStart = aStart; mLength = aLen; } else /* if (rep == 0) */ { delete [] aBuf; } }
void DwString::ReleaseBuffer(char** aBuf, size_t* aSize, size_t* aStart, size_t* aLen) { assert(aBuf != 0); assert(aSize != 0); assert(aStart != 0); assert(aLen != 0); if (mRep->mRefCount == 1) { *aBuf = mRep->mBuffer; *aSize = mRep->mSize; } else { size_t size = mRep->mSize; char* buf = new char [size]; assert(buf != 0); if (buf != 0) { mem_copy(mRep->mBuffer, size, buf); *aBuf = buf; *aSize = size; } else { // If not throwing an exception, recover as best we can *aBuf = 0; *aSize = 0; *aStart = mStart = 0; *aLen = mLength = 0; return; } } *aStart = mStart; *aLen = mLength; mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; }
DwString::DwString() { if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; }
DwString::DwString(size_t aLen, char aChar) { assert(aLen != (size_t)-1); if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; _replace(0, mLength, aLen, aChar); }
DwString& DwString::assign(const DwString& aStr, size_t aPos, size_t aLen) { assert(aPos <= aStr.mLength); size_t pos = DW_MIN(aPos, aStr.mLength); size_t len = DW_MIN(aLen, aStr.mLength - pos); if (mRep == aStr.mRep) { mStart = aStr.mStart + pos; mLength = len; } else { delete_rep_safely(mRep); mRep = new_rep_reference(aStr.mRep); mStart = aStr.mStart + pos; mLength = len; } return *this; }
DwString::DwString(const char* aCstr) { if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; if ( aCstr ) { size_t len = strlen(aCstr); _replace(0, mLength, aCstr, len); } }
void DwString::_replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar) { assert(aPos1 <= mLength); size_t pos1 = DW_MIN(aPos1, mLength); size_t len1 = DW_MIN(aLen1, mLength - pos1); assert(mStart + mLength - len1 < ((size_t) - 1) - aLen2); size_t len2 = DW_MIN(aLen2, ((size_t) - 1) - (mStart + mLength - len1)); size_t i; char *to; const char *from; size_t newLen = mLength - len1 + len2; // Is new string empty? if(newLen == 0) { if(mRep != sEmptyRep) { delete_rep_safely(mRep); mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } } // Is buffer shared? Is buffer too small? else if(mRep->mRefCount > 1 || newLen >= mRep->mSize) { size_t size = newLen + 1; char *newBuf = mem_alloc(&size); assert(newBuf != 0); if(newBuf != 0) { to = newBuf; from = mRep->mBuffer + mStart; for(i = 0; i < pos1; ++i) *to++ = *from++; for(i = 0; i < len2; ++i) *to++ = aChar; from = mRep->mBuffer + mStart + pos1 + len1; for(i = 0; i < mLength - pos1 - len1; ++i) *to++ = *from++; *to = 0; DwStringRep *rep = new DwStringRep(newBuf, size); assert(rep != 0); if(rep != 0) { delete_rep_safely(mRep); mRep = rep; mStart = 0; mLength = newLen; } } } // Is the replacement smaller than the replaced? else if(len2 < len1) { to = mRep->mBuffer + mStart + pos1; for(i = 0; i < len2; ++i) *to++ = aChar; from = mRep->mBuffer + mStart + pos1 + len1; for(i = 0; i < mLength - pos1 - len1; ++i) *to++ = *from++; *to = 0; mLength = newLen; } // Is there enough room at end of buffer? else if(mStart + newLen < mRep->mSize) { to = mRep->mBuffer + mStart + newLen; from = mRep->mBuffer + mStart + mLength - 1; *to-- = 0; for(i = 0; i < mLength - pos1 - len1; ++i) *to-- = *from--; for(i = 0; i < len2; ++i) *to-- = aChar; mLength = newLen; } // Is there enough room at beginning of buffer? else if(len2 - len1 <= mStart) { to = mRep->mBuffer + mStart - (len2 - len1); from = mRep->mBuffer + mStart; for(i = 0; i < pos1; ++i) *to++ = *from++; for(i = 0; i < len2; ++i) *to++ = aChar; mStart -= len2 - len1; mLength = newLen; } // There's enough room, but we must move characters. else { to = mRep->mBuffer + newLen; from = mRep->mBuffer + mStart + mLength - 1; *to-- = 0; for(i = 0; i < mLength - pos1 - len1; ++i) *to-- = *from--; to = mRep->mBuffer; from = mRep->mBuffer + mStart; for(i = 0; i < pos1; ++i) *to++ = *from++; for(i = 0; i < len2; ++i) *to++ = aChar; mStart = 0; mLength = newLen; } }