#pragma once #include #include #include "MemorySegmentSection.hpp" #include "src/Services/StringService.hpp" #include "Exceptions/InvalidTargetDescriptionDataException.hpp" namespace Targets::TargetDescription { enum class MemorySegmentType: std::uint8_t { ALIASED, REGISTERS, EEPROM, FLASH, FUSES, IO, RAM, LOCKBITS, OSCCAL, PRODUCTION_SIGNATURES, SIGNATURES, USER_SIGNATURES, }; struct MemorySegment { std::string key; std::string name; MemorySegmentType type; std::uint32_t startAddress; std::uint32_t size; std::optional pageSize; std::map> sectionsByKey; MemorySegment( const std::string& key, const std::string& name, MemorySegmentType type, std::uint32_t startAddress, std::uint32_t size, const std::optional& pageSize, const std::map>& sectionsByKey ) : key(key) , name(name) , type(type) , startAddress(startAddress) , size(size) , pageSize(pageSize) , sectionsByKey(sectionsByKey) {} std::optional> tryGetSection( std::string_view keyStr ) const { const auto keys = Services::StringService::split(keyStr, '.'); const auto firstSubgroupIt = this->sectionsByKey.find(*keys.begin()); return firstSubgroupIt != this->sectionsByKey.end() ? keys.size() > 1 ? firstSubgroupIt->second.tryGetSubSection(keys | std::ranges::views::drop(1)) : std::optional(std::cref(firstSubgroupIt->second)) : std::nullopt; } const MemorySegmentSection& getSection(std::string_view keyStr) const { const auto propertyGroup = this->tryGetSection(keyStr); if (!propertyGroup.has_value()) { throw Exceptions::InvalidTargetDescriptionDataException( "Failed to get memory segment section \"" + std::string(keyStr) + "\" from memory segment in TDF - section not found" ); } return propertyGroup->get(); } }; }