implemented real CIniFileSection::Insert function, and distinguished with Append .

This commit is contained in:
Zero Fanker 2024-06-17 00:44:31 -04:00
parent 78d3b083e1
commit 58b0de0907
3 changed files with 65 additions and 6 deletions

View file

@ -137,6 +137,15 @@ public:
return this->FindValue(val) >= 0;
}
size_t LowerBound(const CString& key) const {
auto const it = value_pos.lower_bound(key);
if (it != value_pos.end()) {
return it->second;
}
return value_pairs.size();
}
// ==================== Modify
void SetString(const CString& key, const CString& value) {
return this->SetString(key, CString(value));
}
@ -145,7 +154,7 @@ public:
auto const it = value_pos.find(key);
// new, never had one
if (it == value_pos.end()) {
this->Insert(key, std::move(value));
this->Append(key, std::move(value));
return;
}
value_pairs[it->second].second = std::move(value);
@ -159,15 +168,31 @@ public:
this->SetString(key, INIHelper::ToString(val));
}
void Insert(const CString& key, const CString& value) {
this->Insert(key, CString(value));
void Append(const CString& key, const CString& value) {
this->Append(key, CString(value));
}
void Insert(const CString& key, CString&& value) {
void Append(const CString& key, CString&& value) {
value_pairs.push_back({ key, value });
value_pos.insert_or_assign(key, value_pairs.size() - 1);
}
void InsertAt(size_t idx, CString&& key, CString&& value) {
if (idx > value_pairs.size()) {
idx = value_pairs.size() - 1;
}
value_pairs.insert(value_pairs.begin() + idx, { key, value });
value_pos.insert_or_assign(key, idx);
// fix all indexes
for (auto it = value_pos.upper_bound(key); it != value_pos.end(); ++it) {
it->second++;
}
}
void Insert(CString&& key, CString&& value) {
auto const pos = LowerBound(key);
InsertAt(pos, std::move(key), std::move(value));
}
// ==================== Delete
void RemoveAt(size_t idx) {
@ -309,7 +334,7 @@ public:
// ============== Writer and Helper converter ============================
CIniFileSection& AddSection(CString&& sectionName) {
auto const ret = this->sections.insert({ std::move(sectionName), {} });
auto const ret = this->sections.try_emplace(std::move(sectionName), CIniFileSection{});
return ret.first->second;
}
CIniFileSection& AddSection(const CString& sectionName) {

View file

@ -4216,7 +4216,7 @@ void CLoading::HackRules()
auto const pSec = rules.TryGetSection("BuildingTypes");
ASSERT(pSec != nullptr);
if (!pSec->HasValue(gateOne)) {
pSec->Insert(gateOne, gateOne);
pSec->Append(gateOne, gateOne);
}
}

View file

@ -237,4 +237,38 @@ CliffsWater2=112
EXPECT_EQ(0, file.GetInteger("NewUrbanInfo", "Morphable2"));
EXPECT_EQ(false, file["NewUrbanInfo"].Exists("Morphable2"));
}
TEST(CIniFileClass, IniLowerBoundInsertTest) {
auto const fileName = "test.ini";
IniTestHelper helper(fileName, R"(
[Waypoints]
0=123456
1=456123
2=123654
5=789654
6=654789
10=159357
)");
CIniFile file;
ASSERT_EQ(file.LoadFile(std::string(fileName)), 0);
EXPECT_EQ(123654, file.GetInteger("Waypoints", "2"));
auto const pSec = file.TryGetSection("Waypoints");
EXPECT_NE(pSec, nullptr);
auto const pos = pSec->LowerBound("4");
EXPECT_LE(pos, pSec->Size());
pSec->InsertAt(pos, "4", "432156");
EXPECT_EQ(432156, file.GetInteger("Waypoints", "4"));
EXPECT_EQ("432156", file["Waypoints"].Nth(3).second);
EXPECT_EQ("789654", file["Waypoints"].Nth(4).second);
pSec->Insert("9", "149367");
pSec->Insert("11", "987654");
EXPECT_EQ(149367, file.GetInteger("Waypoints", "9"));
EXPECT_EQ(987654, file.GetInteger("Waypoints", "11"));
EXPECT_EQ("987654", file["Waypoints"].Nth(pSec->Size() - 1).second);
EXPECT_EQ("159357", file["Waypoints"].Nth(pSec->Size() - 2).second);
}