allow parsing toml from a QByteArray
This commit is contained in:
parent
42253150e4
commit
860706caec
@ -5,6 +5,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
#include "combinator.hpp"
|
#include "combinator.hpp"
|
||||||
#include "lexer.hpp"
|
#include "lexer.hpp"
|
||||||
@ -2127,6 +2128,49 @@ parse(std::istream& is, const std::string& fname = "unknown file")
|
|||||||
return data.unwrap();
|
return data.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Comment = ::toml::discard_comments,
|
||||||
|
template<typename ...> class Table = std::unordered_map,
|
||||||
|
template<typename ...> class Array = std::vector>
|
||||||
|
basic_value<Comment, Table, Array>
|
||||||
|
parse(QByteArray qba, const std::string& fname = "unknown file")
|
||||||
|
{
|
||||||
|
using value_type = basic_value<Comment, Table, Array>;
|
||||||
|
|
||||||
|
// convert QByteArray to vector<char>
|
||||||
|
std::vector<char> 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<unsigned char, 3> 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<value_type>(loc);
|
||||||
|
if(!data)
|
||||||
|
{
|
||||||
|
throw syntax_error(data.unwrap_err(), source_location(loc));
|
||||||
|
}
|
||||||
|
return data.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Comment = ::toml::discard_comments,
|
template<typename Comment = ::toml::discard_comments,
|
||||||
template<typename ...> class Table = std::unordered_map,
|
template<typename ...> class Table = std::unordered_map,
|
||||||
template<typename ...> class Array = std::vector>
|
template<typename ...> class Array = std::vector>
|
||||||
|
Loading…
Reference in New Issue
Block a user