added slurp routine and comments

This commit is contained in:
Danny Robson 2011-05-25 23:02:39 +10:00
parent 547fdc629a
commit 060e2ebac8
2 changed files with 52 additions and 18 deletions

47
io.cpp
View File

@ -13,25 +13,62 @@
using namespace std; using namespace std;
//----------------------------------------------------------------------------
uint8_t *
slurp (boost::filesystem::path& path) {
fd_ref fd(open (path.c_str(), O_RDONLY | O_CLOEXEC));
// Calculate the total file size
off_t size = lseek (fd, 0, SEEK_END);
if (size == (off_t)-1)
throw errno_error();
if (lseek (fd, 0, SEEK_SET) == (off_t)-1)
throw errno_error ();
// Allocate a buffer, and keep reading until it's full. We provide a null
// padding at the tail as a 'just in case' measure for string manipulation.
unique_ptr <uint8_t[]> buffer (new uint8_t[size + 1]);
buffer.get()[size] = '\0';
check_hard (size >= 0);
size_t remaining = (size_t)size;
uint8_t *cursor = buffer.get();
while (remaining) {
ssize_t consumed = read (fd, cursor, remaining);
if (consumed == -1)
throw errno_error();
check_hard ( consumed >= 0);
check_hard ((size_t)consumed <= remaining);
remaining -= (size_t)consumed;
cursor += consumed;
}
return buffer.release();
}
//----------------------------------------------------------------------------
fd_ref::fd_ref (int _fd): fd_ref::fd_ref (int _fd):
m_fd (_fd) fd (_fd)
{ {
if (m_fd < 0) if (fd < 0)
throw invalid_argument ("invalid file descriptor"); throw invalid_argument ("invalid file descriptor");
} }
fd_ref::~fd_ref () { fd_ref::~fd_ref () {
check (m_fd >= 0); check (fd >= 0);
close (m_fd); close (fd);
} }
fd_ref::operator int (void) const fd_ref::operator int (void) const
{ return m_fd; } { return fd; }
//----------------------------------------------------------------------------
mapped_file::mapped_file (const char *_path): mapped_file::mapped_file (const char *_path):
m_fd (open (_path, O_RDONLY)) m_fd (open (_path, O_RDONLY))
{ load_fd (); } { load_fd (); }

23
io.hpp
View File

@ -20,12 +20,14 @@
#ifndef __UTIL_IO_HPP #ifndef __UTIL_IO_HPP
#define __UTIL_IO_HPP #define __UTIL_IO_HPP
#include "annotations.hpp"
#include <cstdio> #include <cstdio>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
/// Specifies bitwise combinations of IO access rights.
enum access_t { enum access_t {
ACCESS_READ = 1 << 0, ACCESS_READ = 1 << 0,
ACCESS_WRITE = 1 << 1, ACCESS_WRITE = 1 << 1,
@ -33,21 +35,15 @@ enum access_t {
}; };
struct FILE_destructor { /// Reads an entire file into memory. Caller frees the result. Guarantees a
void operator ()(FILE *f) { fclose (f); } /// null trailing byte.
}; uint8_t *
slurp (boost::filesystem::path&) mustuse;
typedef std::unique_ptr <FILE, FILE_destructor> FILE_ref;
struct fd_destructor {
void operator ()(int fd) { close (fd); }
};
/// A simple RAII wrapper for file descriptors
struct fd_ref { struct fd_ref {
public: public:
int m_fd; int fd;
fd_ref (int _fd); fd_ref (int _fd);
~fd_ref (); ~fd_ref ();
@ -56,6 +52,7 @@ struct fd_ref {
}; };
/// Wraps a mechanism to map a file into memory. Read only.
class mapped_file { class mapped_file {
protected: protected:
fd_ref m_fd; fd_ref m_fd;