F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
File.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title Os/File.cpp
3// \brief common function implementation for Os::File
4// ======================================================================
5#include <Os/File.hpp>
6#include <Fw/Types/Assert.hpp>
7
8extern "C" {
9#include <Utils/Hash/libcrc/lib_crc.h> // borrow CRC
10}
11namespace Os {
12
13File::File() : m_crc_buffer(), m_handle_storage(), m_delegate(*FileInterface::getDelegate(m_handle_storage)) {
14 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
15}
16
18 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
19 if (this->m_mode != OPEN_NO_MODE) {
20 this->close();
21 }
22 m_delegate.~FileInterface();
23}
24
25File::File(const File& other) :
26 m_mode(other.m_mode),
27 m_path(other.m_path),
28 m_crc(other.m_crc),
29 m_crc_buffer(),
30 m_handle_storage(),
31 m_delegate(*FileInterface::getDelegate(m_handle_storage, &other.m_delegate)) {
32 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
33}
34
35File& File::operator=(const File& other) {
36 if (this != &other) {
37 this->m_mode = other.m_mode;
38 this->m_path = other.m_path;
39 this->m_crc = other.m_crc;
40 this->m_delegate = *FileInterface::getDelegate(m_handle_storage, &other.m_delegate);
41 }
42 return *this;
43}
44
45File::Status File::open(const CHAR* filepath, File::Mode requested_mode) {
46 return this->open(filepath, requested_mode, OverwriteType::NO_OVERWRITE);
47}
48
49File::Status File::open(const CHAR* filepath, File::Mode requested_mode, File::OverwriteType overwrite) {
50 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
51 FW_ASSERT(nullptr != filepath);
52 FW_ASSERT(File::Mode::OPEN_NO_MODE < requested_mode && File::Mode::MAX_OPEN_MODE > requested_mode);
53 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
54 FW_ASSERT((0 <= overwrite) && (overwrite < OverwriteType::MAX_OVERWRITE_TYPE));
55 // Check for already opened file
56 if (this->isOpen()) {
58 }
59 File::Status status = this->m_delegate.open(filepath, requested_mode, overwrite);
60 if (status == File::Status::OP_OK) {
61 this->m_mode = requested_mode;
62 this->m_path = filepath;
63 // Reset any open CRC calculations
64 this->m_crc = File::INITIAL_CRC;
65 }
66
67 return status;
68}
69
71 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
72 FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
73 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
74 this->m_delegate.close();
75 this->m_mode = Mode::OPEN_NO_MODE;
76 this->m_path = nullptr;
77}
78
79bool File::isOpen() const {
80 FW_ASSERT(&this->m_delegate == reinterpret_cast<const FileInterface*>(&this->m_handle_storage[0]));
81 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
82 return this->m_mode != Mode::OPEN_NO_MODE;
83}
84
86 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
87 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
88 if (OPEN_NO_MODE == this->m_mode) {
90 }
91 return this->m_delegate.size(size_result);
92}
93
95 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
96 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
97 // Check that the file is open before attempting operation
98 if (OPEN_NO_MODE == this->m_mode) {
100 }
101 return this->m_delegate.position(position_result);
102}
103
105 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
106 FW_ASSERT(offset >= 0);
107 FW_ASSERT(length >= 0);
108 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
109 // Check that the file is open before attempting operation
110 if (OPEN_NO_MODE == this->m_mode) {
112 } else if (OPEN_READ == this->m_mode) {
114 }
115 return this->m_delegate.preallocate(offset, length);
116}
117
119 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
120 FW_ASSERT((0 <= seekType) && (seekType < SeekType::MAX_SEEK_TYPE));
121 // Cannot do a seek with a negative offset in absolute mode
122 FW_ASSERT((seekType == File::SeekType::RELATIVE) || (offset >= 0));
123 FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
124 // Check that the file is open before attempting operation
125 if (OPEN_NO_MODE == this->m_mode) {
127 }
128 return this->m_delegate.seek(offset, seekType);
129}
130
132 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
133 FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
134 // Check that the file is open before attempting operation
135 if (OPEN_NO_MODE == this->m_mode) {
137 } else if (OPEN_READ == this->m_mode) {
139 }
140 return this->m_delegate.flush();
141}
142
144 return this->read(buffer, size, WaitType::WAIT);
145}
146
148 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
149 FW_ASSERT(buffer != nullptr);
150 FW_ASSERT(size >= 0);
151 FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
152 // Check that the file is open before attempting operation
153 if (OPEN_NO_MODE == this->m_mode) {
154 size = 0;
156 } else if (OPEN_READ != this->m_mode) {
157 size = 0;
159 }
160 return this->m_delegate.read(buffer, size, wait);
161}
162
164 return this->write(buffer, size, WaitType::WAIT);
165}
166
167
169 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
170 FW_ASSERT(buffer != nullptr);
171 FW_ASSERT(size >= 0);
172 FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
173 // Check that the file is open before attempting operation
174 if (OPEN_NO_MODE == this->m_mode) {
175 size = 0;
177 } else if (OPEN_READ == this->m_mode) {
178 size = 0;
180 }
181 return this->m_delegate.write(buffer, size, wait);
182}
183
185 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
186 return this->m_delegate.getHandle();
187}
188
192 crc = 0;
193 for (FwSizeType i = 0; i < std::numeric_limits<FwSizeType>::max(); i++) {
194 status = this->incrementalCrc(size);
195 // Break on eof or error
196 if ((size != FW_FILE_CHUNK_SIZE) || (status != File::OP_OK)) {
197 break;
198 }
199 }
200 // When successful, finalize the CRC
201 if (status == File::OP_OK) {
202 status = this->finalizeCrc(crc);
203 }
204 return status;
205}
206
209 FW_ASSERT(size >= 0);
211 if (OPEN_NO_MODE == this->m_mode) {
213 } else if (OPEN_READ != this->m_mode) {
215 } else {
216 // Read data without waiting for additional data to be available
217 status = this->read(this->m_crc_buffer, size, File::WaitType::NO_WAIT);
218 if (OP_OK == status) {
219 for (FwSignedSizeType i = 0; i < size && i < FW_FILE_CHUNK_SIZE; i++) {
220 this->m_crc =
221 static_cast<U32>(
222 update_crc_32(this->m_crc, static_cast<CHAR>(this->m_crc_buffer[i]))
223 );
224 }
225 }
226 }
227 return status;
228}
229
232 crc = this->m_crc;
233 this->m_crc = File::INITIAL_CRC;
234 return status;
235}
236
238 const FwSignedSizeType requested_size = size;
239 FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
240 FW_ASSERT(buffer != nullptr);
241 FW_ASSERT(size >= 0);
242 FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
243 // Check that the file is open before attempting operation
244 if (OPEN_NO_MODE == this->m_mode) {
245 size = 0;
247 } else if (OPEN_READ != this->m_mode) {
248 size = 0;
250 }
251 FwSignedSizeType original_location;
252 File::Status status = this->position(original_location);
253 if (status != Os::File::Status::OP_OK) {
254 size = 0;
255 return status;
256 }
258 // Loop reading chunk by chunk
259 for (FwSignedSizeType i = 0; i < size; i += read) {
260 FwSignedSizeType current_chunk_size = FW_MIN(size - i, FW_FILE_CHUNK_SIZE);
261 read = current_chunk_size;
262 status = this->read(buffer + i, read, wait);
263 if (status != File::Status::OP_OK) {
264 (void) this->seek(original_location, File::SeekType::ABSOLUTE);
265 return status;
266 }
267 // EOF break out now
268 if (read == 0) {
269 size = i;
271 }
272 // Loop from i to i + current_chunk_size looking for `\n`
273 for (FwSignedSizeType j = i; j < (i + read); j++) {
274 // Newline seek back to after it, return the size read
275 if (buffer[j] == '\n') {
276 size = j + 1;
277 // Ensure that the computation worked
278 FW_ASSERT(size <= requested_size);
279 (void) this->seek(original_location + j + 1, File::SeekType::ABSOLUTE);
281 }
282 }
283 }
284 // Failed to find newline within data available
286}
287} // Os
288
#define FW_ASSERT(...)
Definition Assert.hpp:14
#define FW_MIN(a, b)
MIN macro.
Definition BasicTypes.h:72
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:30
char CHAR
Definition BasicTypes.h:32
PlatformSignedSizeType FwSignedSizeType
Definition FpConfig.h:30
#define FW_FILE_CHUNK_SIZE
Chunk size for working with files in the OSAL layer.
Definition FpConfig.h:445
PlatformSizeType FwSizeType
Definition FpConfig.h:35
Status seek(FwSignedSizeType offset, SeekType seekType) override
seek the file pointer to the given offset
Definition File.cpp:118
File()
constructor
Definition File.cpp:13
Status incrementalCrc(FwSignedSizeType &size)
calculate the CRC32 of the next section of data
Definition File.cpp:207
Status read(U8 *buffer, FwSignedSizeType &size)
read data from this file into supplied buffer bounded by size
Definition File.cpp:143
Status flush() override
flush file contents to storage
Definition File.cpp:131
Status size(FwSignedSizeType &size_result) override
get size of currently open file
Definition File.cpp:85
void close() override
close the file, if not opened then do nothing
Definition File.cpp:70
Status finalizeCrc(U32 &crc)
finalize and retrieve the CRC value
Definition File.cpp:230
Status readline(U8 *buffer, FwSignedSizeType &size, WaitType wait)
read a line from the file using \n as the delimiter
Definition File.cpp:237
FileHandle * getHandle() override
returns the raw file handle
Definition File.cpp:184
~File() final
destructor
Definition File.cpp:17
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
Definition File.cpp:45
Status preallocate(FwSignedSizeType offset, FwSignedSizeType length) override
pre-allocate file storage
Definition File.cpp:104
Status position(FwSignedSizeType &position_result) override
get file pointer position of the currently open file
Definition File.cpp:94
Status calculateCrc(U32 &crc)
calculate the CRC32 of the entire file
Definition File.cpp:189
bool isOpen() const
determine if the file is open
Definition File.cpp:79
File & operator=(const File &other)
assignment operator that copies the internal representation
Definition File.cpp:35
Status write(const U8 *buffer, FwSignedSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition File.cpp:163
virtual void close()=0
close the file, if not opened then do nothing
virtual Status size(FwSignedSizeType &size_result)=0
get size of currently open file
virtual Status preallocate(FwSignedSizeType offset, FwSignedSizeType length)=0
pre-allocate file storage
@ WAIT
Do wait for read/write operation to finish.
Definition File.hpp:58
@ NO_WAIT
Do not wait for read/write operation to finish.
Definition File.hpp:57
virtual Status flush()=0
flush file contents to storage
@ NO_OVERWRITE
Do NOT overwrite existing files.
Definition File.hpp:45
static FileInterface * getDelegate(FileHandleStorage &aligned_placement_new_memory, const FileInterface *to_copy=nullptr)
provide a pointer to a file delegate object
virtual Status write(const U8 *buffer, FwSignedSizeType &size, WaitType wait)=0
read data from this file into supplied buffer bounded by size
virtual Status position(FwSignedSizeType &position_result)=0
get file pointer position of the currently open file
virtual Status open(const char *path, Mode mode, OverwriteType overwrite)=0
open file with supplied path and mode
virtual Status read(U8 *buffer, FwSignedSizeType &size, WaitType wait)=0
read data from this file into supplied buffer bounded by size
@ INVALID_MODE
Mode for file access is invalid for current operation.
Definition File.hpp:38
@ NOT_OPENED
file hasn't been opened yet
Definition File.hpp:35
@ OTHER_ERROR
A catch-all for other errors. Have to look in implementation-specific code.
Definition File.hpp:40
@ OP_OK
Operation was successful.
Definition File.hpp:30
@ ABSOLUTE
Absolute seek from beginning of file.
Definition File.hpp:52
@ RELATIVE
Relative seek from current file offset.
Definition File.hpp:51
@ MAX_OPEN_MODE
Maximum value of mode.
Definition File.hpp:26
@ OPEN_NO_MODE
File mode not yet selected.
Definition File.hpp:20
@ OPEN_READ
Open file for reading.
Definition File.hpp:21
virtual FileHandle * getHandle()=0
returns the raw file handle
virtual Status seek(FwSignedSizeType offset, SeekType seekType)=0
seek the file pointer to the given offset
virtual ~FileInterface()=default
unsigned long update_crc_32(unsigned long crc, char c)
Definition lib_crc.c:271
base implementation of FileHandle
Definition File.hpp:14