/// /// \file Buffer.h /// \author kyle /// \date 2023-10-10 /// \brief A buffer is the basic document type. /// #ifndef KEPP_FRAME_H #define KEPP_FRAME_H #include #include #include "Defs.h" #include "File.h" #include "Cursor.h" typedef std::vector> BufferContents; /// A Buffer is the atom of text editing. It represents a single document, /// whether a memory-only buffer or a file-backed buffer. /// /// \details /// /// There are currently two main types of Buffers: file-backed and virtual. /// A virtual buffer describes any buffer that isn't backed by a file. /// /// A virtual buffer can be promoted to a file frame, but a file buffer /// cannot be demoted to a virtual buffer. class Buffer { public: enum class FileStatus : uint8_t { /// The file operation succeeded correctly. FileStatusOK = 0, /// There was an error, but it wasn't handled correctly. /// This is mostly for debugging purposes, and shouldn't /// be seen by users. /// /// \detail This is set at the beginning of failable /// operations, and indicates that the right /// status wasn't set correctly. FileStatusUnspecifiedError = 1, /// The file can't be written to because it is marked /// read-only. This refers to a buffer being marked as /// read-only, not to whether the underlying file is /// actually read-only. FileStatusReadOnly = 2, /// There was an I/O error trying to write to the file. FileStatusIOFailed = 3, /// The Buffer couldn't be flushed because it is a virtual /// buffer. If the user explicitly tried to save the buffer, /// they should be prompted for a path. FileStatusVirtual = 4, /// The underlying file doesn't have the right permissions; /// for example, it's not writeable if the user is trying to /// write the file. FileStatusInvalidPermissions = 5, /// The underlying file doesn't exist. FileStatusNonExistent = 6, }; static std::string FileStatusToString(FileStatus status); static bool StatusOK(FileStatus status); /// The constructor with no arguments generates a new anonymous /// buffer. Buffer(); /// A single constructor generates a virtual buffer. Buffer(std::string fName); /// Instantiate a buffer from a filesystem path. Buffer(std::filesystem::path fPath); /// Instantiate a Buffer pointing to fPath. Buffer(std::string fName, std::string fPath); void Close(); const std::string Name(); bool IsVirtual(); Buffer::FileStatus Flush(OptString altPath); /// Refresh reads the contents of the file back into the /// buffer. /// /// \warning This does not care if the file is dirty or not - /// it WILL overwrite the contents of the buffer. /// /// \return A FileStatus indicating whether the read was successful. Buffer::FileStatus Refresh(); void Rename(std::string fName); void ChangePath(std::string newPath); Cursor Where(); void MarkDirty(); bool IsDirty(); size_t Size(); /// Does this buffer have a current, on-disk file? /// /// \return True if this is a file buffer with an extant source /// file. bool Exists(); /// PrintBufferStatus is a debug tool to capture the current /// buffer state. void PrintBufferStatus(std::ostream &os); private: void clearContents(); Cursor cursor; bool dirty; std::string name; OptString path; OptFile file; BufferContents contents; FileStatus status; }; #endif // KEPP_FRAME_H