io: slurp should default to providing bytes, not chars

std::byte has less potential for abuse. if you want an array of chars
you should ask for it.
This commit is contained in:
Danny Robson 2017-09-12 14:18:34 +10:00
parent 4050754ab4
commit c1aa0f7a3d
3 changed files with 35 additions and 11 deletions

View File

@ -60,7 +60,7 @@ addr2line (const void *addr)
); );
// inefficient to copy from vector to string, but it's not a high priority path // inefficient to copy from vector to string, but it's not a high priority path
auto data = util::slurp (stream.get ()); auto data = util::slurp<char> (stream.get ());
return std::string (data.cbegin (), data.cend ()); return std::string (data.cbegin (), data.cend ());
#else #else

34
io.cpp
View File

@ -32,10 +32,15 @@
using namespace util; using namespace util;
//---------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////
std::vector<char> template <typename T>
std::vector<T>
util::slurp (const std::experimental::filesystem::path &path) util::slurp (const std::experimental::filesystem::path &path)
{ {
static_assert (
sizeof (T) == 1,
"slurp is designed for grabbing bytes, not complex structures"
);
posix::fd out (path, O_RDONLY | O_BINARY); posix::fd out (path, O_RDONLY | O_BINARY);
// Calculate the total file size // Calculate the total file size
@ -47,11 +52,11 @@ util::slurp (const std::experimental::filesystem::path &path)
throw errno_error (); throw errno_error ();
// Allocate a buffer, and keep reading until it's full. // Allocate a buffer, and keep reading until it's full.
std::vector<char> buffer (size); std::vector<T> buffer (size);
CHECK_GE (size, 0); CHECK_GE (size, 0);
size_t remaining = (size_t)size; size_t remaining = (size_t)size;
char *cursor = buffer.data (); T *cursor = buffer.data ();
while (remaining) { while (remaining) {
ssize_t consumed = ::read (out, cursor, remaining); ssize_t consumed = ::read (out, cursor, remaining);
@ -69,9 +74,20 @@ util::slurp (const std::experimental::filesystem::path &path)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::vector<char> template std::vector<char> util::slurp (const std::experimental::filesystem::path&);
template std::vector<std::byte> util::slurp (const std::experimental::filesystem::path&);
///////////////////////////////////////////////////////////////////////////////
template <typename T>
std::vector<T>
util::slurp (FILE *stream) util::slurp (FILE *stream)
{ {
static_assert (
sizeof (T) == 1,
"slurp is designed for grabbing bytes, not complex structures"
);
// find how much data is in this file // find how much data is in this file
const int desc = fileno (stream); const int desc = fileno (stream);
if (desc < 0) if (desc < 0)
@ -81,7 +97,7 @@ util::slurp (FILE *stream)
if (fstat (desc, &meta) < 0) if (fstat (desc, &meta) < 0)
errno_error::throw_code (); errno_error::throw_code ();
std::vector<char> buf; std::vector<T> buf;
// we think we know the size, so try to do a simple read // we think we know the size, so try to do a simple read
if (meta.st_size) { if (meta.st_size) {
@ -113,8 +129,12 @@ util::slurp (FILE *stream)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template std::vector<char> util::slurp (FILE*);
template std::vector<std::byte> util::slurp (FILE*);
///////////////////////////////////////////////////////////////////////////////
void void
util::write (const posix::fd &out, util::write (const posix::fd &out,
const void *restrict data, const void *restrict data,

10
io.hpp
View File

@ -20,8 +20,9 @@
#include "platform.hpp" #include "platform.hpp"
#include "posix/fd.hpp" #include "posix/fd.hpp"
#include <cstdio> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstdio>
#include <experimental/filesystem> #include <experimental/filesystem>
#include <vector> #include <vector>
#include <streambuf> #include <streambuf>
@ -35,8 +36,11 @@
namespace util { namespace util {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/// Reads an entire file into memory. /// Reads an entire file into memory.
std::vector<char> slurp (const std::experimental::filesystem::path&); template <typename T = std::byte>
std::vector<char> slurp (FILE *); std::vector<T> slurp (const std::experimental::filesystem::path&);
template <typename T = std::byte>
std::vector<T> slurp (FILE *);
//------------------------------------------------------------------------- //-------------------------------------------------------------------------