blob: 63110d2d2492f698129a7cc961c86680c3d83282 [file] [log] [blame]
Kun Yi9125e632019-01-09 13:52:06 -08001#pragma once
2
3#include "sys.hpp"
4
5#include <fcntl.h>
6#include <unistd.h>
7
8#include <string>
9
10namespace 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 */
17class 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 Yic83d2fa2019-04-03 18:40:19 -070037 * 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 Yi9125e632019-01-09 13:52:06 -080039 * @throws std::system_error if read operation cannot be completed
Kun Yic83d2fa2019-04-03 18:40:19 -070040 * std::bad_alloc if cannot construct string with 'count' size
Kun Yi9125e632019-01-09 13:52:06 -080041 */
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
63class 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