InFile class
This commit is contained in:
parent
af30c9e597
commit
134f2aa3fb
3 changed files with 249 additions and 0 deletions
|
@ -0,0 +1,4 @@
|
|||
# SConscript
|
||||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
Library('erw', ['src/File.cc'])
|
105
lib/core/include/core/File.hh
Normal file
105
lib/core/include/core/File.hh
Normal 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
140
lib/core/src/File.cc
Normal 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 */
|
Loading…
Add table
Add a link
Reference in a new issue