Moved memory region JSON conversion to individual constructors/member functions

This commit is contained in:
Nav
2022-12-19 14:04:34 +00:00
parent c2201548e9
commit fc883d5d1e
11 changed files with 205 additions and 154 deletions

View File

@@ -0,0 +1,26 @@
#pragma once
#include <QString>
#include "BiMap.hpp"
#include "src/Targets/TargetMemory.hpp"
namespace Bloom
{
class EnumToStringMappings
{
public:
static const inline BiMap<Targets::TargetMemoryType, QString> targetMemoryTypes = {
{Targets::TargetMemoryType::RAM, "ram"},
{Targets::TargetMemoryType::EEPROM, "eeprom"},
{Targets::TargetMemoryType::FLASH, "flash"},
{Targets::TargetMemoryType::OTHER, "other"},
};
static const inline BiMap<Targets::TargetMemoryEndianness, QString> targetMemoryEndianness = {
{Targets::TargetMemoryEndianness::LITTLE, "little"},
{Targets::TargetMemoryEndianness::BIG, "big"},
};
};
}

View File

@@ -75,6 +75,9 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteAddressItem.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteAddressItem.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/AnnotationItem.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/AnnotationItem.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ValueAnnotationItem.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ValueAnnotationItem.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.cpp
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/ExcludedMemoryRegion.cpp
# Memory region manager window # Memory region manager window
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp

View File

@@ -0,0 +1,22 @@
#include "ExcludedMemoryRegion.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Bloom
{
ExcludedMemoryRegion::ExcludedMemoryRegion(
const QString& name,
Targets::TargetMemoryType memoryType,
const Targets::TargetMemoryAddressRange& addressRange
)
: MemoryRegion(name, memoryType, MemoryRegionType::EXCLUDED, addressRange)
{}
ExcludedMemoryRegion::ExcludedMemoryRegion(const QJsonObject& jsonObject)
: MemoryRegion(jsonObject)
{
if (this->type != MemoryRegionType::EXCLUDED) {
throw Exceptions::Exception("Invalid memory region type");
}
}
}

View File

@@ -7,9 +7,12 @@ namespace Bloom
class ExcludedMemoryRegion: public MemoryRegion class ExcludedMemoryRegion: public MemoryRegion
{ {
public: public:
explicit ExcludedMemoryRegion( ExcludedMemoryRegion(
const QString& name, const QString& name,
Targets::TargetMemoryType memoryType,
const Targets::TargetMemoryAddressRange& addressRange const Targets::TargetMemoryAddressRange& addressRange
): MemoryRegion(name, MemoryRegionType::EXCLUDED, addressRange) {}; );
ExcludedMemoryRegion(const QJsonObject& jsonObject);
}; };
} }

View File

@@ -0,0 +1,22 @@
#include "FocusedMemoryRegion.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Bloom
{
FocusedMemoryRegion::FocusedMemoryRegion(
const QString& name,
Targets::TargetMemoryType memoryType,
const Targets::TargetMemoryAddressRange& addressRange
)
: MemoryRegion(name, memoryType, MemoryRegionType::FOCUSED, addressRange)
{}
FocusedMemoryRegion::FocusedMemoryRegion(const QJsonObject& jsonObject)
: MemoryRegion(jsonObject)
{
if (this->type != MemoryRegionType::FOCUSED) {
throw Exceptions::Exception("Invalid memory region type");
}
}
}

View File

@@ -20,9 +20,12 @@ namespace Bloom
MemoryRegionDataType dataType = MemoryRegionDataType::UNKNOWN; MemoryRegionDataType dataType = MemoryRegionDataType::UNKNOWN;
Targets::TargetMemoryEndianness endianness = Targets::TargetMemoryEndianness::LITTLE; Targets::TargetMemoryEndianness endianness = Targets::TargetMemoryEndianness::LITTLE;
explicit FocusedMemoryRegion( FocusedMemoryRegion(
const QString& name, const QString& name,
Targets::TargetMemoryType memoryType,
const Targets::TargetMemoryAddressRange& addressRange const Targets::TargetMemoryAddressRange& addressRange
): MemoryRegion(name, MemoryRegionType::FOCUSED, addressRange) {}; );
FocusedMemoryRegion(const QJsonObject& jsonObject);
}; };
} }

View File

