Skip to content

Commit

Permalink
refactor(code): Small DataWriter refactor (endless-sky#10266)
Browse files Browse the repository at this point in the history
  • Loading branch information
tibetiroka authored Jun 28, 2024
1 parent 2ee93f1 commit ea8ebed
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 79 deletions.
25 changes: 18 additions & 7 deletions source/DataNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.

#include "DataNode.h"

#include "DataWriter.h"
#include "Logger.h"

#include <algorithm>
Expand Down Expand Up @@ -93,6 +94,14 @@ const vector<string> &DataNode::Tokens() const noexcept



// Add tokens to the node.
void DataNode::AddToken(const std::string &token)
{
tokens.emplace_back(token);
}



// Get the token with the given index. No bounds checking is done.
// DataFile loading guarantees index 0 always exists.
const string &DataNode::Token(int index) const
Expand Down Expand Up @@ -262,6 +271,14 @@ bool DataNode::IsBool(const string &token)



// Add a new child. The child's parent must be this node.
void DataNode::AddChild(const DataNode &child)
{
children.emplace_back(child);
}



// Check if this node has any children.
bool DataNode::HasChildren() const noexcept
{
Expand Down Expand Up @@ -307,13 +324,7 @@ int DataNode::PrintTrace(const string &message) const
{
if(&token != &tokens.front())
line += ' ';
bool hasSpace = any_of(token.begin(), token.end(), [](unsigned char c) { return isspace(c); });
bool hasQuote = any_of(token.begin(), token.end(), [](char c) { return (c == '"'); });
if(hasSpace)
line += hasQuote ? '`' : '"';
line += token;
if(hasSpace)
line += hasQuote ? '`' : '"';
line += DataWriter::Quote(token);
}
Logger::LogError(line);

Expand Down
4 changes: 4 additions & 0 deletions source/DataNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class DataNode {
int Size() const noexcept;
// Get all the tokens in this node as an iterable vector.
const std::vector<std::string> &Tokens() const noexcept;
// Add tokens to the node.
void AddToken(const std::string &token);
// Get the token at the given index. No bounds checking is done internally.
// DataFile loading guarantees index 0 always exists.
const std::string &Token(int index) const;
Expand All @@ -64,6 +66,8 @@ class DataNode {
bool IsBool(int index) const;
static bool IsBool(const std::string &token);

// Add a new child. The child's parent must be this node.
void AddChild(const DataNode &child);
// Check if this node has any children. If so, the iterator functions below
// can be used to access them.
bool HasChildren() const noexcept;
Expand Down
39 changes: 28 additions & 11 deletions source/DataWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ void DataWriter::SaveToPath(const std::string &filepath)



// Get the contents as a string.
string DataWriter::SaveToString()
{
return out.str();
}



// Write a DataNode with all its children.
void DataWriter::Write(const DataNode &node)
{
Expand Down Expand Up @@ -113,7 +121,8 @@ void DataWriter::EndChild()
// Write a comment line, at the current indentation level.
void DataWriter::WriteComment(const string &str)
{
out << indent << "# " << str << '\n';
out << *before << "# " << str;
Write();
}


Expand All @@ -128,22 +137,30 @@ void DataWriter::WriteToken(const char *a)

// Write a token, given as a string object.
void DataWriter::WriteToken(const string &a)
{
out << *before;
out << Quote(a);

// The next token written will not be the first one on this line, so it only
// needs to have a single space before it.
before = &space;
}



string DataWriter::Quote(const std::string &a)
{
// Figure out what kind of quotation marks need to be used for this string.
bool hasSpace = any_of(a.begin(), a.end(), [](unsigned char c) { return isspace(c); });
bool hasQuote = any_of(a.begin(), a.end(), [](char c) { return (c == '"'); });
bool hasBacktick = any_of(a.begin(), a.end(), [](char c) { return (c == '`'); });
// If the token is an empty string, it needs to be wrapped in quotes as if it had a space.
hasSpace |= a.empty();
// Write the token, enclosed in quotes if necessary.
out << *before;

if(hasQuote)
out << '`' << a << '`';
else if(hasSpace)
out << '"' << a << '"';
return '`' + a + '`';
else if(hasSpace || hasBacktick)
return '"' + a + '"';
else
out << a;

// The next token written will not be the first one on this line, so it only
// needs to have a single space before it.
before = &space;
return a;
}
5 changes: 5 additions & 0 deletions source/DataWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class DataWriter {

// Save the contents to a file.
void SaveToPath(const std::string &path);
// Get the contents as a string.
std::string SaveToString();

// The Write() function can take any number of arguments. Each argument is
// converted to a token. Arguments may be strings or numeric values.
Expand Down Expand Up @@ -75,6 +77,9 @@ class DataWriter {
template <class A>
void WriteToken(const A &a);

// Enclose a string in the correct quotation marks.
static std::string Quote(const std::string &text);


private:
// Save path (in UTF-8). Empty string for in-memory DataWriter.
Expand Down
Loading

0 comments on commit ea8ebed

Please sign in to comment.