InFile class

This commit is contained in:
Eryn Wells 2015-10-17 09:16:26 -07:00
parent af30c9e597
commit 134f2aa3fb
3 changed files with 249 additions and 0 deletions

View file

@ -0,0 +1,4 @@
# SConscript
# Eryn Wells <eryn@erynwells.me>
Library('erw', ['src/File.cc'])

View file

@ -0,0 +1,105 @@
/* File.hh
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
/**
* File interface.
*/
#include <bitset>
#include <fstream>
#include <memory>
#include "String.hh"
namespace erw {
namespace core {
struct File
{
enum class SeekFrom {
/** Seek from the beginning of the file. */
Begin,
/** Seek from the current file offset. */
Here,
/** Seek from the end of the file. */
End,
};
typedef std::bitset<3> Mode;
static constexpr Mode In = Mode(1);
static constexpr Mode Out = Mode(2);
static constexpr Mode Binary = Mode(4);
/** Destructor. */
virtual ~File();
/** Seek to an absolute position in the file. */
virtual File& seek(size_t pos) = 0;
/**
* Seek to an `offset` from the given anchor point in the file.
* @see SeekFrom
*/
virtual File& seek(ssize_t offset, SeekFrom from) = 0;
protected:
/** Convert a File::Mode to an iostream openmode bitset. */
virtual std::ios_base::openmode modeToIOSMode(Mode mode);
};
/** File handle for reading. */
struct InFile
: public File
{
/** Open a file at `path` for reading. */
InFile(const String& path, File::Mode mode);
/** Deleted copy constructor. File handles cannot be copied. */
InFile(const InFile& other) = delete;
/** Move `other` to this InFile. */
InFile(InFile&& other);
virtual ~InFile();
/** Move `other` to this InFile. File handles cannot be copied. */
InFile& operator=(InFile& other);
/** Read up to `count` characters into the provided `buffer`. */
InFile& read(char* buffer, ssize_t count);
/** @see File::seek */
InFile& seek(size_t pos) override;
/** @See File::seek */
InFile& seek(ssize_t pos, File::SeekFrom from) override;
private:
std::ifstream mStream;
std::ios_base::openmode modeToIOSMode(File::Mode mode) override;
};
struct OutFile
: public File
{
/** Write `count` characters from the provided `buffer` into this file. */
InFile& write(char* buffer, ssize_t count);
/** @see File::seek */
InFile& seek(size_t pos) override;
/** @See File::seek */
InFile& seek(ssize_t pos, File::SeekFrom from) override;
private:
std::ofstream stream;
};
} /* namespace core */
} /* namespace erw */

140
lib/core/src/File.cc Normal file
View file

@ -0,0 +1,140 @@
/* File.cc
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
/**
* Implementation of file handling.
*/
#include "core/File.hh"
namespace erw {
namespace core {
#pragma mark - File
File::~File()
{ }
/*
* InFile::modeToIOSMode --
*/
std::ios_base::openmode
File::modeToIOSMode(Mode mode)
{
std::ios_base::openmode openmode = 0;
if ((mode & In).any()) {
openmode |= std::ios_base::in;
}
if ((mode & Out).any()) {
openmode |= std::ios_base::out;
}
if ((mode & Binary).any()) {
openmode |= std::ios_base::binary;
}
return openmode;
}
#pragma mark - InFile
/*
* InFile::InFile --
*/
InFile::InFile(const String& path,
InFile::Mode mode)
: mStream(path, modeToIOSMode(mode))
{ }
/*
* InFile::InFile --
*/
InFile::InFile(InFile&& other)
: mStream(std::move(other.mStream))
{ }
/*
* InFile::~InFile --
*/
InFile::~InFile()
{ }
/*
* InFile::operator= --
*/
InFile&
InFile::operator=(InFile& other)
{
mStream = std::move(other.mStream);
return *this;
}
/*
* InFile::read --
*/
InFile&
InFile::read(char* buffer,
ssize_t count)
{
mStream.read(buffer, count);
return *this;
}
/*
* InFile::seek --
*/
InFile&
InFile::seek(size_t pos)
{
mStream.seekg(pos);
return *this;
}
/*
* InFile::seek --
*/
InFile&
InFile::seek(ssize_t off,
File::SeekFrom from)
{
std::ios_base::seekdir dir;
switch (from) {
case File::SeekFrom::Begin:
dir = std::ios_base::beg;
break;
case File::SeekFrom::Here:
dir = std::ios_base::cur;
break;
case File::SeekFrom::End:
dir = std::ios_base::end;
break;
}
mStream.seekg(off, dir);
return *this;
}
/*
* InFile::modeToIOSMode --
*/
std::ios_base::openmode
InFile::modeToIOSMode(File::Mode mode)
{
// Ensure In flag is always set.
if (!(mode & File::In).any()) {
mode |= File::In;
}
return File::modeToIOSMode(mode);
}
#pragma mark - OutFile
} /* namespace core */
} /* namespace erw */