UPInt String::GetLength() const { // Optimize length accesses for non-UTF8 character strings. DataDesc* pdata = GetData(); UPInt length, size = pdata->GetSize(); if (pdata->LengthIsSize()) return size; length = (UPInt)UTF8Util::GetLength(pdata->Data, (UPInt)size); if (length == size) pdata->Size |= String_LengthIsSize; return length; }
String String::Substring(UPInt start, UPInt end) const { UPInt length = GetLength(); if ((start >= length) || (start >= end)) return String(); DataDesc* pdata = GetData(); // If size matches, we know the exact index range. if (pdata->LengthIsSize()) return String(pdata->Data + start, end - start); // Get position of starting character. SPInt byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize()); SPInt byteSize = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart); return String(pdata->Data + byteStart, (UPInt)byteSize); }
UInt32 String::GetCharAt(UPInt index) const { SPInt i = (SPInt) index; DataDesc* pdata = GetData(); const char* buf = pdata->Data; UInt32 c; if (pdata->LengthIsSize()) { OVR_ASSERT(index < pdata->GetSize()); buf += i; return UTF8Util::DecodeNextChar_Advance0(&buf); } c = UTF8Util::GetCharAt(index, buf, pdata->GetSize()); return c; }
String& String::Insert(const char* substr, UPInt posAt, SPInt strSize) { DataDesc* poldData = GetData(); UPInt oldSize = poldData->GetSize(); UPInt insertSize = (strSize < 0) ? OVR_strlen(substr) : (UPInt)strSize; UPInt byteIndex = (poldData->LengthIsSize()) ? posAt : (UPInt)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize); OVR_ASSERT(byteIndex <= oldSize); DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0, poldData->Data, byteIndex, substr, insertSize); memcpy(pnewData->Data + byteIndex + insertSize, poldData->Data + byteIndex, oldSize - byteIndex); SetData(pnewData); poldData->Release(); return *this; }