| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title Os/Posix/File.hpp | ||
| 3 | // \brief posix implementation for Os::File, header and test definitions | ||
| 4 | // ====================================================================== | ||
| 5 | #include <Os/File.hpp> | ||
| 6 | #ifndef OS_POSIX_FILE_HPP | ||
| 7 | #define OS_POSIX_FILE_HPP | ||
| 8 | |||
| 9 | #include <sys/stat.h> | ||
| 10 | |||
| 11 | namespace Os { | ||
| 12 | namespace Posix { | ||
| 13 | namespace File { | ||
| 14 | |||
| 15 | //! FileHandle class definition for posix implementations. | ||
| 16 | //! | ||
| 17 | struct PosixFileHandle : public FileHandle { | ||
| 18 | static constexpr int INVALID_FILE_DESCRIPTOR = -1; | ||
| 19 | static constexpr int ERROR_RETURN_VALUE = -1; | ||
| 20 | |||
| 21 | //! Posix file descriptor | ||
| 22 | int m_file_descriptor = INVALID_FILE_DESCRIPTOR; | ||
| 23 | }; | ||
| 24 | |||
| 25 | //! \brief posix implementation of Os::File | ||
| 26 | //! | ||
| 27 | //! Posix implementation of `FileInterface` for use as a delegate class handling posix file operations. Posix files use | ||
| 28 | //! standard `open`, `read`, and `write` posix calls. The handle is represented as a `PosixFileHandle` which wraps a | ||
| 29 | //! single `int` type file descriptor used in those API calls. | ||
| 30 | //! | ||
| 31 | class PosixFile : public FileInterface { | ||
| 32 | public: | ||
| 33 | //! \brief constructor | ||
| 34 | //! | ||
| 35 | 946 | PosixFile() = default; | |
| 36 | |||
| 37 | //! \brief copy constructor | ||
| 38 | PosixFile(const PosixFile& other); | ||
| 39 | |||
| 40 | //! \brief assignment operator that copies the internal representation | ||
| 41 | PosixFile& operator=(const PosixFile& other); | ||
| 42 | |||
| 43 | //! \brief destructor | ||
| 44 | //! | ||
| 45 | 1892 | ~PosixFile() override = default; | |
| 46 | |||
| 47 | // ------------------------------------ | ||
| 48 | // Functions overrides | ||
| 49 | // ------------------------------------ | ||
| 50 | |||
| 51 | //! \brief open file with supplied path and mode | ||
| 52 | //! | ||
| 53 | //! Open the file passed in with the given mode. If overwrite is set to OVERWRITE, then opening files in | ||
| 54 | //! OPEN_CREATE mode will clobber existing files. Set overwrite to NO_OVERWRITE to preserve existing files. | ||
| 55 | //! The status of the open request is returned from the function call. Delegates to the chosen | ||
| 56 | //! implementation's `open` function. | ||
| 57 | //! | ||
| 58 | //! It is invalid to send `nullptr` as the path. | ||
| 59 | //! It is invalid to supply `mode` as a non-enumerated value. | ||
| 60 | //! It is invalid to supply `overwrite` as a non-enumerated value. | ||
| 61 | //! | ||
| 62 | //! \param path: c-string of path to open | ||
| 63 | //! \param mode: file operation mode | ||
| 64 | //! \param overwrite: overwrite existing file on create | ||
| 65 | //! \return: status of the open | ||
| 66 | //! | ||
| 67 | Os::FileInterface::Status open(const char* path, Mode mode, OverwriteType overwrite) override; | ||
| 68 | |||
| 69 | //! \brief close the file, if not opened then do nothing | ||
| 70 | //! | ||
| 71 | //! Closes the file, if open. Otherwise this function does nothing. Delegates to the chosen implementation's | ||
| 72 | //! `closeInternal` function. `mode` is set to `OPEN_NO_MODE`. | ||
| 73 | //! | ||
| 74 | void close() override; | ||
| 75 | |||
| 76 | //! \brief get size of currently open file | ||
| 77 | //! | ||
| 78 | //! Get the size of the currently open file and fill the size parameter. Return status of the operation. | ||
| 79 | //! \param size: output parameter for size. | ||
| 80 | //! \return OP_OK on success otherwise error status | ||
| 81 | //! | ||
| 82 | Status size(FwSizeType& size_result) override; | ||
| 83 | |||
| 84 | //! \brief get file pointer position of the currently open file | ||
| 85 | //! | ||
| 86 | //! Get the current position of the read/write pointer of the open file. | ||
| 87 | //! \param position: output parameter for size. | ||
| 88 | //! \return OP_OK on success otherwise error status | ||
| 89 | //! | ||
| 90 | Status position(FwSizeType& position_result) override; | ||
| 91 | |||
| 92 | //! \brief pre-allocate file storage | ||
| 93 | //! | ||
| 94 | //! Pre-allocates file storage with at least `length` storage starting at `offset`. No-op on implementations | ||
| 95 | //! that cannot pre-allocate. | ||
| 96 | //! | ||
| 97 | //! It is invalid to pass a negative `offset`. | ||
| 98 | //! It is invalid to pass a negative `length`. | ||
| 99 | //! | ||
| 100 | //! \param offset: offset into file | ||
| 101 | //! \param length: length after offset to preallocate | ||
| 102 | //! \return OP_OK on success otherwise error status | ||
| 103 | //! | ||
| 104 | Status preallocate(FwSizeType offset, FwSizeType length) override; | ||
| 105 | |||
| 106 | //! \brief seek the file pointer to the given offset | ||
| 107 | //! | ||
| 108 | //! Seek the file pointer to the given `offset`. If `seekType` is set to `ABSOLUTE` then the offset is calculated | ||
| 109 | //! from the start of the file, and if it is set to `RELATIVE` it is calculated from the current position. | ||
| 110 | //! | ||
| 111 | //! \param offset: offset to seek to | ||
| 112 | //! \param seekType: `ABSOLUTE` for seeking from beginning of file, `RELATIVE` to use current position. | ||
| 113 | //! \return OP_OK on success otherwise error status | ||
| 114 | //! | ||
| 115 | Status seek(FwSignedSizeType offset, SeekType seekType) override; | ||
| 116 | |||
| 117 | //! \brief flush file contents to storage | ||
| 118 | //! | ||
| 119 | //! Flushes the file contents to storage (i.e. out of the OS cache to disk). Does nothing in implementations | ||
| 120 | //! that do not support flushing. | ||
| 121 | //! | ||
| 122 | //! \return OP_OK on success otherwise error status | ||
| 123 | //! | ||
| 124 | Status flush() override; | ||
| 125 | |||
| 126 | //! \brief read data from this file into supplied buffer bounded by size | ||
| 127 | //! | ||
| 128 | //! Read data from this file up to the `size` and store it in `buffer`. When `wait` is set to `WAIT`, this | ||
| 129 | //! will block until the requested size has been read successfully read or the end of the file has been | ||
| 130 | //! reached. When `wait` is set to `NO_WAIT` it will return whatever data is currently available. | ||
| 131 | //! | ||
| 132 | //! `size` will be updated to the count of bytes actually read. Status will reflect the success/failure of | ||
| 133 | //! the read operation. | ||
| 134 | //! | ||
| 135 | //! It is invalid to pass `nullptr` to this function call. | ||
| 136 | //! It is invalid to pass a negative `size`. | ||
| 137 | //! It is invalid to supply wait as a non-enumerated value. | ||
| 138 | //! | ||
| 139 | //! \param buffer: memory location to store data read from file | ||
| 140 | //! \param size: size of data to read | ||
| 141 | //! \param wait: `WAIT` to wait for data, `NO_WAIT` to return what is currently available | ||
| 142 | //! \return OP_OK on success otherwise error status | ||
| 143 | //! | ||
| 144 | Status read(U8* buffer, FwSizeType& size, WaitType wait) override; | ||
| 145 | |||
| 146 | //! \brief read data from this file into supplied buffer bounded by size | ||
| 147 | //! | ||
| 148 | //! Write data to this file up to the `size` from the `buffer`. When `wait` is set to `WAIT`, this | ||
| 149 | //! will block until the requested size has been written successfully to disk. When `wait` is set to | ||
| 150 | //! `NO_WAIT` it will return once the data is sent to the OS. | ||
| 151 | //! | ||
| 152 | //! `size` will be updated to the count of bytes actually written. Status will reflect the success/failure of | ||
| 153 | //! the read operation. | ||
| 154 | //! | ||
| 155 | //! It is invalid to pass `nullptr` to this function call. | ||
| 156 | //! It is invalid to pass a negative `size`. | ||
| 157 | //! It is invalid to supply wait as a non-enumerated value. | ||
| 158 | //! | ||
| 159 | //! \param buffer: memory location to store data read from file | ||
| 160 | //! \param size: size of data to read | ||
| 161 | //! \param wait: `WAIT` to wait for data to write to disk, `NO_WAIT` to return what is currently available | ||
| 162 | //! \return OP_OK on success otherwise error status | ||
| 163 | //! | ||
| 164 | Status write(const U8* buffer, FwSizeType& size, WaitType wait) override; | ||
| 165 | |||
| 166 | //! \brief returns the raw file handle | ||
| 167 | //! | ||
| 168 | //! Gets the raw file handle from the implementation. Note: users must include the implementation specific | ||
| 169 | //! header to make any real use of this handle. Otherwise it//!must* be passed as an opaque type. | ||
| 170 | //! | ||
| 171 | //! \return raw file handle | ||
| 172 | //! | ||
| 173 | FileHandle* getHandle() override; | ||
| 174 | |||
| 175 | private: | ||
| 176 | //! \brief Maps FILE_MODE_ constants in config/OsCfg.fpp to mode_t type for open | ||
| 177 | //! | ||
| 178 | //! \param create_mode: Bitmask of file permissions derived from the FILE_MODE_ | ||
| 179 | //! constants in OsCfg.fpp | ||
| 180 | //! | ||
| 181 | //! \return mode_t value that corresponds to the provided create_mode bitmask | ||
| 182 | //! | ||
| 183 | static mode_t map_open_create_mode(const U32 create_mode); | ||
| 184 | |||
| 185 | private: | ||
| 186 | //! File handle for PosixFile | ||
| 187 | PosixFileHandle m_handle; | ||
| 188 | }; | ||
| 189 | } // namespace File | ||
| 190 | } // namespace Posix | ||
| 191 | } // namespace Os | ||
| 192 | |||
| 193 | #endif // OS_POSIX_FILE_HPP | ||
| 194 |