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