Backed out 2 changesets (bug 1101337) because of ASAN bustage landed on a CLOSED TREE

Backed out changeset ffef93ec94aa (bug 1101337)
Backed out changeset 2954a37bc2df (bug 1101337)
This commit is contained in:
Ehsan Akhgari 2014-12-12 13:04:44 -05:00
Родитель 169d700dd5
Коммит eb2d17cdf6
4 изменённых файлов: 7 добавлений и 245 удалений

Просмотреть файл

@ -106,7 +106,7 @@ static nsStringStats gStringStats;
// ---------------------------------------------------------------------------
void
inline void
ReleaseData(void* aData, uint32_t aFlags)
{
if (aFlags & nsSubstring::F_SHARED) {

Просмотреть файл

@ -386,11 +386,6 @@ public:
#ifdef CharT_is_PRUnichar
void ReplaceChar(const char16_t* aSet, char16_t aNewChar);
#endif
/**
* Replace all occurrences of aTarget with aNewValue.
* The complexity of this function is O(n+m), n being the length of the string
* and m being the length of aNewValue.
*/
void ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue);
void ReplaceSubstring(const char_type* aTarget, const char_type* aNewValue);
@ -463,14 +458,6 @@ protected:
: substring_type(aData, aLength, aFlags)
{
}
struct Segment {
uint32_t mBegin, mLength;
Segment(uint32_t aBegin, uint32_t aLength)
: mBegin(aBegin)
, mLength(aLength)
{}
};
};

Просмотреть файл

@ -4,7 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsTArray.h"
/**
* nsTString::Find
@ -451,8 +451,6 @@ nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
}
}
void ReleaseData(void* aData, uint32_t aFlags);
void
nsTString_CharT::ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue )
{
@ -466,91 +464,19 @@ nsTString_CharT::ReplaceSubstring( const self_type& aTarget, const self_type& aN
if (aTarget.Length() == 0)
return;
// Remember all of the non-matching parts.
nsAutoTArray<Segment, 16> nonMatching;
uint32_t i = 0;
uint32_t newLength = 0;
while (true)
while (i < mLength)
{
int32_t r = FindSubstring(mData + i, mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
int32_t until = (r == kNotFound) ? mLength - i : r;
nonMatching.AppendElement(Segment(i, until));
newLength += until;
if (r == kNotFound) {
if (r == kNotFound)
break;
}
newLength += aNewValue.Length();
i += r + aTarget.Length();
if (i >= mLength) {
// Add an auxiliary entry at the end of the list to help as an edge case
// for the algorithms below.
nonMatching.AppendElement(Segment(mLength, 0));
break;
}
Replace(i + r, aTarget.Length(), aNewValue);
i += r + aNewValue.Length();
}
// If there's only one non-matching segment, then the target string was not
// found, and there's nothing to do.
if (nonMatching.Length() == 1) {
MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == mLength,
"We should have the correct non-matching segment.");
return;
}
// Make sure that we can mutate our buffer.
char_type* oldData;
uint32_t oldFlags;
if (!MutatePrep(newLength, &oldData, &oldFlags))
return;
if (oldData) {
// Copy all of the old data to the new buffer.
char_traits::copy(mData, oldData, mLength);
::ReleaseData(oldData, oldFlags);
}
if (aTarget.Length() >= aNewValue.Length()) {
// In the shrinking case, start filling the buffer from the beginning.
const uint32_t delta = (aTarget.Length() - aNewValue.Length());
for (i = 1; i < nonMatching.Length(); ++i) {
// When we move the i'th non-matching segment into position, we need to
// account for the characters deleted by the previous |i| replacements by
// subtracting |i * delta|.
const char_type* sourceSegmentPtr = mData + nonMatching[i].mBegin;
char_type* destinationSegmentPtr = mData + nonMatching[i].mBegin - i * delta;
memmove(destinationSegmentPtr, sourceSegmentPtr,
sizeof(char_type) * nonMatching[i].mLength);
// Write the i'th replacement immediately before the new i'th non-matching
// segment.
char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
aNewValue.Data(), aNewValue.Length());
}
} else {
// In the growing case, start filling the buffer from the end.
const uint32_t delta = (aNewValue.Length() - aTarget.Length());
const uint32_t numNonMatching = nonMatching.Length();
if (numNonMatching > 1) {
for (i = numNonMatching - 1; i > 0; --i) {
// When we move the i'th non-matching segment into position, we need to
// account for the characters added by the previous |i| replacements
// by adding |i * delta|.
const char_type* sourceSegmentPtr = mData + nonMatching[i].mBegin;
char_type* destinationSegmentPtr = mData + nonMatching[i].mBegin + i * delta;
memmove(destinationSegmentPtr, sourceSegmentPtr,
sizeof(char_type) * nonMatching[i].mLength);
// Write the i'th replacement immediately before the new i'th
// non-matching segment.
char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
aNewValue.Data(), aNewValue.Length());
}
}
}
// Adjust the length and make sure the string is null terminated.
mLength = newLength;
mData[mLength] = char_type(0);
}
/**
* nsTString::Trim
*/

Просмотреть файл

@ -451,156 +451,6 @@ bool test_replace_substr_2()
return true;
}
bool test_replace_substr_3()
{
nsCString s;
s.Assign("abcabcabc");
s.ReplaceSubstring("ca", "X");
bool r = strcmp(s.get(), "abXbXbc") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcabcabc");
s.ReplaceSubstring("ca", "XYZ");
r = strcmp(s.get(), "abXYZbXYZbc") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcabcabc");
s.ReplaceSubstring("ca", "XY");
r = strcmp(s.get(), "abXYbXYbc") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcabcabc");
s.ReplaceSubstring("ca", "XYZ!");
r = strcmp(s.get(), "abXYZ!bXYZ!bc") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("bcd", "X");
r = strcmp(s.get(), "aXaXaX") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("bcd", "XYZ!");
r = strcmp(s.get(), "aXYZ!aXYZ!aXYZ!") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("bcd", "XY");
r = strcmp(s.get(), "aXYaXYaXY") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("bcd", "XYZABC");
r = strcmp(s.get(), "aXYZABCaXYZABCaXYZABC") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("bcd", "XYZ");
r = strcmp(s.get(), "aXYZaXYZaXYZ") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("bcd", "XYZ!");
r = strcmp(s.get(), "aXYZ!aXYZ!aXYZ!") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("ab", "X");
r = strcmp(s.get(), "XcdXcdXcd") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("ab", "XYZABC");
r = strcmp(s.get(), "XYZABCcdXYZABCcdXYZABCcd") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("ab", "XY");
r = strcmp(s.get(), "XYcdXYcdXYcd") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("ab", "XYZ!");
r = strcmp(s.get(), "XYZ!cdXYZ!cdXYZ!cd") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("notfound", "X");
r = strcmp(s.get(), "abcdabcdabcd") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
s.Assign("abcdabcdabcd");
s.ReplaceSubstring("notfound", "longlongstring");
r = strcmp(s.get(), "abcdabcdabcd") == 0;
if (!r)
{
printf("[s=%s]\n", s.get());
return false;
}
return true;
}
bool test_strip_ws()
{
const char text[] = " a $ ";
@ -1351,7 +1201,6 @@ tests[] =
{ "test_trim", test_trim },
{ "test_replace_substr", test_replace_substr },
{ "test_replace_substr_2", test_replace_substr_2 },
{ "test_replace_substr_3", test_replace_substr_3 },
{ "test_strip_ws", test_strip_ws },
{ "test_equals_ic", test_equals_ic },
{ "test_fixed_string", test_fixed_string },