11 #if defined(__unix__) || defined(__APPLE__)
14 # include <sys/mman.h>
22 explicit raii_fd(
int file) noexcept : _file(file) {}
24 raii_fd(
const raii_fd&) =
delete;
25 raii_fd& operator=(
const raii_fd&) =
delete;
33 operator int() const noexcept
60 constexpr std::size_t small_file_size = std::size_t(4) * 1024;
61 constexpr std::size_t medium_file_size = std::size_t(32) * 1024;
66 raii_fd fd(::
open(path, O_RDONLY));
68 return get_file_error();
70 auto off = ::lseek(fd, 0, SEEK_END);
71 if (off ==
static_cast<::off_t
>(-1))
73 auto size =
static_cast<std::size_t
>(off);
75 if (
size <= small_file_size)
77 if (::lseek(fd, 0, SEEK_SET) != 0)
80 char buffer[small_file_size];
86 else if (
size <= medium_file_size)
88 if (::lseek(fd, 0, SEEK_SET) != 0)
92 if (::read(fd, builder.data(), builder.size()) !=
static_cast<::ssize_t
>(
size))
95 cb(user_data, builder.data(), builder.size());
99 auto memory = ::mmap(
nullptr,
size, PROT_READ, MAP_PRIVATE, fd, 0);
100 if (memory == MAP_FAILED)
103 cb(user_data,
reinterpret_cast<const char*
>(memory),
size);
105 ::munmap(memory,
size);
111 #else // portable read_file() using C I/O
118 explicit raii_file(std::FILE* file) noexcept : _file(file) {}
120 raii_file(
const raii_file&) =
delete;
121 raii_file& operator=(
const raii_file&) =
delete;
123 ~raii_file() noexcept
129 operator std::FILE*()
const noexcept
160 raii_file file(std::fopen(path,
"rb"));
162 return get_file_error();
165 if (std::fseek(file, 0, SEEK_END) != 0)
168 auto size = std::ftell(file);
172 if (std::fseek(file, 0, SEEK_SET) != 0)
177 if (std::fread(builder.data(),
sizeof(
char), builder.size(), file) != builder.size())
179 LEXY_ASSERT(std::fgetc(file) == EOF,
"we haven't read everything?!");
183 cb(user_data, builder.data(), builder.size());
184 return file_error::_success;
198 const auto buffer_size = builder.
write_size();
203 const auto read = std::fread(builder.
write_data(),
sizeof(
char), buffer_size, stdin);
207 if (read < buffer_size)
209 if (std::ferror(stdin) != 0)
214 LEXY_ASSERT(std::feof(stdin),
"why did fread() not read enough?");
226 return file_error::_success;