GCC Code Coverage Report


Directory: ./
File: Directory.cpp
Date: 2026-09-03 22:13:09
Exec Total Coverage
Lines: 21 91 23.1%
Functions: 4 12 33.3%
Branches: 5 41 12.2%

Line Branch Exec Source
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 2 Directory::Directory()
11
3/3
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 2 times.
34 : m_is_open(false), m_handle_storage(), m_delegate(*DirectoryInterface::getDelegate(m_handle_storage)) {
12 2 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
13 2 }
14
15 4 Directory::~Directory() {
16 4 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
17
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if (this->m_is_open) {
18 this->close();
19 }
20 4 this->m_delegate.~DirectoryInterface();
21 4 }
22
23 // ------------------------------------------------------------
24 // Directory operations delegating to implementation
25 // ------------------------------------------------------------
26 DirectoryHandle* Directory::getHandle() {
27 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
28 return this->m_delegate.getHandle();
29 }
30
31 1 Directory::Status Directory::open(const char* path, OpenMode mode) {
32 1 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
33 1 FW_ASSERT(path != nullptr);
34 1 FW_ASSERT(mode >= 0 and mode < OpenMode::MAX_OPEN_MODE);
35 1 Status status = this->m_delegate.open(path, mode);
36
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (status == Status::OP_OK) {
37 1 this->m_is_open = true;
38 }
39 1 return status;
40 }
41
42 bool Directory::isOpen() {
43 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
44 return this->m_is_open;
45 }
46 Directory::Status Directory::rewind() {
47 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
48 if (not this->m_is_open) {
49 return Status::NOT_OPENED;
50 }
51 return this->m_delegate.rewind();
52 }
53
54 Directory::Status Directory::read(char* fileNameBuffer, FwSizeType bufSize) {
55 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
56 if (not this->m_is_open) {
57 return Status::NOT_OPENED;
58 }
59 FW_ASSERT(fileNameBuffer != nullptr);
60 FW_ASSERT(bufSize > 0);
61 Status status = this->m_delegate.read(fileNameBuffer, bufSize);
62 fileNameBuffer[bufSize - 1] = '\0'; // Guarantee null-termination
63 return status;
64 }
65
66 Directory::Status Directory::read(Fw::StringBase& filename) {
67 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
68 if (not this->m_is_open) {
69 return Status::NOT_OPENED;
70 }
71 return this->m_delegate.read(const_cast<char*>(filename.toChar()), filename.getCapacity());
72 }
73
74 1 void Directory::close() {
75 1 FW_ASSERT(&this->m_delegate == reinterpret_cast<DirectoryInterface*>(&this->m_handle_storage[0]));
76 1 this->m_is_open = false;
77 1 return this->m_delegate.close();
78 }
79
80 // ------------------------------------------------------------
81 // Common functions built on top of OS-specific functions
82 // ------------------------------------------------------------
83
84 Directory::Status Directory::getFileCount(FwSizeType& fileCount) {
85 if (not this->m_is_open) {
86 return Status::NOT_OPENED;
87 }
88 // Rewind to ensure we start from the beginning of the stream
89 if (this->rewind() != Status::OP_OK) {
90 return Status::OTHER_ERROR;
91 }
92 const FwSizeType loopLimit = std::numeric_limits<FwSizeType>::max();
93 FwSizeType count = 0;
94 char unusedBuffer[1]; // buffer must have size but is unused
95 Status readStatus = Status::OP_OK;
96 fileCount = 0;
97 // Count files by reading each file entry until there is NO_MORE_FILES
98 for (FwSizeType iter = 0; iter < loopLimit; ++iter) {
99 readStatus = this->read(unusedBuffer, sizeof(unusedBuffer));
100 if (readStatus == Status::NO_MORE_FILES) {
101 break;
102 } else if (readStatus != Status::OP_OK) {
103 return Status::OTHER_ERROR;
104 }
105 count++;
106 }
107 fileCount = count;
108 if (this->rewind() != Status::OP_OK) {
109 return Status::OTHER_ERROR;
110 }
111 return Status::OP_OK;
112 }
113
114 Directory::Status Directory::readDirectory(Fw::ExternalArray<Fw::String>& filenameArray, FwSizeType& filenameCount) {
115 FW_ASSERT(filenameArray.getElements() != nullptr);
116 FW_ASSERT(filenameArray.getSize() > 0);
117 if (not this->m_is_open) {
118 return Status::NOT_OPENED;
119 }
120 // Rewind to ensure we start reading from the beginning of the stream
121 if (this->rewind() != Status::OP_OK) {
122 return Status::OTHER_ERROR;
123 }
124
125 Status readStatus = Status::OP_OK;
126 Status returnStatus = Status::OP_OK;
127 FwSizeType index;
128 filenameCount = 0;
129 // Iterate through the directory and read the filenames into the array
130 for (index = 0; index < filenameArray.getSize(); index++) {
131 readStatus = this->read(filenameArray[index]);
132 if (readStatus == Status::NO_MORE_FILES) {
133 break;
134 } else if (readStatus != Status::OP_OK) {
135 return Status::OTHER_ERROR;
136 }
137 }
138 filenameCount = index;
139
140 if (this->rewind() != Status::OP_OK) {
141 return Status::OTHER_ERROR;
142 }
143
144 return returnStatus;
145 }
146
147 Directory::Status Directory::readDirectory(Fw::String filenameArray[],
148 const FwSizeType filenameArraySize,
149 FwSizeType& filenameCount) {
150 Fw::ExternalArray<Fw::String> array(filenameArray, filenameArraySize);
151 return this->readDirectory(array, filenameCount);
152 }
153
154 } // namespace Os
155