blob: 63110d2d2492f698129a7cc961c86680c3d83282 [file] [log] [blame]
#pragma once
#include "sys.hpp"
#include <fcntl.h>
#include <unistd.h>
#include <string>
namespace binstore
{
/**
* @brief Represents a file that supports read/write semantics
* TODO: leverage stdplus's support for smart file descriptors when it's ready.
*/
class SysFile
{
public:
virtual ~SysFile() = default;
/**
* @brief Reads content at pos to char* buffer
* @param pos The byte pos into the file to read from
* @param count How many bytes to read
* @param buf Output data
* @returns The size of data read
* @throws std::system_error if read operation cannot be completed
*/
virtual size_t readToBuf(size_t pos, size_t count, char* buf) const = 0;
/**
* @brief Reads content at pos
* @param pos The byte pos into the file to read from
* @param count How many bytes to read
* @returns The data read in a vector, whose size might be smaller than
* count if there is not enough to read. Might be empty if the
* count specified is too large to even fit in a std::string.
* @throws std::system_error if read operation cannot be completed
* std::bad_alloc if cannot construct string with 'count' size
*/
virtual std::string readAsStr(size_t pos, size_t count) const = 0;
/**
* @brief Reads all the content in file after pos
* @param pos The byte pos to read from
* @returns The data read in a vector, whose size might be smaller than
* count if there is not enough to read.
* @throws std::system_error if read operation cannot be completed
*/
virtual std::string readRemainingAsStr(size_t pos) const = 0;
/**
* @brief Writes all of data into file at pos
* @param pos The byte pos to write
* @returns void
* @throws std::system_error if write operation cannot be completed or
* not all of the bytes can be written
*/
virtual void writeStr(const std::string& data, size_t pos) = 0;
};
class SysFileImpl : public SysFile
{
public:
/**
* @brief Constructs sysFile specified by path and offset
* @param path The file path
* @param offset The byte offset relatively. Reading a sysfile at position 0
* actually reads underlying file at 'offset'
* @param sys Syscall operation interface
*/
explicit SysFileImpl(const std::string& path, size_t offset = 0,
const internal::Sys* sys = &internal::sys_impl);
~SysFileImpl();
SysFileImpl() = delete;
SysFileImpl(const SysFileImpl&) = delete;
SysFileImpl& operator=(SysFileImpl) = delete;
size_t readToBuf(size_t pos, size_t count, char* buf) const override;
std::string readAsStr(size_t pos, size_t count) const override;
std::string readRemainingAsStr(size_t pos) const override;
void writeStr(const std::string& data, size_t pos) override;
private:
int fd_;
size_t offset_;
void lseek(size_t pos) const;
const internal::Sys* sys;
};
} // namespace binstore