io: add an fd
overload for slurp
This commit is contained in:
parent
0de176591d
commit
f21369c15a
51
io.cpp
51
io.cpp
@ -122,6 +122,57 @@ template std::vector<char> cruft::slurp (FILE*);
|
||||
template std::vector<std::byte> cruft::slurp (FILE*);
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ValueT>
|
||||
std::vector<ValueT>
|
||||
cruft::slurp (posix::fd &src)
|
||||
{
|
||||
struct stat meta;
|
||||
posix::error::try_value (fstat (src, &meta));
|
||||
|
||||
std::vector<ValueT> buf;
|
||||
|
||||
// we think we know the size, so try to do a simple read
|
||||
if (meta.st_size) {
|
||||
buf.resize (meta.st_size);
|
||||
|
||||
// read as much as possible, then resize to the actual length
|
||||
auto const res = cruft::posix::error::try_call (
|
||||
::read, src.native (), buf.data (), meta.st_size
|
||||
);
|
||||
buf.resize (res);
|
||||
}
|
||||
|
||||
// try reading small chunks until we've hit the end. important for
|
||||
// handling pipe streams (like from popen) which report a zero size.
|
||||
constexpr size_t CHUNK_SIZE = 1024;
|
||||
|
||||
while (1) {
|
||||
// Make room for some more data
|
||||
auto const oldsize = buf.size ();
|
||||
buf.resize (oldsize + CHUNK_SIZE);
|
||||
|
||||
// Append the data
|
||||
auto const res = cruft::posix::error::try_call (
|
||||
::read, src.native (), buf.data () + oldsize, CHUNK_SIZE
|
||||
);
|
||||
buf.resize (oldsize + res);
|
||||
|
||||
// Bail if we've hit EOF
|
||||
if (res == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template std::vector<char> cruft::slurp (posix::fd&);
|
||||
template std::vector<std::byte> cruft::slurp (posix::fd&);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
indenter::overflow (int ch) {
|
||||
|
26
io.hpp
26
io.hpp
@ -26,14 +26,32 @@
|
||||
#endif
|
||||
|
||||
namespace cruft {
|
||||
//-------------------------------------------------------------------------
|
||||
/// Reads an entire file into memory.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// Reads an entire file into memory in one operation.
|
||||
template <typename T = std::byte>
|
||||
std::vector<T> slurp (const std::experimental::filesystem::path&);
|
||||
std::vector<T>
|
||||
slurp (const std::experimental::filesystem::path&);
|
||||
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
/// Read the entire contents of a FILE object into memory.
|
||||
///
|
||||
/// * This may trigger an arbitrary number of read calls.
|
||||
/// * This may block indefinitely depending on the contents of the fd.
|
||||
template <typename T = std::byte>
|
||||
std::vector<T> slurp (FILE *);
|
||||
std::vector<T>
|
||||
slurp (FILE *);
|
||||
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
/// Read the entire contents of a file-descriptor into memory in one
|
||||
/// operation.
|
||||
///
|
||||
/// * This may trigger an arbitrary number of read calls.
|
||||
/// * This may block indefinitely depending on the contents of the fd.
|
||||
template <typename T = std::byte>
|
||||
std::vector<T>
|
||||
slurp (cruft::posix::fd&);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user