SPH
Config.cpp
Go to the documentation of this file.
1 #include "run/Config.h"
2 #include "io/FileSystem.h"
3 #include "system/Platform.h"
4 #include <fstream>
5 
7 
8 std::string quoted(const std::string& value) {
9  return "\"" + value + "\"";
10 }
11 
12 std::string unquoted(const std::string& value) {
13  const std::size_t n1 = value.find_first_of('"');
14  const std::size_t n2 = value.find_last_of('"');
15  if (n1 >= n2) {
16  throw ConfigException("Invalid string format");
17  }
18  return value.substr(n1 + 1, n2 - n1 - 1);
19 }
20 
21 SharedPtr<ConfigNode> ConfigNode::addChild(const std::string& name) {
22  return children.insert(name, makeShared<ConfigNode>());
23 }
24 
25 SharedPtr<ConfigNode> ConfigNode::getChild(const std::string& name) {
26  if (!children.contains(name)) {
27  throw ConfigException("Node '" + name + "' not in config.");
28  }
29  return children[name];
30 }
31 
33  return entries.size();
34 }
35 
36 void ConfigNode::enumerateChildren(Function<void(std::string, ConfigNode&)> func) {
37  for (auto& child : children) {
38  func(child.key, *child.value);
39 
40  child.value->enumerateChildren(func);
41  }
42 }
43 
44 void ConfigNode::write(const std::string& padding, std::stringstream& source) {
45  for (auto& element : entries) {
46  source << padding << quoted(element.key) << " = " << element.value << "\n";
47  }
48 
49  const std::string childPadding = padding + std::string(2, ' ');
50  for (auto& child : children) {
51  source << padding << quoted(child.key) << " [\n";
52  child.value->write(childPadding, source);
53  source << padding << "]\n";
54  }
55 }
56 
57 void ConfigNode::read(std::stringstream& source) {
58  std::string line;
59  while (std::getline(source, line)) {
60  if (line.empty()) {
61  continue;
62  } else if (line.back() == ']') {
63  break;
64  }
65 
66  Array<std::string> childAndBracket = split(line, '[');
67  if (childAndBracket.size() == 2) {
68  SharedPtr<ConfigNode> child = makeShared<ConfigNode>();
69  children.insert(unquoted(childAndBracket[0]), child);
70  child->read(source);
71  } else {
72  Pair<std::string> keyAndValue = splitByFirst(line, '=');
73  if (keyAndValue.empty()) {
74  throw ConfigException("Invalid line format: " + line);
75  }
76  entries.insert(unquoted(keyAndValue[0]), keyAndValue[1]);
77  }
78  }
79 }
80 
81 SharedPtr<ConfigNode> Config::addNode(const std::string& name) {
82  return nodes.insert(name, makeShared<ConfigNode>());
83 }
84 
85 SharedPtr<ConfigNode> Config::getNode(const std::string& name) {
86  if (SharedPtr<ConfigNode> node = this->tryGetNode(name)) {
87  return node;
88  }
89  throw ConfigException("Node '" + name + "' not in config.");
90 }
91 
92 
93 SharedPtr<ConfigNode> Config::tryGetNode(const std::string& name) {
94  if (nodes.contains(name)) {
95  return nodes[name];
96  } else {
97  return nullptr;
98  }
99 }
100 
101 void Config::read(std::stringstream& source) {
102  nodes.clear();
103  while (source && !source.eof()) {
104  SharedPtr<ConfigNode> node = makeShared<ConfigNode>();
105  std::string name;
106  std::getline(source, name, '[');
107  if (name.empty() || name == "\n") {
108  continue;
109  }
110  node->read(source);
111  nodes.insert(unquoted(name), node);
112  }
113 }
114 
115 std::string Config::write() {
116  std::stringstream source;
117  const std::string padding(2, ' ');
118  for (auto& element : nodes) {
119  source << quoted(element.key) << " [\n";
120  element.value->write(padding, source);
121  source << "]\n\n";
122  }
123  return source.str();
124 }
125 
126 void Config::save(const Path& path) {
127  std::ofstream ofs(path.native());
128  ofs << this->write();
129 }
130 
131 void Config::load(const Path& path) {
132  std::ifstream ifs(path.native());
133  std::stringstream buffer;
134  buffer << ifs.rdbuf();
135  this->read(buffer);
136 }
137 
138 void Config::enumerate(Function<void(std::string, ConfigNode&)> func) {
139  for (auto& element : nodes) {
140  func(element.key, *element.value);
141 
142  element.value->enumerateChildren(func);
143  }
144 }
145 
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
std::string unquoted(const std::string &value)
Removes leading and trailing quote from a string.
Definition: Config.cpp:12
NAMESPACE_SPH_BEGIN std::string quoted(const std::string &value)
Helper function wrapping a string by quotes.
Definition: Config.cpp:8
Interface for the configuration files storing job data.
Exception ConfigException
Definition: Config.h:17
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define NAMESPACE_SPH_END
Definition: Object.h:12
System functions.
Array< std::string > split(const std::string &s, const char delimiter)
Splits a string into an array of string using given delimiter.
Pair< std::string > splitByFirst(const std::string &s, const char delimiter)
Splits a string into two parts, using first occurence of given delimiter.
INLINE TCounter size() const noexcept
Definition: Array.h:193
Represents a single node in the hierarchy written into config file.
Definition: Config.h:198
void enumerateChildren(Function< void(std::string name, ConfigNode &node)> func)
Calls the provided functor for each child node.
Definition: Config.cpp:36
Size size() const
Returns the number of entries stored in the node.
Definition: Config.cpp:32
SharedPtr< ConfigNode > getChild(const std::string &name)
Returns a child node.
Definition: Config.cpp:25
SharedPtr< ConfigNode > addChild(const std::string &name)
Adds a new child node to this node.
Definition: Config.cpp:21
void read(std::stringstream &source)
Deserializes the input string stream into nodes.
Definition: Config.cpp:101
SharedPtr< ConfigNode > addNode(const std::string &name)
Adds a new node to the config.
Definition: Config.cpp:81
SharedPtr< ConfigNode > getNode(const std::string &name)
Returns a node with given name.
Definition: Config.cpp:85
void save(const Path &path)
Serializes all nodes in the config into a file.
Definition: Config.cpp:126
SharedPtr< ConfigNode > tryGetNode(const std::string &name)
Returns a node with given name or nullptr if no such node exists.
Definition: Config.cpp:93
std::string write()
Serializes all nodes in the config into a string.
Definition: Config.cpp:115
void load(const Path &path)
Reads content of given file and deserializes the config from the loaded string.
Definition: Config.cpp:131
void enumerate(Function< void(std::string, ConfigNode &)> func)
Calls the provided functor for all nodes in the config.
Definition: Config.cpp:138
Object representing a path on a filesystem.
Definition: Path.h:17
std::string native() const
Returns the native version of the path.
Definition: Path.cpp:71
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
INLINE bool empty() const
Return true if the array is empty.
Definition: StaticArray.h:154
INLINE Size size() const
Returns the number of elements in the map.
Definition: UnorderedMap.h:131
INLINE bool contains(const TKey &key) const
Returns true if the map contains element of given key.
Definition: UnorderedMap.h:126
INLINE void clear()
Removes all elements from the map.
Definition: UnorderedMap.h:97
INLINE TValue & insert(const TKey &key, const TValue &value)
Adds a new element into the map or sets new value of element with the same key.
Definition: UnorderedMap.h:51