GCC Code Coverage Report


Directory: ./
File: Svc/DpCatalog/DpCatalog.hpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 1 1 100.0%
Functions: 1 1 100.0%
Branches: 3 4 75.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title DpCatalog.hpp
3 // \author tcanham
4 // \brief hpp file for DpCatalog component implementation class
5 // ======================================================================
6
7 #ifndef Svc_DpCatalog_HPP
8 #define Svc_DpCatalog_HPP
9
10 #include "Svc/DpCatalog/DpCatalogComponentAc.hpp"
11 #include "Svc/DpCatalog/DpRecordSerializableAc.hpp"
12
13 #include <Fw/DataStructures/ExternalArray.hpp>
14 #include <Fw/DataStructures/RedBlackTreeSet.hpp>
15 #include <Fw/Deprecate.hpp>
16 #include <Fw/Types/MemAllocator.hpp>
17
18 #include <Fw/Types/FileNameString.hpp>
19 #include <config/DpCatalogCfg.hpp>
20 #include <config/DpCfg.hpp>
21
22 #define DIRECTORY_DELIMITER "/"
23
24 namespace Svc {
25
26 class DpCatalog final : public DpCatalogComponentBase {
27 friend class DpCatalogTester;
28
29 public:
30 // ----------------------------------------------------------------------
31 // Component construction and destruction
32 // ----------------------------------------------------------------------
33
34 /// @brief DpCatalog constructor
35 /// @param compName component name
36 DpCatalog(const char* const compName //!< The component name
37 );
38
39 /// @brief DpCatalog destructor
40
3/4
✓ Branch 16 taken 526 times.
✗ Branch 17 not taken.
✓ Branch 23 taken 1052 times.
✓ Branch 24 taken 526 times.
3156 ~DpCatalog() = default;
41
42 /// @brief Configure the DpCatalog
43 /// @param directories array of directories to scan; at most DP_MAX_DIRECTORIES entries
44 /// @param stateFile file to store transmit state. Provide a zero-length string if no state tracking
45 /// @param memId memory ID for allocator
46 /// @param allocator Allocator to supply memory for catalog.
47 /// Instance must survive for shutdown to use for reclaiming memory
48 void configure(const Fw::ExternalArray<Fw::FileNameString>& directories,
49 Fw::FileNameString& stateFile,
50 FwEnumStoreType memId,
51 Fw::MemAllocator& allocator);
52
53 /// @brief Configure the DpCatalog
54 /// @param directories list of directories to scan
55 /// @param numDirs number of supplied directories
56 /// @param stateFile file to store transmit state. Provide a zero-length string if no state tracking
57 /// @param memId memory ID for allocator
58 /// @param allocator Allocator to supply memory for catalog.
59 /// Instance must survive for shutdown to use for reclaiming memory
60 DEPRECATED(void configure(Fw::FileNameString directories[DP_MAX_DIRECTORIES],
61 FwSizeType numDirs,
62 Fw::FileNameString& stateFile,
63 FwEnumStoreType memId,
64 Fw::MemAllocator& allocator),
65 "Use configure(const Fw::ExternalArray<Fw::FileNameString>& directories, ...) instead");
66
67 // @brief clean up component.
68 // Deallocates memory.
69 void shutdown();
70
71 private:
72 // ----------------------------------------------------------------------
73 // Handler implementations for user-defined typed input ports
74 // ----------------------------------------------------------------------
75
76 //! Handler implementation for fileDone
77 //!
78 //! File Downlink send complete port
79 void fileDone_handler(FwIndexType portNum, //!< The port number
80 const Svc::SendFileResponse& resp) override;
81
82 //! Handler implementation for pingIn
83 //!
84 //! Ping input port
85 void pingIn_handler(FwIndexType portNum, //!< The port number
86 U32 key //!< Value to return to pinger
87 ) override;
88
89 //! Handler implementation for addToCat
90 //!
91 //! DP Writer Add File to Cat
92 void addToCat_handler(FwIndexType portNum, //!< The port number
93 const Fw::StringBase& fileName, //!< The file name
94 FwDpPriorityType priority, //!< The priority
95 FwSizeType size //!< The file size
96 ) override;
97
98 private:
99 // ----------------------------------------------------------------------
100 // Handler implementations for commands
101 // ----------------------------------------------------------------------
102
103 //! Handler implementation for command BUILD_CATALOG
104 //!
105 //! Build catalog from data product directory
106 void BUILD_CATALOG_cmdHandler(FwOpcodeType opCode, //!< The opcode
107 U32 cmdSeq //!< The command sequence number
108 ) override;
109
110 //! Handler implementation for command START_XMIT_CATALOG
111 //!
112 //! Start transmitting catalog
113 void START_XMIT_CATALOG_cmdHandler(
114 FwOpcodeType opCode, //!< The opcode
115 U32 cmdSeq, //!< The command sequence number
116 const Fw::Wait& wait, //!< have START_XMIT command wait for catalog to complete transmitting
117 bool remainActive //!< should the catalog resume transmission when Dps are added at runtime
118 ) override;
119
120 //! Handler implementation for command STOP_XMIT_CATALOG
121 //!
122 //! Stop transmitting catalog
123 void STOP_XMIT_CATALOG_cmdHandler(FwOpcodeType opCode, //!< The opcode
124 U32 cmdSeq //!< The command sequence number
125 ) override;
126
127 //! Handler implementation for command CLEAR_CATALOG
128 //!
129 //! clear existing catalog
130 void CLEAR_CATALOG_cmdHandler(FwOpcodeType opCode, //!< The opcode
131 U32 cmdSeq //!< The command sequence number
132 ) override;
133
134 // ----------------------------------
135 // Private data structures
136 // ----------------------------------
137
138 struct DpStateEntry {
139 friend class DpCatalogTester;
140 FwIndexType dir; //!< index to m_directories entry that has directory name where DP exists
141 DpRecord record; //!< data product metadata
142
143 /// @brief insert an entry into the sorted list; if it exists, update the metadata
144 /// @param left an entry to compare
145 /// @param right other entry to compare
146 /// @return -1 if left is higher priority, 0 if equal, and 1 if right is higher priority
147 static I8 compareEntries(const DpStateEntry& left, const DpStateEntry& right);
148
149 bool operator==(const DpStateEntry& other) const;
150 bool operator!=(const DpStateEntry& other) const;
151 bool operator>(const DpStateEntry& other) const;
152 bool operator<(const DpStateEntry& other) const;
153 };
154
155 struct DpDstateFileEntry {
156 bool used; //!< if the entry is used
157 bool visited; //!< used for state file state; indicates that the entry was found in the search of current data
158 //!< products
159 DpStateEntry entry; //!< state entry from file
160 };
161
162 // ----------------------------------
163 // Private helpers
164 // ----------------------------------
165
166 //! Status of a processFile() call
167 enum class ProcessFileStatus {
168 SUCCESS, //!< file added to the catalog
169 FAILED, //!< file could not be processed; continue with the next file
170 QUIT //!< catalog is full; stop processing files
171 };
172
173 /// @brief determine in which managed directory a file resides
174 /// @param fullFile full path to file to be processed
175 /// @return directory index in m_directories; DP_MAX_DIRECTORIES if not in a managed dir
176 FwSizeType determineDirectory(const Fw::String& fullFile);
177
178 /// @brief add entry to sorted list and state file; called on each file in it & upon addToCat
179 /// @param fullFile full path to file to be processed
180 /// @param dir directory index in m_directories
181 /// @return QUIT to stop processing, FAILED for failure but continue, SUCCESS for success
182 ProcessFileStatus processFile(const Fw::String& fullFile, FwSizeType dir);
183
184 /// @brief insert an entry into the sorted catalog; if it exists, update the metadata
185 /// @param entry new entry
186 /// @return true if inserted successfully, false if catalog is full
187 bool insertEntry(DpStateEntry& entry);
188
189 /// @brief reset the catalog
190 void resetCatalog();
191
192 /// #brief fill the binary tree from DP files
193 Fw::CmdResponse fillBinaryTree();
194
195 /// @brief reset the state file data
196 void resetStateFileData();
197
198 /// @brief get file state from the stored state file
199 /// @param entry entry to update from file state
200 void getFileState(DpStateEntry& entry);
201
202 /// @brief prune the state file data and write the remaining entries back
203 void pruneAndWriteStateFile();
204
205 /// @brief load state data from file
206 Fw::CmdResponse loadStateFile();
207
208 /// @brief get file state from the stored state file
209 /// @param entry entry to add to state file
210 void appendFileState(const DpStateEntry& entry);
211
212 /// @brief send the next entry to file downlink
213 void sendNextEntry();
214
215 /// @brief find the next entry in the catalog using iterator
216 /// @param entry entry to return
217 /// @return true if an entry was found, false if no more entries
218 bool findNextEntry(DpStateEntry& entry);
219
220 /// @brief check to see if component successfully initialized
221 /// @return bool if it was initialized
222 bool checkInit();
223
224 /// @brief build catalog. Shared between command and port
225 /// @return command response for pass/fail
226 Fw::CmdResponse doCatalogBuild();
227
228 /// @brief start transmitting catalog. Shared between command and port
229 /// @return command response for pass/fail
230 Fw::CmdResponse doCatalogXmit();
231
232 /// @brief send a cmdResponse to the start xmit cmd if user waited
233 /// @param response the command response for pass/fail
234 void dispatchWaitedResponse(Fw::CmdResponse response);
235
236 // ----------------------------------
237 // Private data
238 // ----------------------------------
239 bool m_initialized = false; //!< set when the component has been initialized
240
241 Fw::RedBlackTreeSet<DpStateEntry, DP_MAX_FILES> m_dpCatalog; //!< The sorted catalog of DPs
242 DpStateEntry m_currentXmitEntry; //!< Entry currently being transmitted
243 bool m_hasCurrentXmit = false; //!< Whether m_currentXmitEntry is valid
244
245 FwSizeType m_numDpSlots = 0; //!< Stores the available number of record slots.
246
247 Fw::FileNameString m_directories[DP_MAX_DIRECTORIES]; //!< List of supplied DP directories
248 FwSizeType m_numDirectories = 0; //!< number of supplied directories
249
250 Fw::FileNameString m_stateFile; //!< file to store transmit state
251 DpDstateFileEntry* m_stateFileData = nullptr; //!< DP state loaded from file
252 FwSizeType m_stateFileEntries = 0; //!< size of state file data
253
254 FwSizeType m_memSize = 0; //!< size of allocated buffer
255 void* m_memPtr = nullptr; //!< stored for shutdown
256 FwEnumStoreType m_allocatorId = 0; //!< stored for shutdown
257 Fw::MemAllocator* m_allocator = nullptr; //!< stored for shutdown
258
259 bool m_catalogBuilt = false; //!< catalog build is complete (can add DPs at runtime)
260 bool m_xmitInProgress = false; //!< set if DP files are in the process of being sent
261 Fw::FileNameString m_currXmitFileName; //!< current file being transmitted
262 bool m_xmitCmdWait = false; //!< true if waiting for transmission complete to complete xmit command
263 U64 m_xmitBytes = 0; //!< bytes transmitted for downlink session
264 FwOpcodeType m_xmitOpCode = 0; //!< stored xmit command opcode
265 U32 m_xmitCmdSeq = 0; //!< stored command sequence id
266
267 U32 m_pendingFiles = 0; //!< Pending Files to Transmit
268 U64 m_pendingDpBytes = 0; //!< Pending Bytes to Transmit
269
270 bool m_remainActive = false; //!< Does the DpCat resume transmission when
271 //!< a runtime Dp is received after
272 //!< the full catalog is sent
273 };
274
275 } // namespace Svc
276
277 #endif
278