mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Make sure gdt values are escaped
This commit is contained in:
parent
ea7b1eadae
commit
603994ce61
@ -63,9 +63,36 @@ bool GdtReader::ReadStringContent(std::string& str)
|
||||
}
|
||||
|
||||
auto c = m_stream.get();
|
||||
while (c != '"' && c != '\n' && c != EOF)
|
||||
auto escaped = false;
|
||||
while ((escaped || c != '"' && c != '\n') && c != EOF)
|
||||
{
|
||||
ss << static_cast<char>(c);
|
||||
if (escaped)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case 'n':
|
||||
ss << '\n';
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
ss << '\r';
|
||||
break;
|
||||
|
||||
default:
|
||||
ss << static_cast<char>(c);
|
||||
break;
|
||||
}
|
||||
escaped = false;
|
||||
}
|
||||
else if(c == '\\')
|
||||
{
|
||||
escaped = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << static_cast<char>(c);
|
||||
}
|
||||
c = m_stream.get();
|
||||
}
|
||||
|
||||
@ -267,6 +294,55 @@ void GdtOutputStream::WriteVersion(const GdtVersion& gdtVersion)
|
||||
WriteEntry(versionEntry);
|
||||
}
|
||||
|
||||
void GdtOutputStream::WriteEscaped(const std::string& str) const
|
||||
{
|
||||
auto wroteBefore = false;
|
||||
for(auto i = 0u; i < str.size(); i++)
|
||||
{
|
||||
auto needsEscape = false;
|
||||
auto c = str[i];
|
||||
switch(c)
|
||||
{
|
||||
case '\r':
|
||||
needsEscape = true;
|
||||
c = 'r';
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
needsEscape = true;
|
||||
c = 'n';
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
needsEscape = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(needsEscape)
|
||||
{
|
||||
if(!wroteBefore)
|
||||
{
|
||||
wroteBefore = true;
|
||||
m_stream << std::string(str, 0, i);
|
||||
}
|
||||
|
||||
m_stream << '\\' << c;
|
||||
}
|
||||
else if(wroteBefore)
|
||||
{
|
||||
m_stream << c;
|
||||
}
|
||||
}
|
||||
|
||||
if(!wroteBefore)
|
||||
{
|
||||
m_stream << str;
|
||||
}
|
||||
}
|
||||
|
||||
void GdtOutputStream::WriteEntry(const GdtEntry& entry)
|
||||
{
|
||||
DoIntendation();
|
||||
@ -283,7 +359,9 @@ void GdtOutputStream::WriteEntry(const GdtEntry& entry)
|
||||
for (const auto& [propertyKey, propertyValue] : entry.m_properties)
|
||||
{
|
||||
DoIntendation();
|
||||
m_stream << "\"" << propertyKey << "\" \"" << propertyValue << "\"\n";
|
||||
m_stream << "\"" << propertyKey << "\" \"";
|
||||
WriteEscaped(propertyValue);
|
||||
m_stream << "\"\n";
|
||||
}
|
||||
|
||||
m_intendation_level--;
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
|
||||
void BeginStream();
|
||||
void WriteVersion(const GdtVersion& gdtVersion);
|
||||
void WriteEscaped(const std::string& str) const;
|
||||
void WriteEntry(const GdtEntry& entry);
|
||||
void EndStream();
|
||||
|
||||
|
@ -4,8 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "Obj/GDT/GdtEntry.h"
|
||||
#include "Obj/Gdt/GdtEntry.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
||||
class InfoString
|
||||
|
@ -300,4 +300,41 @@ namespace obj::gdt
|
||||
REQUIRE(entry.m_properties.at("idk") == "whattotypeanymore");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Gdt: Ensure can write gdt with escape values and parse it again", "[gdt]")
|
||||
{
|
||||
Gdt gdt;
|
||||
gdt.m_version.m_game = "whatagame";
|
||||
gdt.m_version.m_version = 6969;
|
||||
|
||||
{
|
||||
auto entry = std::make_unique<GdtEntry>("sickentry", "verycool.gdf");
|
||||
entry->m_properties["hello"] = "very\nkewl\\stuff";
|
||||
gdt.m_entries.emplace_back(std::move(entry));
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
GdtOutputStream::WriteGdt(gdt, ss);
|
||||
|
||||
std::cout << ss.str();
|
||||
|
||||
Gdt gdt2;
|
||||
GdtReader reader(ss);
|
||||
REQUIRE(reader.Read(gdt2));
|
||||
|
||||
REQUIRE(gdt2.m_version.m_game == "whatagame");
|
||||
REQUIRE(gdt2.m_version.m_version == 6969);
|
||||
|
||||
REQUIRE(gdt2.m_entries.size() == 1);
|
||||
|
||||
{
|
||||
const auto& entry = *gdt2.m_entries[0];
|
||||
REQUIRE(entry.m_name == "sickentry");
|
||||
REQUIRE(entry.m_gdf_name == "verycool.gdf");
|
||||
REQUIRE(entry.m_parent == nullptr);
|
||||
REQUIRE(entry.m_properties.size() == 1);
|
||||
|
||||
REQUIRE(entry.m_properties.at("hello") == "very\nkewl\\stuff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user