Kun Yi | 9125e63 | 2019-01-09 13:52:06 -0800 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| 3 | #include "sys.hpp" |
| 4 | |
| 5 | #include <fcntl.h> |
| 6 | #include <unistd.h> |
| 7 | |
| 8 | #include <string> |
| 9 | |
| 10 | namespace binstore |
| 11 | { |
| 12 | |
| 13 | /** |
| 14 | * @brief Represents a file that supports read/write semantics |
| 15 | * TODO: leverage stdplus's support for smart file descriptors when it's ready. |
| 16 | */ |
| 17 | class SysFile |
| 18 | { |
| 19 | public: |
| 20 | virtual ~SysFile() = default; |
| 21 | |
| 22 | /** |
| 23 | * @brief Reads content at pos to char* buffer |
| 24 | * @param pos The byte pos into the file to read from |
| 25 | * @param count How many bytes to read |
| 26 | * @param buf Output data |
| 27 | * @returns The size of data read |
| 28 | * @throws std::system_error if read operation cannot be completed |
| 29 | */ |
| 30 | virtual size_t readToBuf(size_t pos, size_t count, char* buf) const = 0; |
| 31 | |
| 32 | /** |
| 33 | * @brief Reads content at pos |
| 34 | * @param pos The byte pos into the file to read from |
| 35 | * @param count How many bytes to read |
| 36 | * @returns The data read in a vector, whose size might be smaller than |
Kun Yi | c83d2fa | 2019-04-03 18:40:19 -0700 | [diff] [blame^] | 37 | * count if there is not enough to read. Might be empty if the |
| 38 | * count specified is too large to even fit in a std::string. |
Kun Yi | 9125e63 | 2019-01-09 13:52:06 -0800 | [diff] [blame] | 39 | * @throws std::system_error if read operation cannot be completed |
Kun Yi | c83d2fa | 2019-04-03 18:40:19 -0700 | [diff] [blame^] | 40 | * std::bad_alloc if cannot construct string with 'count' size |
Kun Yi | 9125e63 | 2019-01-09 13:52:06 -0800 | [diff] [blame] | 41 | */ |
| 42 | virtual std::string readAsStr(size_t pos, size_t count) const = 0; |
| 43 | |
| 44 | /** |
| 45 | * @brief Reads all the content in file after pos |
| 46 | * @param pos The byte pos to read from |
| 47 | * @returns The data read in a vector, whose size might be smaller than |
| 48 | * count if there is not enough to read. |
| 49 | * @throws std::system_error if read operation cannot be completed |
| 50 | */ |
| 51 | virtual std::string readRemainingAsStr(size_t pos) const = 0; |
| 52 | |
| 53 | /** |
| 54 | * @brief Writes all of data into file at pos |
| 55 | * @param pos The byte pos to write |
| 56 | * @returns void |
| 57 | * @throws std::system_error if write operation cannot be completed or |
| 58 | * not all of the bytes can be written |
| 59 | */ |
| 60 | virtual void writeStr(const std::string& data, size_t pos) = 0; |
| 61 | }; |
| 62 | |
| 63 | class SysFileImpl : public SysFile |
| 64 | { |
| 65 | public: |
| 66 | /** |
| 67 | * @brief Constructs sysFile specified by path and offset |
| 68 | * @param path The file path |
| 69 | * @param offset The byte offset relatively. Reading a sysfile at position 0 |
| 70 | * actually reads underlying file at 'offset' |
| 71 | * @param sys Syscall operation interface |
| 72 | */ |
| 73 | explicit SysFileImpl(const std::string& path, size_t offset = 0, |
| 74 | const internal::Sys* sys = &internal::sys_impl); |
| 75 | ~SysFileImpl(); |
| 76 | SysFileImpl() = delete; |
| 77 | SysFileImpl(const SysFileImpl&) = delete; |
| 78 | SysFileImpl& operator=(SysFileImpl) = delete; |
| 79 | |
| 80 | size_t readToBuf(size_t pos, size_t count, char* buf) const override; |
| 81 | std::string readAsStr(size_t pos, size_t count) const override; |
| 82 | std::string readRemainingAsStr(size_t pos) const override; |
| 83 | void writeStr(const std::string& data, size_t pos) override; |
| 84 | |
| 85 | private: |
| 86 | int fd_; |
| 87 | size_t offset_; |
| 88 | void lseek(size_t pos) const; |
| 89 | const internal::Sys* sys; |
| 90 | }; |
| 91 | |
| 92 | } // namespace binstore |