Add helper functions for string comparison to RefId

depth-refraction
elsid 2 years ago
parent 6518688120
commit dfcea389be
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -263,7 +263,7 @@ void CSMDoc::CollectionReferencesStage::perform(int stage, Messages& messages)
std::deque<int>& indices = mState.getSubRecords()[cellId.getRefIdString()];
// collect moved references at the end of the container
bool interior = cellId.getRefIdString()[0] != '#';
const bool interior = !cellId.startsWith("#");
std::ostringstream stream;
if (!interior)
{
@ -367,7 +367,7 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
|| references != mState.getSubRecords().end())
{
CSMWorld::Cell cellRecord = cell.get();
bool interior = cellRecord.mId.getRefIdString()[0] != '#';
const bool interior = !cellRecord.mId.startsWith("#");
// count new references and adjust RefNumCount accordingsly
unsigned int newRefNum = cellRecord.mRefNumCounter;
@ -451,10 +451,9 @@ void CSMDoc::WritePathgridCollectionStage::perform(int stage, Messages& messages
if (pathgrid.isModified() || pathgrid.mState == CSMWorld::RecordBase::State_Deleted)
{
CSMWorld::Pathgrid record = pathgrid.get();
std::string recordIdString = record.mId.getRefIdString();
if (recordIdString[0] == '#')
if (record.mId.startsWith("#"))
{
std::istringstream stream(recordIdString.c_str());
std::istringstream stream(record.mId.getRefIdString());
char ignore;
stream >> ignore >> record.mData.mX >> record.mData.mY;
}

@ -47,7 +47,7 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
// Checking type and limits
// optimization - compare it to lists based on naming convention (f-float,i-int,s-string)
if (gmstIdString[0] == 'f')
if (gmst.mId.startsWith("f"))
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::FloatCount; ++i)
{
@ -74,7 +74,7 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
}
}
}
else if (gmstIdString[0] == 'i')
else if (gmst.mId.startsWith("i"))
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i)
{
@ -101,7 +101,7 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
}
}
}
else if (gmstIdString[0] == 's')
else if (gmst.mId.startsWith("s"))
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::StringCount; ++i)
{

@ -9,7 +9,7 @@ void CSMWorld::Pathgrid::load(ESM::ESMReader& esm, bool& isDeleted, const IdColl
load(esm, isDeleted);
// correct ID
if (!mId.empty() && mId.getRefIdString()[0] != '#' && cells.searchId(mId) == -1)
if (!mId.empty() && !mId.startsWith("#") && cells.searchId(mId) == -1)
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;

@ -243,7 +243,7 @@ namespace MWClass
bool Miscellaneous::isSoulGem(const MWWorld::ConstPtr& ptr) const
{
return Misc::StringUtils::ciStartsWith(ptr.getCellRef().getRefId().getRefIdString(), "misc_soulgem");
return ptr.getCellRef().getRefId().startsWith("misc_soulgem");
}
}

@ -1447,7 +1447,7 @@ namespace MWClass
bool Npc::isClass(const MWWorld::ConstPtr& ptr, std::string_view className) const
{
return Misc::StringUtils::ciEqual(ptr.get<ESM::NPC>()->mBase->mClass.getRefIdString(), className);
return ptr.get<ESM::NPC>()->mBase->mClass == className;
}
bool Npc::canSwim(const MWWorld::ConstPtr& ptr) const

@ -856,7 +856,7 @@ namespace MWMechanics
for (const ESM::GameSetting& currentSetting : gameSettings)
{
// Don't bother checking this GMST if it's not a sMagicBound* one.
if (!Misc::StringUtils::ciStartsWith(currentSetting.mId.getRefIdString(), "smagicbound"))
if (!currentSetting.mId.startsWith("smagicbound"))
continue;
// All sMagicBound* GMST's should be of type string

@ -526,8 +526,7 @@ namespace MWRender
addAnimSource(smodel, smodel);
if (!isWerewolf
&& Misc::StringUtils::lowerCase(mNpc->mRace.getRefIdString()).find("argonian") != std::string::npos)
if (!isWerewolf && mNpc->mRace.contains("argonian"))
addAnimSource("meshes\\xargonian_swimkna.nif", smodel);
}
else

@ -153,7 +153,7 @@ namespace MWWorld
{
std::vector<const T*> results;
std::copy_if(mShared.begin(), mShared.end(), std::back_inserter(results),
[prefix](const T* item) { return Misc::StringUtils::ciStartsWith(item->mId.getRefIdString(), prefix); });
[prefix](const T* item) { return item->mId.startsWith(prefix); });
if (!results.empty())
return results[Misc::Rng::rollDice(results.size(), prng)];
return nullptr;

@ -171,6 +171,11 @@ namespace
EXPECT_FALSE(ciStartsWith("foo", "foo bar"));
}
TEST(MiscStringsCiStartsWith, should_be_case_insensitive)
{
EXPECT_TRUE(ciStartsWith("foo bar", "FOO"));
}
TEST(MiscStringsFormat, string_format)
{
std::string f = "1%s2";
@ -192,4 +197,39 @@ namespace
EXPECT_EQ(Misc::StringUtils::format(f, view.substr(1, 1)), "122");
EXPECT_EQ(Misc::StringUtils::format(f, view.substr(2)), "12");
}
TEST(MiscStringsCiFind, should_return_zero_for_2_empty_strings)
{
EXPECT_EQ(ciFind(std::string_view(), std::string_view()), 0);
}
TEST(MiscStringsCiFind, should_return_zero_when_looking_for_empty_string)
{
EXPECT_EQ(ciFind("foo", std::string_view()), 0);
}
TEST(MiscStringsCiFind, should_return_npos_for_longer_substring)
{
EXPECT_EQ(ciFind("a", "aa"), std::string_view::npos);
}
TEST(MiscStringsCiFind, should_return_zero_for_the_same_string)
{
EXPECT_EQ(ciFind("foo", "foo"), 0);
}
TEST(MiscStringsCiFind, should_return_first_position_of_substring)
{
EXPECT_EQ(ciFind("foobar foobar", "bar"), 3);
}
TEST(MiscStringsCiFind, should_be_case_insensitive)
{
EXPECT_EQ(ciFind("foobar", "BAR"), 3);
}
TEST(MiscStringsCiFind, should_return_npos_for_absent_substring)
{
EXPECT_EQ(ciFind("foobar", "baz"), std::string_view::npos);
}
}

@ -44,6 +44,16 @@ namespace ESM
return Misc::StringUtils::ciEqual(mId, rhs);
}
bool RefId::startsWith(std::string_view prefix) const
{
return Misc::StringUtils::ciStartsWith(mId, prefix);
}
bool RefId::contains(std::string_view subString) const
{
return Misc::StringUtils::ciFind(mId, subString) != std::string_view::npos;
}
const RefId RefId::sEmpty = {};
}

@ -29,6 +29,10 @@ namespace ESM
bool empty() const { return mId.empty(); }
bool startsWith(std::string_view prefix) const;
bool contains(std::string_view subString) const;
bool operator==(const RefId& rhs) const;
bool operator==(std::string_view rhs) const;

@ -176,6 +176,16 @@ namespace Misc::StringUtils
return;
str.replace(pos, substr.size(), with);
}
inline std::string_view::size_type ciFind(std::string_view str, std::string_view substr)
{
if (str.size() < substr.size())
return std::string_view::npos;
for (std::string_view::size_type i = 0, n = str.size() - substr.size() + 1; i < n; ++i)
if (ciEqual(str.substr(i, substr.size()), substr))
return i;
return std::string_view::npos;
}
}
#endif

Loading…
Cancel
Save