F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
Directory.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Os/Directory.cpp
3 // \brief common function implementation for Os::Directory
4 // ======================================================================
5 #include <Fw/Types/Assert.hpp>
6 #include <Os/Directory.hpp>
7 
8 namespace Os {
9 
10 Directory::Directory() : m_is_open(false), m_handle_storage(), m_delegate(*DirectoryInterface::getDelegate(m_handle_storage)) {
11  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
12 }
13 
15  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
16  if (this->m_is_open) {
17  this->close();
18  }
19  this->m_delegate.~DirectoryInterface();
20 }
21 
22 // ------------------------------------------------------------
23 // Directory operations delegating to implementation
24 // ------------------------------------------------------------
26  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
27  return this->m_delegate.getHandle();
28 }
29 
30 Directory::Status Directory::open(const char* path, OpenMode mode) {
31  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
32  FW_ASSERT(path != nullptr);
33  FW_ASSERT(mode >= 0 and mode < OpenMode::MAX_OPEN_MODE);
34  Status status = this->m_delegate.open(path, mode);
35  if (status == Status::OP_OK) {
36  this->m_is_open = true;
37  }
38  return status;
39 }
40 
42  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
43  return this->m_is_open;
44 }
46  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
47  if (not this->m_is_open) {
48  return Status::NOT_OPENED;
49  }
50  return this->m_delegate.rewind();
51 }
52 
53 Directory::Status Directory::read(char * fileNameBuffer, FwSizeType bufSize) {
54  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
55  if (not this->m_is_open) {
56  return Status::NOT_OPENED;
57  }
58  FW_ASSERT(fileNameBuffer != nullptr);
59  Status status = this->m_delegate.read(fileNameBuffer, bufSize);
60  fileNameBuffer[bufSize - 1] = '\0'; // Guarantee null-termination
61  return status;
62 }
63 
65  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
66  if (not this->m_is_open) {
67  return Status::NOT_OPENED;
68  }
69  return this->m_delegate.read(const_cast<char*>(filename.toChar()), filename.getCapacity());
70 }
71 
73  FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
74  this->m_is_open = false;
75  return this->m_delegate.close();
76 }
77 
78 // ------------------------------------------------------------
79 // Common functions built on top of OS-specific functions
80 // ------------------------------------------------------------
81 
83  if (not this->m_is_open) {
84  return Status::NOT_OPENED;
85  }
86  // Rewind to ensure we start from the beginning of the stream
87  if (this->rewind() != Status::OP_OK) {
88  return Status::OTHER_ERROR;
89  }
90  const FwSizeType loopLimit = std::numeric_limits<FwSizeType>::max();
91  FwSizeType count = 0;
92  char unusedBuffer[1]; // buffer must have size but is unused
93  Status readStatus = Status::OP_OK;
94  fileCount = 0;
95  // Count files by reading each file entry until there is NO_MORE_FILES
96  for (FwSizeType iter = 0; iter < loopLimit; ++iter) {
97  readStatus = this->read(unusedBuffer, sizeof(unusedBuffer));
98  if (readStatus == Status::NO_MORE_FILES) {
99  break;
100  } else if (readStatus != Status::OP_OK) {
101  return Status::OTHER_ERROR;
102  }
103  count++;
104  }
105  fileCount = count;
106  if (this->rewind() != Status::OP_OK) {
107  return Status::OTHER_ERROR;
108  }
109  return Status::OP_OK;
110 }
111 
112 
113 Directory::Status Directory::readDirectory(Fw::String filenameArray[], const FwSizeType filenameArraySize, FwSizeType& filenameCount) {
114  FW_ASSERT(filenameArray != nullptr);
115  FW_ASSERT(filenameArraySize > 0);
116  if (not this->m_is_open) {
117  return Status::NOT_OPENED;
118  }
119  // Rewind to ensure we start reading from the beginning of the stream
120  if (this->rewind() != Status::OP_OK) {
121  return Status::OTHER_ERROR;
122  }
123 
124  Status readStatus = Status::OP_OK;
125  Status returnStatus = Status::OP_OK;
126  FwSizeType index;
127  filenameCount = 0;
128  // Iterate through the directory and read the filenames into the array
129  for (index = 0; index < filenameArraySize; index++) {
130  readStatus = this->read(filenameArray[index]);
131  if (readStatus == Status::NO_MORE_FILES) {
132  break;
133  } else if (readStatus != Status::OP_OK) {
134  return Status::OTHER_ERROR;
135  }
136  }
137  filenameCount = index;
138 
139  if (this->rewind() != Status::OP_OK) {
140  return Status::OTHER_ERROR;
141  }
142 
143  return returnStatus;
144 
145 }
146 
147 
148 } // namespace Os
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
virtual const CHAR * toChar() const =0
virtual SizeType getCapacity() const =0
return size of buffer
Status rewind() override
Rewind directory stream.
Definition: Directory.cpp:45
Status getFileCount(FwSizeType &fileCount)
Get the number of files in the directory.
Definition: Directory.cpp:82
Status open(const char *path, OpenMode mode) override
Open or create a directory.
Definition: Directory.cpp:30
bool isOpen()
Check if Directory is open or not.
Definition: Directory.cpp:41
DirectoryHandle * getHandle() override
return the underlying Directory handle (implementation specific)
Definition: Directory.cpp:25
Status readDirectory(Fw::String filenameArray[], const FwSizeType arraySize, FwSizeType &filenameCount)
Read the contents of the directory and store filenames in filenameArray of size arraySize.
Definition: Directory.cpp:113
void close() override
Close directory.
Definition: Directory.cpp:72
~Directory() final
Destructor.
Definition: Directory.cpp:14
Directory()
Constructor.
Definition: Directory.cpp:10
Status read(char *fileNameBuffer, FwSizeType buffSize) override
Get next filename from directory stream.
Definition: Directory.cpp:53
virtual Status rewind()=0
Rewind directory stream.
virtual Status open(const char *path, OpenMode mode)=0
Open or create a directory.
virtual ~DirectoryInterface()=default
default virtual destructor
virtual void close()=0
Get next filename from directory stream and write it to a Fw::StringBase object.
virtual Status read(char *fileNameBuffer, FwSizeType buffSize)=0
Get next filename from directory stream.
virtual DirectoryHandle * getHandle()=0
return the underlying Directory handle (implementation specific)
@ OP_OK
Operation succeeded.
Definition: Os.hpp:26
@ OTHER_ERROR
A catch-all for other errors. Have to look in implementation-specific code.