Allolib  1.0
C++ Components For Interactive Multimedia
al_Toml.hpp
1 #ifndef INCLUDE_AL_TOML_HPP
2 #define INCLUDE_AL_TOML_HPP
3 
4 #include <cstdint>
5 #include <iostream>
6 #include <sstream>
7 #include <stdexcept> // std::runtime_error
8 #include <string>
9 #include <vector>
10 
11 #include "al/io/al_File.hpp"
12 #include "cpptoml.h"
13 
14 namespace al {
15 
20 struct TomlLoader {
21  std::shared_ptr<cpptoml::table> root;
22  std::string mFilename;
23 
24  TomlLoader() {}
25 
26  TomlLoader(const std::string& filename) { setFile(filename); }
27 
28  void setFile(const std::string& filename) {
29  if (!al::File::exists(filename)) {
30  std::cout << "TomlLoader creating config file: " << filename << std::endl;
31  al::File configFile(filename);
32  if (configFile.open(filename, "w")) {
33  configFile.close();
34  } else {
35  std::cout << "ERROR: Unable to create config file: " << filename
36  << std::endl;
37  }
38  }
39  // will throw cpptoml::parse_exception if file is not found
40  root = cpptoml::parse_file(filename);
41  mFilename = filename;
42  }
43 
45  void writeFile(std::string filename = "") {
46  if (filename == "") {
47  filename = mFilename;
48  }
49  al::File configFile(filename, "w");
50  if (configFile.open()) {
51  std::ostringstream ss;
52  ss << (*root);
53  configFile.write(ss.str());
54  configFile.close();
55  } else {
56  std::cout << "ERROR: Opening toml file '" << filename << "' for writing."
57  << std::endl;
58  }
59  }
60 
61  template <typename T>
62  void setDefaultValue(const std::string& keyName, const T& value) {
63  if (!root) {
64  throw std::runtime_error(
65  "al::TomlLoader::setDefaultValue, toml file not set");
66  }
67  auto val = root->get_as<T>(keyName);
68  if (!val) {
69  root->insert(keyName, value);
70  }
71  }
72  template <typename T>
73  void setDefaultValueVector(const std::string& keyName,
74  const std::vector<T>& value) {
75  if (!root) {
76  throw std::runtime_error(
77  "al::TomlLoader::setDefaultValue, toml file not set");
78  }
79  auto val = root->get_array_of<T>(keyName);
80  if (!val) {
81  auto array = cpptoml::make_array();
82  for (auto& elem : value) {
83  array->push_back(elem);
84  }
85  root->insert(keyName, array);
86  }
87  }
88 
89  template <typename T>
90  bool hasKey(const std::string& keyName) {
91  if (root) {
92  auto val = root->get_as<T>(keyName);
93  if (val) {
94  return true;
95  }
96  }
97  return false;
98  }
99 
100  template <typename T>
101  void set(const std::string& key, const T& value) {
102  if (!root) {
103  throw std::runtime_error("al::TomlLoader::get, toml file not set");
104  }
105  root->insert(key, value);
106  }
107 
108  // get top level key's value, supported template parameter type are:
109  // std::string, int64_t, double, bool,
110  // cpptoml::local_date, cpptoml::local_time, cpptoml::local_datetime,
111  // cpptoml::offset_datetime
112  template <typename T>
113  T get(const std::string& key) {
114  if (!root) {
115  throw std::runtime_error("al::TomlLoader::get, toml file not set");
116  }
117  auto val = root->get_as<T>(key);
118  if (!val) {
119  throw std::runtime_error(std::string("al::TomlLoader::get, key '") + key +
120  std::string("' not found"));
121  }
122  return *val;
123  }
124 
125  // get second level (one table below) key's value.
126  // give table name and key name
127  template <typename T>
128  T get(const std::string& table_key, const std::string& key) {
129  if (!root) {
130  throw std::runtime_error("al::TomlLoader::get, toml file not set");
131  }
132  auto table = root->get_table(table_key);
133  if (!table) {
134  throw std::runtime_error(std::string("al::TomlLoader::get, table '") +
135  table_key + std::string("' not found"));
136  }
137  auto val = table->get_as<T>(key);
138  if (!val) {
139  throw std::runtime_error(std::string("al::TomlLoader::get, key '") + key +
140  std::string("' not found"));
141  }
142  return *val;
143  }
144 
145  double getd(const std::string& key) { return get<double>(key); }
146 
147  int64_t geti(const std::string& key) { return get<int64_t>(key); }
148 
149  std::string gets(const std::string& key) { return get<std::string>(key); }
150 
151  bool getb(const std::string& key) { return get<bool>(key); }
152 
153  double getd(const std::string& table, const std::string& key) {
154  return get<double>(table, key);
155  }
156 
157  int64_t geti(const std::string& table, const std::string& key) {
158  return get<int64_t>(table, key);
159  }
160 
161  std::string gets(const std::string& table, const std::string& key) {
162  return get<std::string>(table, key);
163  }
164 
165  bool getb(const std::string& table, const std::string& key) {
166  return get<bool>(table, key);
167  }
168 
169  template <typename T>
170  std::vector<T> getVector(const std::string& key) {
171  if (!root) {
172  throw std::runtime_error("al::TomlLoader::get, toml file not set");
173  }
174  auto vals = root->get_array_of<T>(key);
175  std::vector<T> outVector;
176  for (const T& val : *vals) {
177  outVector.push_back(val);
178  }
179  return outVector;
180  }
181 
182  template <typename T>
183  void setVector(const std::string& key, const std::vector<T>& vec) {
184  if (!root) {
185  throw std::runtime_error("al::TomlLoader::get, toml file not set");
186  }
187  auto array = cpptoml::make_array();
188  for (auto& elem : vec) {
189  array->push_back(elem);
190  }
191  root->insert(key, array);
192  }
193 };
194 
195 namespace TOML {
196 void setFile(const std::string& file);
197 double getd(const std::string& key);
198 int64_t geti(const std::string& key);
199 std::string gets(const std::string& key);
200 bool getb(const std::string& key);
201 double getd(const std::string& table, const std::string& key);
202 int64_t geti(const std::string& table, const std::string& key);
203 std::string gets(const std::string& table, const std::string& key);
204 bool getb(const std::string& table, const std::string& key);
205 } // namespace TOML
206 
207 } // namespace al
208 
209 #endif
File.
Definition: al_File.hpp:166
static bool exists(const std::string &path)
Returns whether a file or directory exists.
void close()
Close file.
int write(const std::string &v)
Write string to file.
Definition: al_File.hpp:208
bool open(const std::string &path, const std::string &mode="r")
Open file.
Definition: al_App.hpp:23
TomlLoader class.
Definition: al_Toml.hpp:20
void writeFile(std::string filename="")
Updates file on disk.
Definition: al_Toml.hpp:45