Working on backing files.
Also started a sketches project to illustrate quick ideas.
This commit is contained in:
124
Buffer.cc
124
Buffer.cc
@@ -20,12 +20,12 @@
|
||||
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
/// SOFTWARE.
|
||||
///
|
||||
/// @\section DESCRIPTION
|
||||
|
||||
|
||||
#include <optional>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
|
||||
#include "Buffer.h"
|
||||
|
||||
@@ -34,9 +34,9 @@ static std::string
|
||||
anonymousName()
|
||||
{
|
||||
std::uniform_int_distribution<> dist(1000, 9999);
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 rng(randomDevice());
|
||||
std::stringstream ss;
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 rng(randomDevice());
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "Buffer<" << dist(rng) << ">";
|
||||
return ss.str();
|
||||
@@ -44,35 +44,137 @@ anonymousName()
|
||||
|
||||
|
||||
Buffer::Buffer()
|
||||
: name(anonymousName())
|
||||
: dirty(false), name(anonymousName())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer(std::string fName)
|
||||
: name(std::move(fName))
|
||||
: dirty(false), name(std::move(fName))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer(std::string fName, std::string fPath)
|
||||
: name(std::move(fName)), path(std::move(fPath))
|
||||
: dirty(false), name(std::move(fName)), path(fPath)
|
||||
{
|
||||
if (this->path) {
|
||||
this->file = OptFile(File(this->path.value()));
|
||||
this->file = OptFile (File(fPath));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int Buffer::Flush(OptString altPath)
|
||||
Buffer::FileStatus
|
||||
Buffer::Flush(OptString altPath)
|
||||
{
|
||||
return altPath ? 0 : 1;
|
||||
OptOutFileStream handle = std::nullopt;
|
||||
|
||||
if (altPath) {
|
||||
auto altFile = File(altPath.value());
|
||||
handle = altFile.Flush();
|
||||
} else if (this->file) {
|
||||
handle = this->file.value().Flush();
|
||||
} else {
|
||||
// At this point, we have no alternate path to write out
|
||||
// and this Buffer isn't file-backed. From this point
|
||||
// forward, we can operate under the assumption that
|
||||
// `this->file` is a valid file.
|
||||
return Buffer::FileStatus::FileStatusVirtual;
|
||||
}
|
||||
|
||||
auto realFile = this->file.value();
|
||||
if (!handle) {
|
||||
if (realFile.IsReadOnly()) {
|
||||
return Buffer::FileStatus::FileStatusReadOnly;
|
||||
}
|
||||
|
||||
if (!realFile.IsWriteable()) {
|
||||
return Buffer::FileStatus::FileStatusInvalidPermissions;
|
||||
}
|
||||
|
||||
return Buffer::FileStatus::FileStatusIOFailed;
|
||||
}
|
||||
|
||||
/// At this point, we know we're working with a valid file handle.
|
||||
auto realHandle = handle.value();
|
||||
if (!realHandle->good()) {
|
||||
return Buffer::FileStatus::FileStatusIOFailed;
|
||||
}
|
||||
|
||||
for (auto line : this->contents) {
|
||||
std::copy(line.begin(), line.end(),
|
||||
std::ostream_iterator<uint8_t>(*realHandle, ""));
|
||||
}
|
||||
|
||||
realHandle->flush();
|
||||
realHandle->close();
|
||||
delete realHandle;
|
||||
this->dirty = false;
|
||||
return Buffer::FileStatus::FileStatusOK;
|
||||
}
|
||||
|
||||
|
||||
void Buffer::ChangePath(std::string newPath)
|
||||
Buffer::FileStatus
|
||||
Buffer::Refresh()
|
||||
{
|
||||
if (this->IsVirtual()) {
|
||||
return Buffer::FileStatus::FileStatusVirtual;
|
||||
}
|
||||
|
||||
auto realFile = this->file.value();
|
||||
auto handle = realFile.Refresh();
|
||||
if (!handle) {
|
||||
return FileStatus::FileStatusNonExistent;
|
||||
}
|
||||
|
||||
auto realHandle = handle.value();
|
||||
this->clearContents();
|
||||
this->dirty = false; // clean slate, kiddo
|
||||
|
||||
/// \todo Moral quandary: if the file disappears from disk, we
|
||||
/// probably want to know that, but maybe clearing the
|
||||
/// contents first isn't the right move.
|
||||
if (!realHandle->good()) {
|
||||
delete realHandle;
|
||||
return FileStatus::FileStatusIOFailed;
|
||||
}
|
||||
|
||||
size_t currentLine = 0;
|
||||
|
||||
while (realHandle->good()) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Buffer::ChangePath(std::string newPath)
|
||||
{
|
||||
this->path = OptString(std::move(newPath));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Buffer::clearContents()
|
||||
{
|
||||
for (auto & line : this->contents) {
|
||||
line.clear();
|
||||
}
|
||||
|
||||
this->contents.clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Buffer::MarkDirty()
|
||||
{
|
||||
if (this->dirty) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->dirty = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user