First Commit
This commit is contained in:
commit
8a6c7106e3
1312 files changed
+425396
No files matched your search
+2379
File diff suppressed because it is too large.
Load diff
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) CK Tan
|
||||
https://github.com/cktan/tomlc99
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef TOML_H
|
||||
#define TOML_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define TOML_EXTERN extern "C"
|
||||
#else
|
||||
#define TOML_EXTERN extern
|
||||
#endif
|
||||
|
||||
typedef struct toml_timestamp_t toml_timestamp_t;
|
||||
typedef struct toml_table_t toml_table_t;
|
||||
typedef struct toml_array_t toml_array_t;
|
||||
typedef struct toml_datum_t toml_datum_t;
|
||||
|
||||
/* Parse a file. Return a table on success, or 0 otherwise.
|
||||
* Caller must toml_free(the-return-value) after use.
|
||||
*/
|
||||
TOML_EXTERN toml_table_t *toml_parse_file(FILE *fp, char *errbuf, int errbufsz);
|
||||
|
||||
/* Parse a string containing the full config.
|
||||
* Return a table on success, or 0 otherwise.
|
||||
* Caller must toml_free(the-return-value) after use.
|
||||
*/
|
||||
TOML_EXTERN toml_table_t *toml_parse(char *conf, /* NUL terminated, please. */
|
||||
char *errbuf, int errbufsz);
|
||||
|
||||
/* Free the table returned by toml_parse() or toml_parse_file(). Once
|
||||
* this function is called, any handles accessed through this tab
|
||||
* directly or indirectly are no longer valid.
|
||||
*/
|
||||
TOML_EXTERN void toml_free(toml_table_t *tab);
|
||||
|
||||
/* Timestamp types. The year, month, day, hour, minute, second, z
|
||||
* fields may be NULL if they are not relevant. e.g. In a DATE
|
||||
* type, the hour, minute, second and z fields will be NULLs.
|
||||
*/
|
||||
struct toml_timestamp_t {
|
||||
struct { /* internal. do not use. */
|
||||
int year, month, day;
|
||||
int hour, minute, second, millisec;
|
||||
char z[10];
|
||||
} __buffer;
|
||||
int *year, *month, *day;
|
||||
int *hour, *minute, *second, *millisec;
|
||||
char *z;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* Enhanced access methods
|
||||
*/
|
||||
struct toml_datum_t {
|
||||
int ok;
|
||||
union {
|
||||
toml_timestamp_t *ts; /* ts must be freed after use */
|
||||
char *s; /* string value. s must be freed after use */
|
||||
int b; /* bool value */
|
||||
int64_t i; /* int value */
|
||||
double d; /* double value */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* on arrays: */
|
||||
/* ... retrieve size of array. */
|
||||
TOML_EXTERN int toml_array_nelem(const toml_array_t *arr);
|
||||
/* ... retrieve values using index. */
|
||||
TOML_EXTERN toml_datum_t toml_string_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_bool_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_int_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_double_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_datum_t toml_timestamp_at(const toml_array_t *arr, int idx);
|
||||
/* ... retrieve array or table using index. */
|
||||
TOML_EXTERN toml_array_t *toml_array_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN toml_table_t *toml_table_at(const toml_array_t *arr, int idx);
|
||||
|
||||
/* on tables: */
|
||||
/* ... retrieve the key in table at keyidx. Return 0 if out of range. */
|
||||
TOML_EXTERN const char *toml_key_in(const toml_table_t *tab, int keyidx);
|
||||
/* ... returns 1 if key exists in tab, 0 otherwise */
|
||||
TOML_EXTERN int toml_key_exists(const toml_table_t *tab, const char *key);
|
||||
/* ... retrieve values using key. */
|
||||
TOML_EXTERN toml_datum_t toml_string_in(const toml_table_t *arr,
|
||||
const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_bool_in(const toml_table_t *arr, const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_int_in(const toml_table_t *arr, const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_double_in(const toml_table_t *arr,
|
||||
const char *key);
|
||||
TOML_EXTERN toml_datum_t toml_timestamp_in(const toml_table_t *arr,
|
||||
const char *key);
|
||||
/* .. retrieve array or table using key. */
|
||||
TOML_EXTERN toml_array_t *toml_array_in(const toml_table_t *tab,
|
||||
const char *key);
|
||||
TOML_EXTERN toml_table_t *toml_table_in(const toml_table_t *tab,
|
||||
const char *key);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* lesser used
|
||||
*/
|
||||
/* Return the array kind: 't'able, 'a'rray, 'v'alue, 'm'ixed */
|
||||
TOML_EXTERN char toml_array_kind(const toml_array_t *arr);
|
||||
|
||||
/* For array kind 'v'alue, return the type of values
|
||||
i:int, d:double, b:bool, s:string, t:time, D:date, T:timestamp, 'm'ixed
|
||||
0 if unknown
|
||||
*/
|
||||
TOML_EXTERN char toml_array_type(const toml_array_t *arr);
|
||||
|
||||
/* Return the key of an array */
|
||||
TOML_EXTERN const char *toml_array_key(const toml_array_t *arr);
|
||||
|
||||
/* Return the number of key-values in a table */
|
||||
TOML_EXTERN int toml_table_nkval(const toml_table_t *tab);
|
||||
|
||||
/* Return the number of arrays in a table */
|
||||
TOML_EXTERN int toml_table_narr(const toml_table_t *tab);
|
||||
|
||||
/* Return the number of sub-tables in a table */
|
||||
TOML_EXTERN int toml_table_ntab(const toml_table_t *tab);
|
||||
|
||||
/* Return the key of a table*/
|
||||
TOML_EXTERN const char *toml_table_key(const toml_table_t *tab);
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* misc
|
||||
*/
|
||||
TOML_EXTERN int toml_utf8_to_ucs(const char *orig, int len, int64_t *ret);
|
||||
TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
|
||||
TOML_EXTERN void toml_set_memutil(void *(*xxmalloc)(size_t),
|
||||
void (*xxfree)(void *));
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* deprecated
|
||||
*/
|
||||
/* A raw value, must be processed by toml_rto* before using. */
|
||||
typedef const char *toml_raw_t;
|
||||
TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t *tab, const char *key);
|
||||
TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t *arr, int idx);
|
||||
TOML_EXTERN int toml_rtos(toml_raw_t s, char **ret);
|
||||
TOML_EXTERN int toml_rtob(toml_raw_t s, int *ret);
|
||||
TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t *ret);
|
||||
TOML_EXTERN int toml_rtod(toml_raw_t s, double *ret);
|
||||
TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double *ret, char *buf, int buflen);
|
||||
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t *ret);
|
||||
|
||||
#endif /* TOML_H */
|
||||
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 CK Tan
|
||||
https://github.com/cktan/tomlcpp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
#include "tomlcpp.hpp"
|
||||
#include "toml.h"
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
|
||||
using namespace toml;
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
static void *toml_mymalloc(size_t sz) { return new char[sz]; }
|
||||
|
||||
static void toml_myfree(void *p) {
|
||||
if (p) {
|
||||
char *pp = (char *)p;
|
||||
delete[] pp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of memory to be freed when all references
|
||||
* to the tree returned by toml::parse is no longer reachable.
|
||||
*/
|
||||
struct toml::Backing {
|
||||
char *ptr = 0;
|
||||
toml_table_t *root = 0;
|
||||
Backing(const string &conf) {
|
||||
ptr = new char[conf.length() + 1];
|
||||
strcpy(ptr, conf.c_str());
|
||||
}
|
||||
~Backing() {
|
||||
if (ptr)
|
||||
delete[] ptr;
|
||||
if (root)
|
||||
toml_free(root);
|
||||
}
|
||||
};
|
||||
|
||||
pair<bool, string> Table::getString(const string &key) const {
|
||||
string str;
|
||||
toml_datum_t p = toml_string_in(m_table, key.c_str());
|
||||
if (p.ok) {
|
||||
str = p.u.s;
|
||||
toml_myfree(p.u.s);
|
||||
}
|
||||
return {p.ok, str};
|
||||
}
|
||||
|
||||
pair<bool, bool> Table::getBool(const string &key) const {
|
||||
toml_datum_t p = toml_bool_in(m_table, key.c_str());
|
||||
return {p.ok, !!p.u.b};
|
||||
}
|
||||
|
||||
pair<bool, int64_t> Table::getInt(const string &key) const {
|
||||
toml_datum_t p = toml_int_in(m_table, key.c_str());
|
||||
return {p.ok, p.u.i};
|
||||
}
|
||||
|
||||
pair<bool, double> Table::getDouble(const string &key) const {
|
||||
toml_datum_t p = toml_double_in(m_table, key.c_str());
|
||||
return {p.ok, p.u.d};
|
||||
}
|
||||
|
||||
pair<bool, Timestamp> Table::getTimestamp(const string &key) const {
|
||||
Timestamp ret;
|
||||
toml_datum_t p = toml_timestamp_in(m_table, key.c_str());
|
||||
if (p.ok) {
|
||||
toml_timestamp_t &ts = *p.u.ts;
|
||||
ret.year = (ts.year ? *ts.year : -1);
|
||||
ret.month = (ts.month ? *ts.month : -1);
|
||||
ret.day = (ts.day ? *ts.day : -1);
|
||||
ret.hour = (ts.hour ? *ts.hour : -1);
|
||||
ret.minute = (ts.minute ? *ts.minute : -1);
|
||||
ret.second = (ts.second ? *ts.second : -1);
|
||||
ret.millisec = (ts.millisec ? *ts.millisec : -1);
|
||||
ret.z = ts.z ? string(ts.z) : "";
|
||||
toml_myfree(p.u.ts);
|
||||
}
|
||||
return {p.ok, ret};
|
||||
}
|
||||
|
||||
std::unique_ptr<Array> Table::getArray(const string &key) const {
|
||||
toml_array_t *a = toml_array_in(m_table, key.c_str());
|
||||
if (!a)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<Array>(a, m_backing);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<Table> Table::getTable(const string &key) const {
|
||||
toml_table_t *t = toml_table_in(m_table, key.c_str());
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<Table>(t, m_backing);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<string> Table::keys() const {
|
||||
vector<string> vec;
|
||||
for (int i = 0;; i++) {
|
||||
const char *k = toml_key_in(m_table, i);
|
||||
if (!k)
|
||||
break;
|
||||
vec.push_back(k);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
char Array::kind() const { return toml_array_kind(m_array); }
|
||||
|
||||
char Array::type() const { return toml_array_type(m_array); }
|
||||
|
||||
pair<bool, string> Array::getString(int idx) const {
|
||||
string str;
|
||||
toml_datum_t p = toml_string_at(m_array, idx);
|
||||
if (p.ok) {
|
||||
str = p.u.s;
|
||||
toml_myfree(p.u.s);
|
||||
}
|
||||
return {p.ok, str};
|
||||
}
|
||||
|
||||
pair<bool, bool> Array::getBool(int idx) const {
|
||||
toml_datum_t p = toml_bool_at(m_array, idx);
|
||||
return {p.ok, !!p.u.b};
|
||||
}
|
||||
|
||||
pair<bool, int64_t> Array::getInt(int idx) const {
|
||||
toml_datum_t p = toml_int_at(m_array, idx);
|
||||
return {p.ok, p.u.i};
|
||||
}
|
||||
|
||||
pair<bool, double> Array::getDouble(int idx) const {
|
||||
toml_datum_t p = toml_double_at(m_array, idx);
|
||||
return {p.ok, p.u.d};
|
||||
}
|
||||
|
||||
pair<bool, Timestamp> Array::getTimestamp(int idx) const {
|
||||
Timestamp ret;
|
||||
toml_datum_t p = toml_timestamp_at(m_array, idx);
|
||||
if (p.ok) {
|
||||
toml_timestamp_t &ts = *p.u.ts;
|
||||
ret.year = (ts.year ? *ts.year : -1);
|
||||
ret.month = (ts.month ? *ts.month : -1);
|
||||
ret.day = (ts.day ? *ts.day : -1);
|
||||
ret.hour = (ts.hour ? *ts.hour : -1);
|
||||
ret.second = (ts.second ? *ts.second : -1);
|
||||
ret.millisec = (ts.millisec ? *ts.millisec : -1);
|
||||
ret.z = ts.z ? string(ts.z) : "";
|
||||
toml_myfree(p.u.ts);
|
||||
}
|
||||
return {p.ok, ret};
|
||||
}
|
||||
|
||||
std::unique_ptr<Array> Array::getArray(int idx) const {
|
||||
toml_array_t *a = toml_array_at(m_array, idx);
|
||||
if (!a)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<Array>(a, m_backing);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<Table> Array::getTable(int idx) const {
|
||||
toml_table_t *t = toml_table_at(m_array, idx);
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<Table>(t, m_backing);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<Array>> Array::getArrayVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<Array>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_array_t *a = toml_array_at(m_array, i);
|
||||
if (!a)
|
||||
return 0;
|
||||
|
||||
ret->push_back(Array(a, m_backing));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<Table>> Array::getTableVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<Table>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_table_t *t = toml_table_at(m_array, i);
|
||||
if (!t)
|
||||
return 0;
|
||||
|
||||
ret->push_back(Table(t, m_backing));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<string>> Array::getStringVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<string>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_datum_t p = toml_string_at(m_array, i);
|
||||
if (!p.ok)
|
||||
return 0;
|
||||
ret->push_back(p.u.s);
|
||||
toml_myfree(p.u.s);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<bool>> Array::getBoolVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<bool>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_datum_t p = toml_bool_at(m_array, i);
|
||||
if (!p.ok)
|
||||
return 0;
|
||||
ret->push_back(!!p.u.b);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<int64_t>> Array::getIntVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<int64_t>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_datum_t p = toml_int_at(m_array, i);
|
||||
if (!p.ok)
|
||||
return 0;
|
||||
ret->push_back(p.u.i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<Timestamp>> Array::getTimestampVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<Timestamp>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_datum_t p = toml_timestamp_at(m_array, i);
|
||||
if (!p.ok)
|
||||
return 0;
|
||||
|
||||
toml_timestamp_t &ts = *p.u.ts;
|
||||
Timestamp v;
|
||||
v.year = (ts.year ? *ts.year : -1);
|
||||
v.month = (ts.month ? *ts.month : -1);
|
||||
v.day = (ts.day ? *ts.day : -1);
|
||||
v.hour = (ts.hour ? *ts.hour : -1);
|
||||
v.second = (ts.second ? *ts.second : -1);
|
||||
v.millisec = (ts.millisec ? *ts.millisec : -1);
|
||||
v.z = ts.z ? string(ts.z) : "";
|
||||
toml_myfree(p.u.ts);
|
||||
|
||||
ret->push_back(v);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<vector<double>> Array::getDoubleVector() const {
|
||||
int top = toml_array_nelem(m_array);
|
||||
if (top < 0)
|
||||
return 0;
|
||||
|
||||
auto ret = std::make_unique<vector<double>>();
|
||||
ret->reserve(top);
|
||||
for (int i = 0; i < top; i++) {
|
||||
toml_datum_t p = toml_double_at(m_array, i);
|
||||
if (!p.ok)
|
||||
return 0;
|
||||
ret->push_back(p.u.d);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int toml::Array::size() const { return toml_array_nelem(m_array); }
|
||||
|
||||
toml::Result toml::parse(const string &conf) {
|
||||
toml::Result ret;
|
||||
char errbuf[200];
|
||||
auto backing = std::make_shared<Backing>(conf);
|
||||
|
||||
toml_set_memutil(toml_mymalloc, toml_myfree);
|
||||
toml_table_t *t = toml_parse(backing->ptr, errbuf, sizeof(errbuf));
|
||||
if (t) {
|
||||
ret.table = std::make_shared<Table>(t, backing);
|
||||
backing->root = t;
|
||||
} else {
|
||||
ret.errmsg = (*errbuf) ? string(errbuf) : "unknown error";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
toml::Result toml::parseFile(const string &path) {
|
||||
toml::Result ret;
|
||||
std::ifstream stream(path);
|
||||
if (!stream) {
|
||||
ret.errmsg = strerror(errno);
|
||||
return ret;
|
||||
}
|
||||
string conf(std::istreambuf_iterator<char>{stream}, {});
|
||||
return toml::parse(conf);
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 CK Tan
|
||||
https://github.com/cktan/tomlcpp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef TOML_HPP
|
||||
#define TOML_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
struct toml_table_t;
|
||||
struct toml_array_t;
|
||||
|
||||
namespace toml {
|
||||
|
||||
struct Backing;
|
||||
class Array;
|
||||
class Table;
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
/* A Timestamp value */
|
||||
struct Timestamp {
|
||||
// -1 means it is not valid
|
||||
int year = -1;
|
||||
int month = -1;
|
||||
int day = -1;
|
||||
int hour = -1;
|
||||
int minute = -1;
|
||||
int second = -1;
|
||||
int millisec = -1;
|
||||
string z; // "" if no timezone
|
||||
};
|
||||
|
||||
/* A table in toml. You can extract value/table/array using a key. */
|
||||
class Table {
|
||||
public:
|
||||
vector<string> keys() const;
|
||||
|
||||
// get content
|
||||
pair<bool, string> getString(const string &key) const;
|
||||
pair<bool, bool> getBool(const string &key) const;
|
||||
pair<bool, int64_t> getInt(const string &key) const;
|
||||
pair<bool, double> getDouble(const string &key) const;
|
||||
pair<bool, Timestamp> getTimestamp(const string &key) const;
|
||||
std::unique_ptr<Table> getTable(const string &key) const;
|
||||
std::unique_ptr<Array> getArray(const string &key) const;
|
||||
|
||||
// internal
|
||||
Table(toml_table_t *t, std::shared_ptr<Backing> backing)
|
||||
: m_table(t), m_backing(backing) {}
|
||||
|
||||
private:
|
||||
toml_table_t *const m_table = 0;
|
||||
std::shared_ptr<Backing> m_backing;
|
||||
|
||||
Table() = delete;
|
||||
};
|
||||
|
||||
/* An array in toml. You can extract value/table/array using an index. */
|
||||
class Array {
|
||||
public:
|
||||
// Content kind
|
||||
// t:table, a:array, v:value, m:mixed
|
||||
char kind() const;
|
||||
|
||||
// For Value kind only, check the type of the value
|
||||
// i:int, d:double, b:bool, s:string, t:time, D: date, T:timestamp, m:mixed,
|
||||
// 0:unknown
|
||||
char type() const;
|
||||
|
||||
// Return the #elements in the array
|
||||
int size() const;
|
||||
|
||||
// You may have to use these methods for arrays with mixed values
|
||||
pair<bool, string> getString(int idx) const;
|
||||
pair<bool, bool> getBool(int idx) const;
|
||||
pair<bool, int64_t> getInt(int idx) const;
|
||||
pair<bool, double> getDouble(int idx) const;
|
||||
pair<bool, Timestamp> getTimestamp(int idx) const;
|
||||
|
||||
std::unique_ptr<Table> getTable(int idx) const;
|
||||
std::unique_ptr<Array> getArray(int idx) const;
|
||||
|
||||
// Use these methods only if you know the array has no mixed values!
|
||||
// For values, some conveniet methods to obtain vector
|
||||
std::unique_ptr<vector<string>> getStringVector() const;
|
||||
std::unique_ptr<vector<bool>> getBoolVector() const;
|
||||
std::unique_ptr<vector<int64_t>> getIntVector() const;
|
||||
std::unique_ptr<vector<double>> getDoubleVector() const;
|
||||
std::unique_ptr<vector<Timestamp>> getTimestampVector() const;
|
||||
|
||||
// Obtain vectors of table or array
|
||||
std::unique_ptr<vector<Table>> getTableVector() const;
|
||||
std::unique_ptr<vector<Array>> getArrayVector() const;
|
||||
|
||||
// internal
|
||||
Array(toml_array_t *a, std::shared_ptr<Backing> backing)
|
||||
: m_array(a), m_backing(backing) {}
|
||||
|
||||
private:
|
||||
toml_array_t *const m_array = 0;
|
||||
std::shared_ptr<Backing> m_backing;
|
||||
|
||||
Array() = delete;
|
||||
};
|
||||
|
||||
/* The main function: Parse */
|
||||
struct Result {
|
||||
std::shared_ptr<Table> table;
|
||||
string errmsg;
|
||||
};
|
||||
|
||||
Result parse(const string &conf);
|
||||
Result parseFile(const string &path);
|
||||
}; // namespace toml
|
||||
|
||||
#endif /* TOML_HPP */
|
||||
Binary file not shown.
@@ -0,0 +1,49 @@
|
||||
#include "tomlcpp.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
|
||||
void fatal(std::string msg) {
|
||||
cerr << "FATAL: " << msg << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 1. parse file
|
||||
auto res = toml::parseFile("sample.toml");
|
||||
if (!res.table) {
|
||||
fatal("cannot parse file: " + res.errmsg);
|
||||
}
|
||||
|
||||
// 2. get top level table
|
||||
auto server = res.table->getTable("server");
|
||||
if (!server) {
|
||||
fatal("missing [server]");
|
||||
}
|
||||
|
||||
// 3. extract values from the top level table
|
||||
auto [ok, host] = server->getString("host");
|
||||
if (!ok) {
|
||||
fatal("missing or bad host entry");
|
||||
}
|
||||
|
||||
auto portArray = server->getArray("port");
|
||||
if (!portArray) {
|
||||
fatal("missing 'port' array");
|
||||
}
|
||||
|
||||
// 4. examine the values
|
||||
cout << "host: " << host << "\n";
|
||||
cout << "port: ";
|
||||
for (int i = 0;; i++) {
|
||||
auto p = portArray->getInt(i);
|
||||
if (!p.first)
|
||||
break;
|
||||
|
||||
cout << p.second << " ";
|
||||
}
|
||||
cout << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user