@@ -0,0 +1,67 @@
#include "MemoryRegion.hpp"
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Bloom
{
MemoryRegion::MemoryRegion(
const QString& name,
Targets::TargetMemoryType memoryType,
MemoryRegionType type,
const Targets::TargetMemoryAddressRange& addressRange
)
: name(name)
, memoryType(memoryType)
, type(type)
, addressRange(addressRange)
{}
MemoryRegion::MemoryRegion(const QJsonObject& jsonObject) {
using Exceptions::Exception;
if (
!jsonObject.contains("name")
|| !jsonObject.contains("memoryType")
|| !jsonObject.contains("type")
|| !jsonObject.contains("createdTimestamp")
|| !jsonObject.contains("addressInputType")
|| !jsonObject.contains("addressRange")
) {
throw Exception("Missing data");
}
const auto addressRangeObj = jsonObject.find("addressRange")->toObject();
if (
!addressRangeObj.contains("startAddress")
|| !addressRangeObj.contains("endAddress")
) {
throw Exception("Missing address range data");
}
this->name = jsonObject.find("name")->toString();
this->memoryType = EnumToStringMappings::targetMemoryTypes.at(jsonObject.find("memoryType")->toString());
this->type = MemoryRegion::memoryRegionTypesByName.at(jsonObject.find("type")->toString());
this->createdDate.setSecsSinceEpoch(jsonObject.find("createdTimestamp")->toInteger());
this->addressRangeInputType = MemoryRegion::addressTypesByName.at(jsonObject.find("addressInputType")->toString());
this->addressRange = {
static_cast<std::uint32_t>(addressRangeObj.find("startAddress")->toInteger()),
static_cast<std::uint32_t>(addressRangeObj.find("endAddress")->toInteger()),
};
}
QJsonObject MemoryRegion::toJson() const {
return QJsonObject({
{"name", this->name},
{"memoryType", EnumToStringMappings::targetMemoryTypes.at(this->memoryType)},
{"type", MemoryRegion::memoryRegionTypesByName.at(this->type)},
{"createdTimestamp", this->createdDate.toSecsSinceEpoch()},
{"addressInputType", MemoryRegion::addressTypesByName.at(this->addressRangeInputType)},
{"addressRange", QJsonObject({
{"startAddress", static_cast<qint64>(this->addressRange.startAddress)},
{"endAddress", static_cast<qint64>(this->addressRange.endAddress)},
})},
});
}
}

View File

