Utils: Fix replace function in SmallString

You need to allocate the memory before you replace a smaller text with
a larger one. It has some overhead because you go two times over the text
but it is anyway not designed for a large text.

Change-Id: I2f56f1300a5daf9e26632b5b0667023a09ff4bd2
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2017-08-02 18:57:26 +02:00
committed by Tim Jenssen
parent 45dbc743b0
commit 4ae0c6782f
2 changed files with 66 additions and 2 deletions

View File

@@ -761,6 +761,27 @@ unittest_public:
return cacheLineBlocks * cacheLineSize;
}
size_type countOccurrence(SmallStringView text)
{
auto found = begin();
size_type count = 0;
while (true) {
found = std::search(found,
end(),
text.begin(),
text.end());
if (found == end())
break;
++count;
found += text.size();
}
return count;
}
private:
BasicSmallString(Internal::StringDataLayout<Size> data) noexcept
: m_data(data)
@@ -883,7 +904,6 @@ private:
std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size());
} else {
size_type newSize = size() + sizeDifference;
reserve(optimalCapacity(newSize));
setSize(newSize);
at(newSize) = 0;
}
@@ -896,8 +916,16 @@ private:
size_type sizeDifference = 0;
size_type startIndex = 0;
size_type replacementTextSizeDifference = toText.size() - fromText.size();
size_type occurrences = countOccurrence(fromText);
size_type newSize = size() + (replacementTextSizeDifference * occurrences);
if (occurrences > 0) {
reserve(optimalCapacity(newSize));
replaceLargerSizedRecursive(startIndex, fromText, toText, sizeDifference);
}
}
void setSize(size_type size)
{

View File

@@ -753,6 +753,42 @@ TEST(SmallString, Clear)
ASSERT_TRUE(text.isEmpty());
}
TEST(SmallString, NoOccurrencesForEmptyText)
{
SmallString text;
auto occurrences = text.countOccurrence("text");
ASSERT_THAT(occurrences, 0);
}
TEST(SmallString, NoOccurrencesInText)
{
SmallString text("here is some text, here is some text, here is some text");
auto occurrences = text.countOccurrence("texts");
ASSERT_THAT(occurrences, 0);
}
TEST(SmallString, SomeOccurrences)
{
SmallString text("here is some text, here is some text, here is some text");
auto occurrences = text.countOccurrence("text");
ASSERT_THAT(occurrences, 3);
}
TEST(SmallString, SomeMoreOccurrences)
{
SmallString text("texttexttext");
auto occurrences = text.countOccurrence("text");
ASSERT_THAT(occurrences, 3);
}
TEST(SmallString, ReplaceWithCharacter)
{
SmallString text("here is some text, here is some text, here is some text");