27 m_freeListHead(nullptr),
28 m_freeListFoot(nullptr),
29 m_traverseStack(nullptr),
30 m_currentNode(nullptr),
31 m_currentXmitNode(nullptr),
35 m_stateFileData(nullptr),
36 m_stateFileEntries(0),
41 m_xmitInProgress(false),
65 this->m_stateFile = stateFile;
74 static const FwSizeType slotSize =
sizeof(DpBtreeNode) +
sizeof(DpBtreeNode**) +
sizeof(DpDstateFileEntry);
78 this->m_memPtr = allocator.
allocate(memId, this->m_memSize, notUsed);
101 (this->m_memSize >=
sizeof(DpBtreeNode)) and
102 (this->m_memPtr !=
nullptr)
105 this->m_numDpSlots = this->m_memSize / slotSize;
106 this->resetBinaryTree();
108 this->m_traverseStack =
reinterpret_cast<DpBtreeNode**
>(&this->m_freeListHead[this->m_numDpSlots]);
109 this->resetTreeStack();
111 this->m_stateFileData =
reinterpret_cast<DpDstateFileEntry*
>(&this->m_traverseStack[this->m_numDpSlots]);
116 this->m_numDpSlots = 0;
120 for (
FwSizeType dir = 0; dir < numDirs; dir++) {
121 this->m_directories[dir] = directories[dir];
123 this->m_numDirectories = numDirs;
126 this->m_allocator = &allocator;
127 this->m_allocatorId = memId;
128 this->m_initialized =
true;
131 void DpCatalog::resetBinaryTree() {
135 this->m_freeListHead =
static_cast<DpBtreeNode*
>(this->m_memPtr);
136 for (
FwSizeType slot = 0; slot < this->m_numDpSlots; slot++) {
138 (void)
new(&this->m_freeListHead[slot]) DpBtreeNode();
139 this->m_freeListHead[slot].left =
nullptr;
140 this->m_freeListHead[slot].right =
nullptr;
143 this->m_freeListHead[slot-1].left = &this->m_freeListHead[slot];
147 this->m_freeListFoot = &this->m_freeListHead[this->m_numDpSlots - 1];
149 this->m_dpTree =
nullptr;
151 this->m_numDpRecords = 0;
155 void DpCatalog::resetStateFileData() {
157 for (
FwSizeType slot = 0; slot < this->m_numDpSlots; slot++) {
158 this->m_stateFileData[slot].used =
false;
159 this->m_stateFileData[slot].visited =
false;
160 (void)
new(&this->m_stateFileData[slot].entry.record) DpRecord();
162 this->m_stateFileEntries = 0;
170 if (this->m_stateFile.
length() == 0) {
189 this->m_stateFileEntries = 0;
192 for (
FwSizeType entry = 0; entry < this->m_numDpSlots; entry++) {
196 stat = stateFile.
read(buffer, size);
210 if (size !=
sizeof(buffer)) {
216 Fw::SerializeStatus serStat = entryBuffer.setBuffLen(static_cast<Fw::Serializable::SizeType>(size));
219 entryBuffer.resetDeser();
225 Fw::SerializeStatus status = entryBuffer.deserialize(this->m_stateFileData[entry].entry.dir);
227 status = entryBuffer.deserialize(this->m_stateFileData[entry].entry.record);
229 this->m_stateFileData[entry].used =
true;
230 this->m_stateFileData[entry].visited =
false;
234 this->m_stateFileEntries++;
240 void DpCatalog::getFileState(DpStateEntry& entry) {
243 for (
FwSizeType line = 0; line < this->m_stateFileEntries; line++) {
246 (this->m_stateFileData[line].entry.dir == entry.dir) and
247 (this->m_stateFileData[line].entry.record.getid() == entry.record.getid()) and
248 (this->m_stateFileData[line].entry.record.gettSec() == entry.record.gettSec()) and
249 (this->m_stateFileData[line].entry.record.gettSub() == entry.record.gettSub()) and
250 (this->m_stateFileData[line].entry.record.getpriority() == entry.record.getpriority())
253 entry.record.setstate(this->m_stateFileData[line].entry.record.getstate());
254 entry.record.setblocks(this->m_stateFileData[line].entry.record.getblocks());
256 this->m_stateFileData[line].visited =
true;
262 void DpCatalog::pruneAndWriteStateFile() {
275 this->m_stateFile.
toChar(),
289 for (
FwSizeType entry = 0; entry < this->m_numDpSlots; entry++) {
292 (this->m_stateFileData[entry].used) and
293 (this->m_stateFileData[entry].visited)
296 entryBuffer.resetSer();
298 Fw::SerializeStatus serStat = entryBuffer.serialize(this->m_stateFileData[entry].entry.dir);
301 serStat = entryBuffer.serialize(this->m_stateFileData[entry].entry.record);
306 stat = stateFile.
write(buffer, size);
318 void DpCatalog::appendFileState(
const DpStateEntry& entry) {
320 FW_ASSERT(entry.dir < static_cast<FwIndexType>(this->m_numDirectories),
322 static_cast<FwAssertArgType>(this->m_numDirectories)
339 BYTE buffer[
sizeof(entry.dir)+
sizeof(entry.record)];
342 entryBuffer.resetSer();
347 serStat = entryBuffer.serialize(entry.record);
352 stat = stateFile.
write(buffer, size);
366 if (not this->checkInit()) {
372 if (0 == this->m_numDpSlots) {
378 if (this->m_xmitInProgress) {
384 this->resetStateFileData();
390 this->resetBinaryTree();
393 response = this->fillBinaryTree();
396 this->resetBinaryTree();
397 this->resetStateFileData();
402 this->pruneAndWriteStateFile();
422 for (
FwSizeType dir = 0; dir < this->m_numDirectories; dir++) {
426 U32 pendingFiles = 0;
427 U64 pendingDpBytes = 0;
428 U32 filesProcessed = 0;
434 this->m_directories[dir],
439 status = dpDir.
readDirectory(this->m_fileList, (this->m_numDpSlots - totalFiles), filesRead);
443 this->m_directories[dir],
451 filesRead <= this->m_numDpSlots - totalFiles,
452 static_cast<FwAssertArgType>(filesRead),
453 static_cast<FwAssertArgType>(this->m_numDpSlots - totalFiles));
461 this->m_fileList[file].toChar(),
462 this->m_fileList[file].length(),
473 this->m_directories[dir].toChar(),
474 this->m_fileList[file].toChar()
497 stat = dpFile.
read(dpBuff, size);
526 entry.record.setid(container.
getId());
528 entry.record.setstate(container.
getState());
531 entry.record.setsize(static_cast<U64>(fileSize));
534 this->getFileState(entry);
537 bool insertedOk = this->insertEntry(entry);
538 if (not insertedOk) {
541 this->resetBinaryTree();
542 this->resetStateFileData();
548 pendingDpBytes += entry.record.getsize();
552 if (this->m_numDpRecords > this->m_numDpSlots) {
561 totalFiles += filesProcessed;
564 this->m_directories[dir],
565 static_cast<U32>(totalFiles),
572 if (totalFiles == this->m_numDpSlots) {
583 bool DpCatalog::insertEntry(DpStateEntry& entry) {
593 if (this->m_dpTree ==
nullptr) {
594 bool goodInsert = this->allocateNode(this->m_dpTree,entry);
595 if (not goodInsert) {
601 DpBtreeNode* node = this->m_dpTree;
602 for (
FwSizeType record = 0; record < this->m_numDpSlots; record++) {
603 CheckStat stat = CheckStat::CHECK_CONT;
605 if (entry.record.getpriority() == node->entry.record.getpriority()) {
607 if (entry.record.gettSec() == node->entry.record.gettSec()) {
609 stat = this->checkLeftRight(
610 entry.record.getid() < node->entry.record.getid(),
615 stat = this->checkLeftRight(
616 entry.record.gettSec() < node->entry.record.gettSec(),
622 stat = this->checkLeftRight(
623 entry.record.getpriority() < node->entry.record.getpriority(),
630 if (stat == CheckStat::CHECK_ERROR) {
632 }
else if (stat == CheckStat::CHECK_OK) {
640 this->m_numDpRecords++;
646 DpCatalog::CheckStat DpCatalog::checkLeftRight(
bool condition, DpBtreeNode* &node,
const DpStateEntry& newEntry) {
648 if (node->left ==
nullptr) {
649 bool allocated = this->allocateNode(node->left,newEntry);
651 return CheckStat::CHECK_ERROR;
653 return CheckStat::CHECK_OK;
656 return CheckStat::CHECK_CONT;
659 if (node->right ==
nullptr) {
660 bool allocated = this->allocateNode(node->right,newEntry);
662 return CheckStat::CHECK_ERROR;
664 return CheckStat::CHECK_OK;
667 return CheckStat::CHECK_CONT;
673 bool DpCatalog::allocateNode(DpBtreeNode* &newNode,
674 const DpStateEntry& newEntry) {
678 if (this->m_freeListHead ==
nullptr) {
683 newNode = this->m_freeListHead;
685 this->m_freeListHead = this->m_freeListHead->left;
688 newNode->left =
nullptr;
689 newNode->right =
nullptr;
690 newNode->entry = newEntry;
698 void DpCatalog::deleteEntry(DpStateEntry& entry) {
702 void DpCatalog::sendNextEntry() {
710 this->m_currentXmitNode = this->findNextTreeNode();
712 if (this->m_currentXmitNode ==
nullptr) {
714 this->m_xmitInProgress =
false;
716 if (this->m_xmitCmdWait) {
723 this->m_directories[this->m_currentXmitNode->entry.dir].toChar(),
724 this->m_currentXmitNode->entry.record.getid(),
725 this->m_currentXmitNode->entry.record.gettSec(),
726 this->m_currentXmitNode->entry.record.gettSub()
729 this->m_currXmitFileName,
730 static_cast<U32>(this->m_currentXmitNode->entry.record.getsize()),
731 this->m_currentXmitNode->entry.record.getpriority()
744 DpCatalog::DpBtreeNode* DpCatalog::findNextTreeNode() {
751 DpBtreeNode* found =
nullptr;
755 for (
FwSizeType record = 0; record < this->m_numDpRecords; record++) {
759 if (this->m_currentNode ==
nullptr) {
761 if (this->m_currStackEntry < 0) {
766 this->m_currentNode = this->m_traverseStack[this->m_currStackEntry--];
768 found = this->m_currentNode;
770 this->m_currentNode = this->m_currentNode->right;
771 if (found !=
nullptr) {
777 if (this->m_currentNode->left !=
nullptr) {
779 this->m_traverseStack[++this->m_currStackEntry] = this->m_currentNode;
780 this->m_currentNode = this->m_currentNode->left;
785 found = this->m_currentNode;
788 this->m_currentNode = this->m_currentNode->right;
790 if (found !=
nullptr) {
800 bool DpCatalog::checkInit() {
801 if (not this->m_initialized) {
805 else if (0 == this->m_numDpSlots) {
817 if ((this->m_allocator !=
nullptr) and (this->m_memPtr !=
nullptr)) {
818 this->m_allocator->
deallocate(this->m_allocatorId, this->m_memPtr);
841 this->m_xmitInProgress =
false;
850 this->appendFileState(this->m_currentXmitNode->entry);
852 this->m_xmitBytes += this->m_currentXmitNode->entry.record.getsize();
854 this->sendNextEntry();
872 BUILD_CATALOG_cmdHandler(
883 START_XMIT_CATALOG_cmdHandler(
897 this->m_xmitCmdWait =
false;
898 this->m_xmitOpCode = 0;
899 this->m_xmitCmdSeq = 0;
902 this->m_xmitCmdWait =
true;
903 this->m_xmitOpCode = opCode;
904 this->m_xmitCmdSeq = cmdSeq;
913 if (not this->checkInit()) {
919 if (0 == this->m_numDpSlots) {
925 if (this->m_xmitInProgress) {
931 this->m_xmitBytes = 0;
940 this->resetTreeStack();
941 this->m_xmitInProgress =
true;
943 this->sendNextEntry();
948 void DpCatalog::resetTreeStack() {
951 this->m_currStackEntry = -1;
953 this->m_currentNode = this->m_dpTree;
957 STOP_XMIT_CATALOG_cmdHandler(
962 if (not this->m_xmitInProgress) {
972 CLEAR_CATALOG_cmdHandler(
PlatformUIntType NATIVE_UINT_TYPE
void log_WARNING_HI_DpCatalogFull(Svc::DpRecord dp)
Serialization/Deserialization operation was successful.
A data product Container.
Status readDirectory(Fw::String filenameArray[], const FwSizeType arraySize, FwSizeType &filenameCount)
Read the contents of the directory and store filenames in filenameArray of size arraySize.
FwDpPriorityType getPriority() const
void log_WARNING_HI_StateFileTruncated(const Fw::StringBase &file, I32 offset, I32 size) const
Log event StateFileTruncated.
void log_WARNING_HI_ComponentNoMemory()
void log_WARNING_HI_DirectoryOpenError(const Fw::StringBase &loc, I32 stat) const
void log_WARNING_HI_DpFileXmitError(const Fw::StringBase &file, Svc::SendFileStatus stat)
Log event DpFileXmitError.
void log_WARNING_HI_DpInsertError(Svc::DpRecord dp)
Auto-generated base for DpCatalog component.
FwSignedSizeType substring_find(const CHAR *source_string, FwSizeType source_size, const CHAR *sub_string, FwSizeType sub_size)
find the first occurrence of a substring
Wait or don't wait for something.
void log_WARNING_HI_NotInitialized() const
Log event NotInitialized.
static constexpr FwSizeType MIN_PACKET_SIZE
const char * toChar() const
Status read(U8 *buffer, FwSignedSizeType &size)
read data from this file into supplied buffer bounded by size
PlatformIntType NATIVE_INT_TYPE
virtual void * allocate(const NATIVE_UINT_TYPE identifier, NATIVE_UINT_TYPE &size, bool &recoverable)=0
Allocate memory.
PlatformSizeType FwSizeType
Overwrite file when it exists and creation was requested.
The size of the serial representation.
void log_WARNING_HI_StateFileOpenError(const Fw::StringBase &file, I32 stat) const
Log event StateFileOpenError.
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
void configure(Fw::FileNameString directories[DP_MAX_DIRECTORIES], FwSizeType numDirs, Fw::FileNameString &stateFile, NATIVE_UINT_TYPE memId, Fw::MemAllocator &allocator)
Configure the DpCatalog.
Enum representing a command response.
void log_WARNING_HI_DpFileSendError(const Fw::StringBase &file, Svc::SendFileStatus stat)
Log event DpFileSendError.
PlatformIndexType FwIndexType
void setBuffer(const Buffer &buffer)
Set the packet buffer.
void log_ACTIVITY_HI_CatalogBuildComplete() const
static const FwSizeType DP_MAX_FILES
void log_WARNING_LO_DpXmitInProgress()
constexpr const char * DP_FILENAME_FORMAT
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
SerializeStatus
forward declaration for string
void log_WARNING_HI_FileOpenError(const Fw::StringBase &loc, I32 stat)
void log_WARNING_HI_NoDpMemory() const
Log event NoDpMemory.
void log_WARNING_HI_FileSizeError(const Fw::StringBase &file, I32 stat)
Svc::SendFileStatus::T getstatus() const
Get member status.
void log_WARNING_HI_FileReadError(const Fw::StringBase &file, I32 stat)
const char * toChar() const
void log_ACTIVITY_LO_ProcessingDirectory(const Fw::StringBase &directory) const
void log_ACTIVITY_HI_ProcessingDirectoryComplete(const Fw::StringBase &loc, U32 total, U32 pending, U64 pending_bytes) const
void log_ACTIVITY_LO_SendingProduct(const Fw::StringBase &file, U32 bytes, U32 prio) const
void log_WARNING_LO_NoStateFileSpecified() const
Log event NoStateFileSpecified.
External serialize buffer with no copy semantics.
void log_WARNING_HI_ComponentNotInitialized()
virtual void deallocate(const NATIVE_UINT_TYPE identifier, void *ptr)=0
Deallocate memory.
Fw::Time getTimeTag() const
Svc::SendFileResponse fileOut_out(FwIndexType portNum, const Fw::StringBase &sourceFileName, const Fw::StringBase &destFileName, U32 offset, U32 length)
Invoke output port fileOut.
SizeType length() const
Get length of string.
void close() override
close the file, if not opened then do nothing
void log_WARNING_LO_XmitNotActive() const
Log event XmitNotActive.
void log_ACTIVITY_HI_CatalogXmitCompleted(U64 bytes) const
void log_ACTIVITY_LO_ProcessingFile(const Fw::StringBase &file) const
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Command successfully executed.
C++-compatible configuration header for fprime configuration.
uint8_t U8
8-bit unsigned integer
DpCatalog(const char *const compName)
DpCatalog constructor.
~DpCatalog()
DpCatalog destructor.
Command had execution error.
void log_WARNING_HI_StateFileReadError(const Fw::StringBase &file, I32 stat, I32 offset) const
Log event StateFileReadError.
Fw::DpState getState() const
Get the product state.
void pingOut_out(FwIndexType portNum, U32 key)
Invoke output port pingOut.
void log_WARNING_HI_CatalogFull(const Fw::StringBase &dir)
Operation was successful.
void log_ACTIVITY_LO_ProductComplete(const Fw::StringBase &file) const
void log_WARNING_HI_FileHdrDesError(const Fw::StringBase &file, I32 stat)
Operation was successful.
Send file response struct.
Status open(const char *path, OpenMode mode) override
Open or create a directory.
PlatformSignedSizeType FwSignedSizeType
static Status getFileSize(const char *path, FwSignedSizeType &size)
Get the size of the file (in bytes) at the specified path.
Fw::SerializeStatus deserializeHeader()
Operation was successful.
PlatformUIntType FwNativeUIntType
Status write(const U8 *buffer, FwSignedSizeType &size)
write data to this file from the supplied buffer bounded by size
void log_WARNING_HI_StateFileWriteError(const Fw::StringBase &file, I32 stat) const
Log event StateFileWriteError.
static const FwSizeType DP_MAX_DIRECTORIES
FwSizeType string_length(const CHAR *source, FwSizeType buffer_size)
get the length of the source string
Open file for writing and truncates file if it exists, ie same flags as creat()