From 860706caec6cf2ab26089d6c1f1fc12166767cd9 Mon Sep 17 00:00:00 2001 From: kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> Date: Fri, 16 Apr 2021 11:02:02 -0700 Subject: [PATCH] allow parsing toml from a QByteArray --- libraries/toml11/include/toml/parser.hpp | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/libraries/toml11/include/toml/parser.hpp b/libraries/toml11/include/toml/parser.hpp index c3df644e..3ab74209 100644 --- a/libraries/toml11/include/toml/parser.hpp +++ b/libraries/toml11/include/toml/parser.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "combinator.hpp" #include "lexer.hpp" @@ -2127,6 +2128,49 @@ parse(std::istream& is, const std::string& fname = "unknown file") return data.unwrap(); } +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value +parse(QByteArray qba, const std::string& fname = "unknown file") +{ + using value_type = basic_value; + + // convert QByteArray to vector + std::vector letters(qba.begin(), qba.end()); + + while(!letters.empty() && letters.back() == '\0') + { + letters.pop_back(); + } + assert(letters.empty() || letters.back() != '\0'); + + detail::location loc(std::move(fname), std::move(letters)); + + // skip BOM if exists. + // XXX component of BOM (like 0xEF) exceeds the representable range of + // signed char, so on some (actually, most) of the environment, these cannot + // be compared to char. However, since we are always out of luck, we need to + // check our chars are equivalent to BOM. To do this, first we need to + // convert char to unsigned char to guarantee the comparability. + if(loc.source()->size() >= 3) + { + std::array BOM; + std::memcpy(BOM.data(), loc.source()->data(), 3); + if(BOM[0] == 0xEF && BOM[1] == 0xBB && BOM[2] == 0xBF) + { + loc.advance(3); // BOM found. skip. + } + } + + const auto data = detail::parse_toml_file(loc); + if(!data) + { + throw syntax_error(data.unwrap_err(), source_location(loc)); + } + return data.unwrap(); +} + template class Table = std::unordered_map, template class Array = std::vector>