mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Merge pull request #193 from lukash/replace-fstream
Use C-style IO instead of ifstream for parsing
This commit is contained in:
@@ -10,6 +10,18 @@
|
||||
namespace toml
|
||||
{
|
||||
|
||||
struct file_io_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
file_io_error(int errnum, const std::string& msg, const std::string& fname)
|
||||
: std::runtime_error(msg + " \"" + fname + "\": " + std::strerror(errnum)),
|
||||
errno_(errnum)
|
||||
{}
|
||||
int get_errno() {return errno_;}
|
||||
private:
|
||||
int errno_;
|
||||
};
|
||||
|
||||
struct exception : public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
|
||||
#include "combinator.hpp"
|
||||
|
||||
|
||||
@@ -2377,27 +2377,14 @@ result<Value, std::string> parse_toml_file(location& loc)
|
||||
return ok(Value(std::move(data), file, comments));
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
template<typename Comment = TOML11_DEFAULT_COMMENT_STRATEGY,
|
||||
template<typename ...> class Table = std::unordered_map,
|
||||
template<typename ...> class Array = std::vector>
|
||||
basic_value<Comment, Table, Array>
|
||||
parse(std::istream& is, std::string fname = "unknown file")
|
||||
parse(std::vector<char>& letters, const std::string& fname)
|
||||
{
|
||||
using value_type = basic_value<Comment, Table, Array>;
|
||||
|
||||
const auto beg = is.tellg();
|
||||
is.seekg(0, std::ios::end);
|
||||
const auto end = is.tellg();
|
||||
const auto fsize = end - beg;
|
||||
is.seekg(beg);
|
||||
|
||||
// read whole file as a sequence of char
|
||||
assert(fsize >= 0);
|
||||
std::vector<char> letters(static_cast<std::size_t>(fsize));
|
||||
is.read(letters.data(), fsize);
|
||||
|
||||
// append LF.
|
||||
// Although TOML does not require LF at the EOF, to make parsing logic
|
||||
// simpler, we "normalize" the content by adding LF if it does not exist.
|
||||
@@ -2435,16 +2422,75 @@ parse(std::istream& is, std::string fname = "unknown file")
|
||||
return data.unwrap();
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
template<typename Comment = TOML11_DEFAULT_COMMENT_STRATEGY,
|
||||
template<typename ...> class Table = std::unordered_map,
|
||||
template<typename ...> class Array = std::vector>
|
||||
basic_value<Comment, Table, Array>
|
||||
parse(FILE * file, const std::string& fname)
|
||||
{
|
||||
const long beg = std::ftell(file);
|
||||
if (beg == -1l) {
|
||||
throw file_io_error(errno, "Failed to access", fname);
|
||||
}
|
||||
|
||||
int res = std::fseek(file, 0, SEEK_END);
|
||||
if (res != 0) {
|
||||
throw file_io_error(errno, "Failed to seek", fname);
|
||||
}
|
||||
|
||||
const long end = std::ftell(file);
|
||||
if (end == -1l) {
|
||||
throw file_io_error(errno, "Failed to access", fname);
|
||||
}
|
||||
|
||||
const auto fsize = end - beg;
|
||||
|
||||
res = std::fseek(file, beg, SEEK_SET);
|
||||
if (res != 0) {
|
||||
throw file_io_error(errno, "Failed to seek", fname);
|
||||
}
|
||||
|
||||
// read whole file as a sequence of char
|
||||
assert(fsize >= 0);
|
||||
std::vector<char> letters(static_cast<std::size_t>(fsize));
|
||||
std::fread(letters.data(), sizeof(char), static_cast<std::size_t>(fsize), file);
|
||||
|
||||
return detail::parse<Comment, Table, Array>(letters, fname);
|
||||
}
|
||||
|
||||
template<typename Comment = TOML11_DEFAULT_COMMENT_STRATEGY,
|
||||
template<typename ...> class Table = std::unordered_map,
|
||||
template<typename ...> class Array = std::vector>
|
||||
basic_value<Comment, Table, Array>
|
||||
parse(std::istream& is, std::string fname = "unknown file")
|
||||
{
|
||||
const auto beg = is.tellg();
|
||||
is.seekg(0, std::ios::end);
|
||||
const auto end = is.tellg();
|
||||
const auto fsize = end - beg;
|
||||
is.seekg(beg);
|
||||
|
||||
// read whole file as a sequence of char
|
||||
assert(fsize >= 0);
|
||||
std::vector<char> letters(static_cast<std::size_t>(fsize));
|
||||
is.read(letters.data(), fsize);
|
||||
|
||||
return detail::parse<Comment, Table, Array>(letters, fname);
|
||||
}
|
||||
|
||||
template<typename Comment = TOML11_DEFAULT_COMMENT_STRATEGY,
|
||||
template<typename ...> class Table = std::unordered_map,
|
||||
template<typename ...> class Array = std::vector>
|
||||
basic_value<Comment, Table, Array> parse(std::string fname)
|
||||
{
|
||||
std::ifstream ifs(fname.c_str(), std::ios_base::binary);
|
||||
std::ifstream ifs(fname, std::ios_base::binary);
|
||||
if(!ifs.good())
|
||||
{
|
||||
throw std::runtime_error("toml::parse: file open error -> " + fname);
|
||||
throw std::ios_base::failure("toml::parse: Error opening file \"" + fname + "\"");
|
||||
}
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
return parse<Comment, Table, Array>(ifs, std::move(fname));
|
||||
}
|
||||
|
||||
@@ -2471,13 +2517,7 @@ template<typename Comment = TOML11_DEFAULT_COMMENT_STRATEGY,
|
||||
template<typename ...> class Array = std::vector>
|
||||
basic_value<Comment, Table, Array> parse(const std::filesystem::path& fpath)
|
||||
{
|
||||
std::ifstream ifs(fpath, std::ios_base::binary);
|
||||
if(!ifs.good())
|
||||
{
|
||||
throw std::runtime_error("toml::parse: file open error -> " +
|
||||
fpath.string());
|
||||
}
|
||||
return parse<Comment, Table, Array>(ifs, fpath.string());
|
||||
return parse<Comment, Table, Array>(fpath.string());
|
||||
}
|
||||
#endif // TOML11_HAS_STD_FILESYSTEM
|
||||
|
||||
|
||||
Reference in New Issue
Block a user