F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
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 
8 extern "C" {
9 #include <Utils/Hash/libcrc/lib_crc.h> // borrow CRC
10 }
11 namespace Os {
12 
13 File::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 
25 File::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 
35 File& 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 
45 File::Status File::open(const CHAR* filepath, File::Mode requested_mode) {
46  return this->open(filepath, requested_mode, OverwriteType::NO_OVERWRITE);
47 }
48 
49 File::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()) {
57  return File::Status::INVALID_MODE;
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  }
64  // Reset any open CRC calculations
65  this->m_crc = File::INITIAL_CRC;
66  return status;
67 }
68 
69 void File::close() {
70  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
71  FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
72  FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
73  this->m_delegate.close();
74  this->m_mode = Mode::OPEN_NO_MODE;
75  this->m_path = nullptr;
76 }
77 
78 bool File::isOpen() const {
79  FW_ASSERT(&this->m_delegate == reinterpret_cast<const FileInterface*>(&this->m_handle_storage[0]));
80  FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
81  return this->m_mode != Mode::OPEN_NO_MODE;
82 }
83 
85  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
86  FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
87  if (OPEN_NO_MODE == this->m_mode) {
88  return File::Status::NOT_OPENED;
89  }
90  return this->m_delegate.size(size_result);
91 }
92 
94  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
95  FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
96  // Check that the file is open before attempting operation
97  if (OPEN_NO_MODE == this->m_mode) {
98  return File::Status::NOT_OPENED;
99  }
100  return this->m_delegate.position(position_result);
101 }
102 
104  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
105  FW_ASSERT(offset >= 0);
106  FW_ASSERT(length >= 0);
107  FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
108  // Check that the file is open before attempting operation
109  if (OPEN_NO_MODE == this->m_mode) {
110  return File::Status::NOT_OPENED;
111  } else if (OPEN_READ == this->m_mode) {
112  return File::Status::INVALID_MODE;
113  }
114  return this->m_delegate.preallocate(offset, length);
115 }
116 
118  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
119  FW_ASSERT((0 <= seekType) && (seekType < SeekType::MAX_SEEK_TYPE));
120  // Cannot do a seek with a negative offset in absolute mode
121  FW_ASSERT((seekType == File::SeekType::RELATIVE) || (offset >= 0));
122  FW_ASSERT((0 <= this->m_mode) && (this->m_mode < Mode::MAX_OPEN_MODE));
123  // Check that the file is open before attempting operation
124  if (OPEN_NO_MODE == this->m_mode) {
125  return File::Status::NOT_OPENED;
126  }
127  return this->m_delegate.seek(offset, seekType);
128 }
129 
131  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
132  FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
133  // Check that the file is open before attempting operation
134  if (OPEN_NO_MODE == this->m_mode) {
135  return File::Status::NOT_OPENED;
136  } else if (OPEN_READ == this->m_mode) {
137  return File::Status::INVALID_MODE;
138  }
139  return this->m_delegate.flush();
140 }
141 
143  return this->read(buffer, size, WaitType::WAIT);
144 }
145 
147  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
148  FW_ASSERT(buffer != nullptr);
149  FW_ASSERT(size >= 0);
150  FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
151  // Check that the file is open before attempting operation
152  if (OPEN_NO_MODE == this->m_mode) {
153  size = 0;
154  return File::Status::NOT_OPENED;
155  } else if (OPEN_READ != this->m_mode) {
156  size = 0;
157  return File::Status::INVALID_MODE;
158  }
159  return this->m_delegate.read(buffer, size, wait);
160 }
161 
163  return this->write(buffer, size, WaitType::WAIT);
164 }
165 
166 
168  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
169  FW_ASSERT(buffer != nullptr);
170  FW_ASSERT(size >= 0);
171  FW_ASSERT(this->m_mode < Mode::MAX_OPEN_MODE);
172  // Check that the file is open before attempting operation
173  if (OPEN_NO_MODE == this->m_mode) {
174  size = 0;
175  return File::Status::NOT_OPENED;
176  } else if (OPEN_READ == this->m_mode) {
177  size = 0;
178  return File::Status::INVALID_MODE;
179  }
180  return this->m_delegate.write(buffer, size, wait);
181 }
182 
184  FW_ASSERT(&this->m_delegate == reinterpret_cast<FileInterface*>(&this->m_handle_storage[0]));
185  return this->m_delegate.getHandle();
186 }
187 
191  crc = 0;
192  for (FwSizeType i = 0; i < std::numeric_limits<FwSizeType>::max(); i++) {
193  status = this->incrementalCrc(size);
194  // Break on eof or error
195  if ((size != FW_FILE_CHUNK_SIZE) || (status != File::OP_OK)) {
196  break;
197  }
198  }
199  // When successful, finalize the CRC
200  if (status == File::OP_OK) {
201  status = this->finalizeCrc(crc);
202  }
203  return status;
204 }
205 
208  FW_ASSERT(size >= 0);
210  if (OPEN_NO_MODE == this->m_mode) {
211  status = File::Status::NOT_OPENED;
212  } else if (OPEN_READ != this->m_mode) {
213  status = File::Status::INVALID_MODE;
214  } else {
215  // Read data without waiting for additional data to be available
216  status = this->read(this->m_crc_buffer, size, File::WaitType::NO_WAIT);
217  if (OP_OK == status) {
218  for (FwSignedSizeType i = 0; i < size && i < FW_FILE_CHUNK_SIZE; i++) {
219  this->m_crc =
220  static_cast<U32>(
221  update_crc_32(this->m_crc, static_cast<CHAR>(this->m_crc_buffer[i]))
222  );
223  }
224  }
225  }
226  return status;
227 }
228 
231  crc = this->m_crc;
232  this->m_crc = File::INITIAL_CRC;
233  return status;
234 }
235 } // Os
236 
#define FW_ASSERT(...)
Definition: Assert.hpp:14
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:26
char CHAR
Definition: BasicTypes.h:28
PlatformSignedSizeType FwSignedSizeType
Definition: FpConfig.h:25
#define FW_FILE_CHUNK_SIZE
Chunk size for working with files.
Definition: FpConfig.h:382
PlatformSizeType FwSizeType
Definition: FpConfig.h:30
Status seek(FwSignedSizeType offset, SeekType seekType) override
seek the file pointer to the given offset
Definition: File.cpp:117
File()
constructor
Definition: File.cpp:13
Status incrementalCrc(FwSignedSizeType &size)
calculate the CRC32 of the next section of data
Definition: File.cpp:206
Status read(U8 *buffer, FwSignedSizeType &size)
read data from this file into supplied buffer bounded by size
Definition: File.cpp:142
Status flush() override
flush file contents to storage
Definition: File.cpp:130
Status size(FwSignedSizeType &size_result) override
get size of currently open file
Definition: File.cpp:84
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:69
Status finalizeCrc(U32 &crc)
finalize and retrieve the CRC value
Definition: File.cpp:229
FileHandle * getHandle() override
returns the raw file handle
Definition: File.cpp:183
~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:103
Status position(FwSignedSizeType &position_result) override
get file pointer position of the currently open file
Definition: File.cpp:93
Status calculateCrc(U32 &crc)
calculate the CRC32 of the entire file
Definition: File.cpp:188
bool isOpen() const
determine if the file is open
Definition: File.cpp:78
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:162
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
virtual Status flush()=0
flush file contents to storage
static FileInterface * getDelegate(HandleStorage &aligned_placement_new_memory, const FileInterface *to_copy=nullptr)
provide a pointer to a file delegate object
Definition: DefaultFile.cpp:10
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
@ OP_OK
Operation was successful.
Definition: File.hpp:30
@ 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
@ OP_OK
Operation was successful.
Definition: FileSystem.hpp:15
base implementation of FileHandle
Definition: File.hpp:14