@@ -3,10 +3,12 @@
#include <cstdint> #include <cstdint>
#include <atomic> #include <atomic>
#include <QString> #include <QString>
#include <QJsonObject>
#include <utility> #include <utility>
#include "src/Targets/TargetMemory.hpp" #include "src/Targets/TargetMemory.hpp"
#include "src/Helpers/DateTime.hpp" #include "src/Helpers/DateTime.hpp"
#include "src/Helpers/BiMap.hpp"
#include "AddressType.hpp" #include "AddressType.hpp"
namespace Bloom namespace Bloom
@@ -28,6 +30,7 @@ namespace Bloom
public: public:
QString name; QString name;
QDateTime createdDate = DateTime::currentDateTime(); QDateTime createdDate = DateTime::currentDateTime();
Targets::TargetMemoryType memoryType;
MemoryRegionType type; MemoryRegionType type;
/** /**
@@ -50,10 +53,15 @@ namespace Bloom
Targets::TargetMemoryAddressRange addressRange; Targets::TargetMemoryAddressRange addressRange;
MemoryRegion( MemoryRegion(
QString name, const QString& name,
Targets::TargetMemoryType memoryType,
MemoryRegionType type, MemoryRegionType type,
const Targets::TargetMemoryAddressRange& addressRange const Targets::TargetMemoryAddressRange& addressRange
): name(std::move(name)), type(type), addressRange(addressRange) {}; );
MemoryRegion(const QJsonObject& jsonObject);
virtual QJsonObject toJson() const;
virtual ~MemoryRegion() = default; virtual ~MemoryRegion() = default;
@@ -66,5 +74,16 @@ namespace Bloom
[[nodiscard]] bool intersectsWith(const MemoryRegion& other) const { [[nodiscard]] bool intersectsWith(const MemoryRegion& other) const {
return this->addressRange.intersectsWith(other.addressRange); return this->addressRange.intersectsWith(other.addressRange);
} }
private:
static const inline BiMap<MemoryRegionType, QString> memoryRegionTypesByName = {
{MemoryRegionType::EXCLUDED, "excluded"},
{MemoryRegionType::FOCUSED, "focused"},
};
static const inline BiMap<AddressType, QString> addressTypesByName = {
{AddressType::ABSOLUTE, "absolute"},
{AddressType::RELATIVE, "relative"},
};
}; };
} }

View File

@@ -249,6 +249,7 @@ namespace Bloom::Widgets
auto* region = this->addFocusedRegion(FocusedMemoryRegion( auto* region = this->addFocusedRegion(FocusedMemoryRegion(
"Untitled Region", "Untitled Region",
this->memoryDescriptor.type,
TargetMemoryAddressRange( TargetMemoryAddressRange(
this->memoryDescriptor.addressRange.startAddress, this->memoryDescriptor.addressRange.startAddress,
this->memoryDescriptor.addressRange.startAddress + 10 this->memoryDescriptor.addressRange.startAddress + 10
@@ -263,6 +264,7 @@ namespace Bloom::Widgets
auto* region = this->addExcludedRegion(ExcludedMemoryRegion( auto* region = this->addExcludedRegion(ExcludedMemoryRegion(
"Untitled Region", "Untitled Region",
this->memoryDescriptor.type,
TargetMemoryAddressRange( TargetMemoryAddressRange(
this->memoryDescriptor.addressRange.startAddress, this->memoryDescriptor.addressRange.startAddress,
this->memoryDescriptor.addressRange.startAddress + 10 this->memoryDescriptor.addressRange.startAddress + 10

View File

@@ -2,6 +2,10 @@
#include <QJsonArray> #include <QJsonArray>
#include "src/Helpers/EnumToStringMappings.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
namespace Bloom namespace Bloom
{ {
ProjectSettings::ProjectSettings(const QJsonObject& jsonObject) { ProjectSettings::ProjectSettings(const QJsonObject& jsonObject) {
@@ -67,12 +71,12 @@ namespace Bloom
const auto settingsObj = settingsIt.value().toObject(); const auto settingsObj = settingsIt.value().toObject();
const auto memoryTypeName = settingsIt.key(); const auto memoryTypeName = settingsIt.key();
if (!InsightProjectSettings::memoryTypesByName.contains(memoryTypeName)) { if (!EnumToStringMappings::targetMemoryTypes.contains(memoryTypeName)) {
continue; continue;
} }
this->memoryInspectionPaneSettingsByMemoryType.insert(std::pair( this->memoryInspectionPaneSettingsByMemoryType.insert(std::pair(
InsightProjectSettings::memoryTypesByName.at(memoryTypeName), EnumToStringMappings::targetMemoryTypes.at(memoryTypeName),
this->memoryInspectionPaneSettingsFromJson(settingsObj) this->memoryInspectionPaneSettingsFromJson(settingsObj)
)); ));
} }
@@ -92,13 +96,13 @@ namespace Bloom
auto memoryInspectionPaneSettingsObj = QJsonObject(); auto memoryInspectionPaneSettingsObj = QJsonObject();
for (const auto& [memoryType, inspectionPaneSettings] : this->memoryInspectionPaneSettingsByMemoryType) { for (const auto& [memoryType, inspectionPaneSettings] : this->memoryInspectionPaneSettingsByMemoryType) {
if (!InsightProjectSettings::memoryTypesByName.contains(memoryType)) { if (!EnumToStringMappings::targetMemoryTypes.contains(memoryType)) {
// This is just a precaution - all known memory types should be in the mapping. // This is just a precaution - all known memory types should be in the mapping.
continue; continue;
} }
memoryInspectionPaneSettingsObj.insert( memoryInspectionPaneSettingsObj.insert(
InsightProjectSettings::memoryTypesByName.at(memoryType), EnumToStringMappings::targetMemoryTypes.at(memoryType),
this->memoryInspectionPaneSettingsToJson(inspectionPaneSettings) this->memoryInspectionPaneSettingsToJson(inspectionPaneSettings)
); );
} }
@@ -146,6 +150,8 @@ namespace Bloom
Widgets::TargetMemoryInspectionPaneSettings InsightProjectSettings::memoryInspectionPaneSettingsFromJson( Widgets::TargetMemoryInspectionPaneSettings InsightProjectSettings::memoryInspectionPaneSettingsFromJson(
const QJsonObject& jsonObject const QJsonObject& jsonObject
) const { ) const {
using Exceptions::Exception;
auto inspectionPaneSettings = Widgets::TargetMemoryInspectionPaneSettings(); auto inspectionPaneSettings = Widgets::TargetMemoryInspectionPaneSettings();
if (jsonObject.contains("refreshOnTargetStop")) { if (jsonObject.contains("refreshOnTargetStop")) {
@@ -193,105 +199,34 @@ namespace Bloom
} }
if (jsonObject.contains("focusedRegions")) { if (jsonObject.contains("focusedRegions")) {
const auto focusedRegions = jsonObject.find("focusedRegions")->toArray(); for (const auto& regionValue : jsonObject.find("focusedRegions")->toArray()) {
try {
inspectionPaneSettings.focusedMemoryRegions.push_back(
FocusedMemoryRegion(regionValue.toObject())
);
for (const auto& regionValue : focusedRegions) { } catch (Exception exception) {
const auto regionObj = regionValue.toObject(); Logger::warning(
"Failed to parse focused memory region from project settings file - "
if (!regionObj.contains("name") + exception.getMessage() + " - region will be ignored."
|| !regionObj.contains("addressRange") );
|| !regionObj.contains("addressInputType")
|| !regionObj.contains("createdTimestamp")
|| !regionObj.contains("dataType")
) {
continue;
} }
const auto addressRangeObj = regionObj.find("addressRange")->toObject();
if (!addressRangeObj.contains("startAddress")
|| !addressRangeObj.contains("endAddress")
) {
continue;
}
auto region = FocusedMemoryRegion(
regionObj.find("name")->toString(),
{
static_cast<std::uint32_t>(addressRangeObj.find("startAddress")->toInteger()),
static_cast<std::uint32_t>(addressRangeObj.find("endAddress")->toInteger()),
}
);
region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger());
const auto addressInputType = InsightProjectSettings::addressTypesByName.valueAt(
regionObj.find("addressInputType")->toString()
);
if (addressInputType.has_value()) {
region.addressRangeInputType = addressInputType.value();
}
const auto dataType = InsightProjectSettings::regionDataTypesByName.valueAt(
regionObj.find("dataType")->toString()
);
if (dataType.has_value()) {
region.dataType = dataType.value();
}
const auto endianness = InsightProjectSettings::regionEndiannessByName.valueAt(
regionObj.find("endianness")->toString()
);
if (endianness.has_value()) {
region.endianness = endianness.value();
}
inspectionPaneSettings.focusedMemoryRegions.emplace_back(region);
} }
} }
if (jsonObject.contains("excludedRegions")) { if (jsonObject.contains("excludedRegions")) {
const auto excludedRegions = jsonObject.find("excludedRegions")->toArray(); for (const auto& regionValue : jsonObject.find("excludedRegions")->toArray()) {
try {
inspectionPaneSettings.excludedMemoryRegions.emplace_back(
ExcludedMemoryRegion(regionValue.toObject())
);
for (const auto& regionValue : excludedRegions) { } catch (Exception exception) {
const auto regionObj = regionValue.toObject(); Logger::warning(
"Failed to parse excluded memory region from project settings file - "
if (!regionObj.contains("name") + exception.getMessage() + " - region will be ignored."
|| !regionObj.contains("addressRange") );
|| !regionObj.contains("addressInputType")
|| !regionObj.contains("createdTimestamp")
) {
continue;
} }
const auto addressRangeObj = regionObj.find("addressRange")->toObject();
if (!addressRangeObj.contains("startAddress")
|| !addressRangeObj.contains("endAddress")
) {
continue;
}
auto region = ExcludedMemoryRegion(
regionObj.find("name")->toString(),
{
static_cast<std::uint32_t>(addressRangeObj.find("startAddress")->toInteger()),
static_cast<std::uint32_t>(addressRangeObj.find("endAddress")->toInteger()),
}
);
region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger());
const auto addressInputType = InsightProjectSettings::addressTypesByName.valueAt(
regionObj.find("addressInputType")->toString()
);
if (addressInputType.has_value()) {
region.addressRangeInputType = addressInputType.value();
}
inspectionPaneSettings.excludedMemoryRegions.emplace_back(region);
} }
} }
@@ -340,8 +275,6 @@ namespace Bloom
QJsonObject InsightProjectSettings::memoryInspectionPaneSettingsToJson( QJsonObject InsightProjectSettings::memoryInspectionPaneSettingsToJson(
const Widgets::TargetMemoryInspectionPaneSettings& inspectionPaneSettings const Widgets::TargetMemoryInspectionPaneSettings& inspectionPaneSettings
) const { ) const {
const auto& regionDataTypesByName = InsightProjectSettings::regionDataTypesByName;
const auto& regionEndiannessByName = InsightProjectSettings::regionEndiannessByName;
const auto& addressTypesByName = InsightProjectSettings::addressTypesByName; const auto& addressTypesByName = InsightProjectSettings::addressTypesByName;
auto settingsObj = QJsonObject({ auto settingsObj = QJsonObject({
@@ -361,49 +294,12 @@ namespace Bloom
auto focusedRegions = QJsonArray(); auto focusedRegions = QJsonArray();
for (const auto& focusedRegion : inspectionPaneSettings.focusedMemoryRegions) { for (const auto& focusedRegion : inspectionPaneSettings.focusedMemoryRegions) {
if (!regionDataTypesByName.contains(focusedRegion.dataType) focusedRegions.push_back(focusedRegion.toJson());
|| !regionEndiannessByName.contains(focusedRegion.endianness)
|| !addressTypesByName.contains(focusedRegion.addressRangeInputType)
) {
continue;
}
const auto addressRangeObj = QJsonObject({
{"startAddress", static_cast<qint64>(focusedRegion.addressRange.startAddress)},
{"endAddress", static_cast<qint64>(focusedRegion.addressRange.endAddress)},
});
auto regionObj = QJsonObject({
{"name", focusedRegion.name},
{"addressRange", addressRangeObj},
{"createdTimestamp", focusedRegion.createdDate.toSecsSinceEpoch()},
{"addressInputType", addressTypesByName.at(focusedRegion.addressRangeInputType)},
{"dataType", regionDataTypesByName.at(focusedRegion.dataType)},
{"endianness", regionEndiannessByName.at(focusedRegion.endianness)},
});
focusedRegions.push_back(regionObj);
} }
auto excludedRegions = QJsonArray(); auto excludedRegions = QJsonArray();
for (const auto& excludedRegion : inspectionPaneSettings.excludedMemoryRegions) { for (const auto& excludedRegion : inspectionPaneSettings.excludedMemoryRegions) {
if (!addressTypesByName.contains(excludedRegion.addressRangeInputType)) { excludedRegions.push_back(excludedRegion.toJson());
continue;
}
const auto addressRangeObj = QJsonObject({
{"startAddress", static_cast<qint64>(excludedRegion.addressRange.startAddress)},
{"endAddress", static_cast<qint64>(excludedRegion.addressRange.endAddress)},
});
auto regionObj = QJsonObject({
{"name", excludedRegion.name},
{"addressRange", addressRangeObj},
{"createdTimestamp", excludedRegion.createdDate.toSecsSinceEpoch()},
{"addressInputType", addressTypesByName.at(excludedRegion.addressRangeInputType)},
});
excludedRegions.push_back(regionObj);
} }
settingsObj.insert("focusedRegions", focusedRegions); settingsObj.insert("focusedRegions", focusedRegions);

View File

@@ -42,18 +42,6 @@ namespace Bloom
{Targets::TargetMemoryType::EEPROM, "eeprom"}, {Targets::TargetMemoryType::EEPROM, "eeprom"},
}; };
static const inline BiMap<MemoryRegionDataType, QString> regionDataTypesByName = {
{MemoryRegionDataType::UNKNOWN, "other"},
{MemoryRegionDataType::UNSIGNED_INTEGER, "unsigned_int"},
{MemoryRegionDataType::SIGNED_INTEGER, "signed_int"},
{MemoryRegionDataType::ASCII_STRING, "ascii_string"},
};
static const inline BiMap<Targets::TargetMemoryEndianness, QString> regionEndiannessByName = {
{Targets::TargetMemoryEndianness::LITTLE, "little"},
{Targets::TargetMemoryEndianness::BIG, "big"},
};
static const inline BiMap<AddressType, QString> addressTypesByName = { static const inline BiMap<AddressType, QString> addressTypesByName = {
{AddressType::ABSOLUTE, "absolute"}, {AddressType::ABSOLUTE, "absolute"},
{AddressType::RELATIVE, "relative"}, {AddressType::RELATIVE, "relative"},