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; 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: private:
BasicSmallString(Internal::StringDataLayout<Size> data) noexcept BasicSmallString(Internal::StringDataLayout<Size> data) noexcept
: m_data(data) : m_data(data)
@@ -883,7 +904,6 @@ private:
std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size()); std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size());
} else { } else {
size_type newSize = size() + sizeDifference; size_type newSize = size() + sizeDifference;
reserve(optimalCapacity(newSize));
setSize(newSize); setSize(newSize);
at(newSize) = 0; at(newSize) = 0;
} }
@@ -896,7 +916,15 @@ private:
size_type sizeDifference = 0; size_type sizeDifference = 0;
size_type startIndex = 0; size_type startIndex = 0;
replaceLargerSizedRecursive(startIndex, fromText, toText, sizeDifference); 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) void setSize(size_type size)

View File

@@ -753,6 +753,42 @@ TEST(SmallString, Clear)
ASSERT_TRUE(text.isEmpty()); 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) TEST(SmallString, ReplaceWithCharacter)
{ {
SmallString text("here is some text, here is some text, here is some text"); SmallString text("here is some text, here is some text, here is some text");