Update the unfinished payload data (DT) block. This function updates the channel group (CG) and a CG-VLSD channel group regarding cycle count and offsets (VLSD)
| 682 | // channel group (CG) and a CG-VLSD channel group regarding cycle count |
| 683 | // and offsets (VLSD) |
| 684 | bool Dg4Block::FinalizeCgAndVlsdBlocks(std::streambuf& buffer, bool update_cg, |
| 685 | bool update_vlsd) { |
| 686 | auto& block_list = DataBlockList(); |
| 687 | if (block_list.empty()) { |
| 688 | // No data blocks to update |
| 689 | MDF_DEBUG() << "No last data block to update."; |
| 690 | return true; |
| 691 | } |
| 692 | // It is the last DT block in the list that can be updated. If it isn't a DT |
| 693 | // block, we cannot finish the file. |
| 694 | auto* last_block = block_list.back().get(); |
| 695 | if (last_block == nullptr || last_block->BlockType() != "DT") { |
| 696 | MDF_DEBUG() << "Last data block is not a DT block."; |
| 697 | return true; |
| 698 | } |
| 699 | auto* dt_block = dynamic_cast<Dt4Block*>(last_block); |
| 700 | if (dt_block == nullptr) { |
| 701 | MDF_ERROR() << "Invalid DT block type-cast."; |
| 702 | return false; |
| 703 | } |
| 704 | // Create a simple map that speeds up the counting. |
| 705 | std::map<uint64_t, CgCounter> counter_list; |
| 706 | for (const auto& cg4 : Cg4()) { |
| 707 | if (!cg4) { |
| 708 | continue; |
| 709 | } |
| 710 | CgCounter counter; |
| 711 | counter.CgBlock = cg4.get(); |
| 712 | counter_list.emplace(cg4->RecordId(), counter); |
| 713 | } |
| 714 | if (counter_list.empty()) { |
| 715 | return true; // Nothing to update |
| 716 | } |
| 717 | |
| 718 | |
| 719 | SetFilePosition(buffer, dt_block->DataPosition()); |
| 720 | uint64_t count = 0; |
| 721 | while (count < dt_block->DataSize()) { |
| 722 | uint64_t record_id = 0; |
| 723 | count += ReadRecordId(buffer,record_id); |
| 724 | auto cg_find = counter_list.size() == 1 ? |
| 725 | counter_list.begin() : counter_list.find(record_id); |
| 726 | if (cg_find == counter_list.end()) { |
| 727 | MDF_DEBUG() << "Failed to find the CG block. Record ID: " << record_id; |
| 728 | break; |
| 729 | } |
| 730 | auto& counter = cg_find->second; |
| 731 | auto* cg_block = counter.CgBlock; |
| 732 | uint64_t count_bytes = 0; |
| 733 | if (cg_block == nullptr) { |
| 734 | MDF_ERROR() << "CG block pointer is null. Internal error."; |
| 735 | return false; |
| 736 | } |
| 737 | if ((cg_block->Flags() & CgFlag::VlsdChannel) != 0) { |
| 738 | // This is normally used for string, |
| 739 | // and the CG block only includes one signal |
| 740 | uint32_t length = 0; |
| 741 | count_bytes += ReadNumber(buffer, length); |
no test coverage detected