| 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 |