diff options
Diffstat (limited to 'tools/minicargo/toml.h')
-rw-r--r-- | tools/minicargo/toml.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/tools/minicargo/toml.h b/tools/minicargo/toml.h new file mode 100644 index 00000000..1c8f90d5 --- /dev/null +++ b/tools/minicargo/toml.h @@ -0,0 +1,127 @@ +#pragma once + +#include <fstream> +#include <vector> +#include <unordered_map> + +class TomlFileIter; +struct TomlKeyValue; + +class TomlFile +{ + /// Input file stream + ::std::ifstream m_if; + + /// Name of the current `[]` block + ::std::vector<::std::string> m_current_block; + + /// Path suffix of the current composite (none if empty) + ::std::vector<::std::string> m_current_composite; + + /// Index of the next array field (if zero, not parsing an array) + unsigned int m_next_array_index; + + /// Next indexes if top-level defined arrays (e.g. `[[foo]]`) + ::std::unordered_map<::std::string,unsigned> m_array_counts; + +public: + TomlFile(const ::std::string& filename); + + TomlFileIter begin(); + TomlFileIter end(); + + TomlKeyValue get_next_value(); +}; + +struct TomlValue +{ + enum class Type + { + Boolean, + String, + Integer, + List, + }; + struct TypeError: + public ::std::exception + { + Type have; + Type exp; + + TypeError(Type h, Type e): + have(h), + exp(e) + { + } + + const char* what() const override { + return "toml type error"; + } + }; + + Type m_type; + uint64_t m_int_value; + ::std::string m_str_value; + ::std::vector<TomlValue> m_sub_values; + + TomlValue(): + m_type(Type::String) + { + } + TomlValue(::std::string s): + m_type( Type::String ), + m_str_value(::std::move(s)) + { + } + TomlValue(bool v) : + m_type(Type::Boolean), + m_int_value(v ? 1 : 0) + { + } + + const ::std::string& as_string() const { + if( m_type != Type::String ) { + throw TypeError { m_type, Type::String }; + } + return m_str_value; + } + bool as_bool() const { + if(m_type != Type::Boolean) { + throw TypeError { m_type, Type::Boolean }; + } + return m_int_value != 0; + } +}; + +struct TomlKeyValue +{ + ::std::vector<::std::string> path; + TomlValue value; +}; + +class TomlFileIter +{ + friend class TomlFile; + TomlFile& m_reader; + TomlKeyValue m_cur_value; + + TomlFileIter(TomlFile& tf): + m_reader(tf) + { + + } + +public: + TomlKeyValue operator*() const + { + return m_cur_value; + } + void operator++() + { + m_cur_value = m_reader.get_next_value(); + } + bool operator!=(const TomlFileIter& x) const + { + return m_cur_value.path != x.m_cur_value.path; + } +}; |