io: support piped streams in slurp
This commit is contained in:
parent
568af11a0a
commit
aa780963e0
24
io.cpp
24
io.cpp
@ -82,16 +82,34 @@ util::slurp (FILE *stream)
|
|||||||
if (fstat (desc, &meta) < 0)
|
if (fstat (desc, &meta) < 0)
|
||||||
errno_error::throw_code ();
|
errno_error::throw_code ();
|
||||||
|
|
||||||
// allocate a buffer we think is the correct size
|
|
||||||
std::vector<char> buf;
|
std::vector<char> buf;
|
||||||
|
|
||||||
|
// we think we know the size, so try to do a simple read
|
||||||
|
if (meta.st_size) {
|
||||||
buf.resize (meta.st_size);
|
buf.resize (meta.st_size);
|
||||||
|
|
||||||
// read as much as possible, then resize to the actual length
|
// read as much as possible, then resize to the actual length
|
||||||
auto res = fread (buf.data (), 1, meta.st_size, stream);
|
auto res = fread (buf.data (), 1, meta.st_size, stream);
|
||||||
if (!ferror (stream))
|
|
||||||
buf.resize (res);
|
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 = 128;
|
||||||
|
size_t cursor = buf.size ();
|
||||||
|
|
||||||
|
while (!feof (stream) && !ferror (stream)) {
|
||||||
|
auto oldsize = buf.size ();
|
||||||
|
buf.resize (oldsize + CHUNK_SIZE);
|
||||||
|
auto res = fread (buf.data () + cursor, 1, CHUNK_SIZE, stream);
|
||||||
|
|
||||||
|
if (res != CHUNK_SIZE)
|
||||||
|
buf.resize (oldsize + res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ferror (stream))
|
||||||
|
throw stream_error ();
|
||||||
|
|
||||||
CHECK (feof (stream));
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
io.hpp
8
io.hpp
@ -142,6 +142,14 @@ namespace util {
|
|||||||
private:
|
private:
|
||||||
const boost::filesystem::path m_path;
|
const boost::filesystem::path m_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class stream_error : public std::exception {
|
||||||
|
public:
|
||||||
|
virtual ~stream_error () { ; }
|
||||||
|
|
||||||
|
virtual const char* what (void) const noexcept
|
||||||
|
{ return "error on C stream"; }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN32
|
#ifdef PLATFORM_WIN32
|
||||||
|
Loading…
Reference in New Issue
Block a user