Simple version of toml reader

This commit is contained in:
jmsgrogan 2022-10-11 19:39:14 +01:00
parent 70991e59af
commit 48d21b9194
2 changed files with 91 additions and 25 deletions

View file

@ -6,16 +6,19 @@
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <iostream> #include <iostream>
#include <locale>
#include <string>
using Path = std::filesystem::path; using Path = std::filesystem::path;
class TomlSection class TomlTable
{ {
public: public:
using Comment = std::pair<unsigned, std::string>; using Comment = std::pair<unsigned, std::string>;
using KeyValuePairs = std::unordered_map<std::string, std::string>;
TomlSection(const std::string& tag) TomlTable(const std::string& header)
: mTag(tag) : mHeader(header)
{ {
} }
@ -25,33 +28,60 @@ public:
mComments.push_back(comment); mComments.push_back(comment);
} }
void addSection(std::unique_ptr<TomlSection> section) void addTable(std::unique_ptr<TomlTable> table)
{ {
mSections[section->getTag()] = std::move(section); mTables[table->getHeader()] = std::move(table);
} }
void addValue(const std::string& key, const std::string& value) void addKeyValuePair(const std::string& key, const std::string& value)
{ {
mValues[key] = value; mMap[key] = value;
} }
std::string getTag() const std::string getHeader() const
{ {
return mTag; return mHeader;
}
TomlTable* getTable(const std::string& path)
{
return mTables[path].get();
}
KeyValuePairs getKeyValuePairs() const
{
return mMap;
} }
private: private:
unsigned mLineOffset{ 0 }; unsigned mLineOffset{ 0 };
std::string mTag; std::string mHeader;
std::unordered_map<std::string, std::unique_ptr<TomlSection> > mSections; std::unordered_map<std::string, std::unique_ptr<TomlTable> > mTables;
std::unordered_map<std::string, std::string> mValues; KeyValuePairs mMap;
std::vector<Comment> mComments; std::vector<Comment> mComments;
}; };
class TomlContent class TomlContent
{ {
public:
TomlContent()
: mRootTable(std::make_unique<TomlTable>("root"))
{
}
TomlTable* getRootTable() const
{
return mRootTable.get();
}
TomlTable* getTable(const std::string& path) const
{
return mRootTable->getTable(path);
}
private: private:
std::unique_ptr<TomlSection> mRootSection; std::unique_ptr<TomlTable> mRootTable;
}; };
class TomlReader class TomlReader
@ -72,35 +102,45 @@ public:
{ {
const auto lines = File(input_path).readLines(); const auto lines = File(input_path).readLines();
mLastSectionOffset = 0; mLastSectionOffset = 0;
mWorkingSection = std::make_unique<TomlSection>("root"); mWorkingTable = mContent->getRootTable();
for (const auto& line : lines) for (const auto& line : lines)
{ {
processLine(line); processLine(line);
mLastSectionOffset++; mLastSectionOffset++;
} }
mWorkingTable = nullptr;
} }
void processLine(const std::string& line) void processLine(const std::string& line)
{ {
bool in_comment{ false }; bool in_comment{ false };
bool in_tag{ false }; bool in_header{ false };
bool found_key{ false };
std::string working_string; std::string working_string;
std::string key_string;
for (auto c : line) for (auto c : line)
{ {
if (c == '#' && !in_comment) if (c == '#' && !in_comment)
{ {
in_comment = true; in_comment = true;
} }
else if (c == '[' && !in_comment && !in_tag) else if (c == '[' && !in_comment && !in_header)
{ {
in_tag = true; in_header = true;
} }
else if (c == ']' && in_tag) else if (c == '=' && !in_comment && !in_header)
{
found_key = true;
key_string = working_string;
working_string = "";
}
else if (c == ']' && in_header)
{ {
break; break;
} }
else if (in_comment || in_tag) else
{ {
working_string += c; working_string += c;
} }
@ -108,17 +148,36 @@ public:
if (in_comment) if (in_comment)
{ {
std::cout << "Found comment at: " << mLastSectionOffset << " with value " << working_string; mWorkingTable->addComment({ mLastSectionOffset, working_string });
mWorkingSection->addComment({ mLastSectionOffset, working_string });
} }
else if (in_tag) else if (in_header)
{ {
std::cout << "Found tag at: " << mLastSectionOffset << " with value " << working_string; onHeader(working_string);
} }
else if (found_key)
{
std::locale locale;
key_string.erase(std::remove_if(key_string.begin(), key_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), key_string.end());
working_string.erase(std::remove_if(working_string.begin(), working_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), working_string.end());
onKeyValuePair(key_string, working_string);
}
}
void onHeader(const std::string& header)
{
auto new_table = std::make_unique<TomlTable>(header);
auto table_temp = new_table.get();
mWorkingTable->addTable(std::move(new_table));
mWorkingTable = table_temp;
}
void onKeyValuePair(const std::string key, const std::string value)
{
mWorkingTable->addKeyValuePair(key, value);
} }
private: private:
unsigned mLastSectionOffset{ 0 }; unsigned mLastSectionOffset{ 0 };
std::unique_ptr<TomlContent> mContent; std::unique_ptr<TomlContent> mContent;
std::unique_ptr<TomlSection> mWorkingSection; TomlTable* mWorkingTable{nullptr};
}; };

View file

@ -1,14 +1,21 @@
#include "TomlReader.h" #include "TomlReader.h"
#include <filesystem> #include <filesystem>
#include <iostream>
int main() int main()
{ {
const auto data_loc = std::filesystem::path(__FILE__) / "../data"; const auto data_loc = std::filesystem::path(__FILE__) / "../../data";
const auto sample_toml_file = data_loc / "sample_toml.toml"; const auto sample_toml_file = data_loc / "sample_toml.toml";
auto reader = TomlReader(); auto reader = TomlReader();
reader.read(sample_toml_file); reader.read(sample_toml_file);
auto themes_table = reader.getContent()->getTable("themes");
for (const auto& items : themes_table->getKeyValuePairs())
{
std::cout << "Got entry with key: " << items.first << " and val " << items.second << std::endl;
}
return 0; return 0;
} }