From 060e2ebac81a1cfa4d72dddfcb3fb07845713a95 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 25 May 2011 23:02:39 +1000 Subject: [PATCH] added slurp routine and comments --- io.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++----- io.hpp | 23 ++++++++++------------- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/io.cpp b/io.cpp index 62125508..e416d36b 100644 --- a/io.cpp +++ b/io.cpp @@ -13,25 +13,62 @@ 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 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): - m_fd (_fd) + fd (_fd) { - if (m_fd < 0) + if (fd < 0) throw invalid_argument ("invalid file descriptor"); } fd_ref::~fd_ref () { - check (m_fd >= 0); - close (m_fd); + check (fd >= 0); + close (fd); } fd_ref::operator int (void) const - { return m_fd; } + { return fd; } +//---------------------------------------------------------------------------- mapped_file::mapped_file (const char *_path): m_fd (open (_path, O_RDONLY)) { load_fd (); } diff --git a/io.hpp b/io.hpp index d6cc3882..72d716e0 100644 --- a/io.hpp +++ b/io.hpp @@ -20,12 +20,14 @@ #ifndef __UTIL_IO_HPP #define __UTIL_IO_HPP +#include "annotations.hpp" + #include #include #include #include - +/// Specifies bitwise combinations of IO access rights. enum access_t { ACCESS_READ = 1 << 0, ACCESS_WRITE = 1 << 1, @@ -33,21 +35,15 @@ enum access_t { }; -struct FILE_destructor { - void operator ()(FILE *f) { fclose (f); } -}; - -typedef std::unique_ptr FILE_ref; - - -struct fd_destructor { - void operator ()(int fd) { close (fd); } -}; +/// Reads an entire file into memory. Caller frees the result. Guarantees a +/// null trailing byte. +uint8_t * +slurp (boost::filesystem::path&) mustuse; +/// A simple RAII wrapper for file descriptors struct fd_ref { public: - int m_fd; - + int fd; fd_ref (int _fd); ~fd_ref (); @@ -56,6 +52,7 @@ struct fd_ref { }; +/// Wraps a mechanism to map a file into memory. Read only. class mapped_file { protected: fd_ref m_fd;