24#include "musx/xml/XmlInterface.h"
25#include "musx/dom/BaseClasses.h"
26#include "musx/dom/ObjectPool.h"
27#include "musx/dom/Document.h"
28#include "FactoryBase.h"
29#include "TypeRegistry.h"
31#ifdef MUSX_DISPLAY_NODE_NAMES
49template<
typename DerivedType,
typename ObjectBase,
typename PoolType>
70 auto pool = std::make_shared<PoolType>(document);
72#ifdef MUSX_DISPLAY_NODE_NAMES
73 std::string currentTag;
74 size_t currentTagCount = 0;
80 for (
auto childElement = element->getFirstChildElement(); childElement; childElement = childElement->getNextSibling()) {
81 if (
auto instanceInfo = DerivedType::extractFromXml(childElement, document, elementLinker, pool)) {
82#ifdef MUSX_DISPLAY_NODE_NAMES
83 if (currentTag != childElement->getTagName()) {
84 if (!currentTag.empty()) {
87 currentTag = childElement->getTagName();
92 MUSX_ASSERT_IF(childElement->getTagName() != instanceInfo->xmlNodeName) {
93 throw std::logic_error(
"Instance of " + std::string(instanceInfo->xmlNodeName) +
" does not match xml tag " + element->getTagName());
95 auto typedPtr = std::dynamic_pointer_cast<ObjectBase>(instanceInfo->instance);
96 MUSX_ASSERT_IF(!typedPtr) {
97 throw std::logic_error(
"Unable to cast instance to correct type for " + std::string(instanceInfo->xmlNodeName));
99 if constexpr (std::is_same_v<PoolType, EntryPool>) {
100 pool->add(typedPtr->getEntryNumber(), typedPtr);
102 pool->add(instanceInfo->xmlNodeName, typedPtr);
107#ifdef MUSX_DISPLAY_NODE_NAMES
108 if (!currentTag.empty() && currentTagCount != 0) {
174 auto cmperAttribute = element->findAttribute(
"cmper");
175 if (!cmperAttribute) {
176 throw std::invalid_argument(
"missing cmper for others element " + element->getTagName());
178 auto inciAttribute = element->findAttribute(
"inci");
181 document, cmperAttribute->getValueAs<
dom::Cmper>(), inciAttribute->getValueAs<
dom::Inci>());
185 document, cmperAttribute->getValueAs<
dom::Cmper>());
217 std::optional<dom::Inci> inci;
218 if (
auto inciAttribute = element->findAttribute(
"inci")) {
219 inci = inciAttribute->getValueAs<
dom::Inci>();
221 if (
auto entnumAttribute = element->findAttribute(
"entnum")) {
222 if (inci.has_value()) {
230 auto cmper1Attribute = element->findAttribute(
"cmper1");
231 if (!cmper1Attribute) {
232 throw std::invalid_argument(
"missing cmper1 for details element " + element->getTagName());
234 auto cmper2Attribute = element->findAttribute(
"cmper2");
235 if (!cmper2Attribute) {
236 throw std::invalid_argument(
"missing cmper2 for details element " + element->getTagName());
238 if (inci.has_value()) {
240 document, cmper1Attribute->getValueAs<
dom::Cmper>(), cmper2Attribute->getValueAs<
dom::Cmper>(), inci.value());
243 document, cmper1Attribute->getValueAs<
dom::Cmper>(), cmper2Attribute->getValueAs<
dom::Cmper>());
273 auto entnumAttr = element->findAttribute(
"entnum");
275 throw std::invalid_argument(
"missing entum attribute for entry");
277 auto prevAttr = element->findAttribute(
"prev");
279 throw std::invalid_argument(
"missing prev attribute for entry");
281 auto nextAttr = element->findAttribute(
"next");
283 throw std::invalid_argument(
"missing next attribute for entry");
319 auto textAttributeName = [element]() -> std::string {
325 auto textAttribute = element->findAttribute(textAttributeName);
326 if (!textAttribute) {
327 throw std::invalid_argument(
"Element <" + element->getTagName() +
"> does not have attribute " + textAttributeName);
329 auto textNumber = [textAttribute]() ->
Cmper {
330 if (textAttribute->getName() ==
"type") {
331 return toCmper(textAttribute->getValue());
333 return textAttribute->getValueAs<
Cmper>();
339 static Cmper toCmper(
const std::string& type)
343 static const std::unordered_map<std::string_view, TextType> typeMap = {
344 {
"title", TextType::Title},
345 {
"composer", TextType::Composer},
346 {
"copyright", TextType::Copyright},
347 {
"description", TextType::Description},
348 {
"lyricist", TextType::Lyricist},
349 {
"arranger", TextType::Arranger},
350 {
"subtitle", TextType::Subtitle}
353 auto it = typeMap.find(type);
354 if (it != typeMap.end()) {
355 return Cmper(it->second);
358 throw std::invalid_argument(
"Unknown type attribute value for <fileInfo> node: " + type);
static constexpr std::string_view XmlNodeName
The XML node name for this type.
Definition Texts.h:114
TextType
Represents various text types for the file header.
Definition Texts.h:89
Factory class for creating Details objects from XML.
Definition PoolFactory.h:198
static auto extractFromXml(const XmlElementPtr &element, const dom::DocumentPtr &document, ElementLinker &elementLinker, const DetailsPoolPtr &pool)
Extracts an OthersBase object from an XML element.
Definition PoolFactory.h:215
A utility class for managing deferred relationships between elements during document construction.
Definition FactoryBase.h:71
Factory class for creating Entry objects from XML.
Definition PoolFactory.h:255
static auto extractFromXml(const XmlElementPtr &element, const dom::DocumentPtr &document, ElementLinker &elementLinker, const EntryPoolPtr &pool)
Extracts an Entry object from an XML element.
Definition PoolFactory.h:271
Factory base class.
Definition FactoryBase.h:133
Factory class for creating Options objects from XML.
Definition PoolFactory.h:125
static auto extractFromXml(const XmlElementPtr &element, const dom::DocumentPtr &document, ElementLinker &elementLinker, const OptionsPoolPtr &pool)
Extracts an OptionsBase object from an XML element.
Definition PoolFactory.h:141
Factory class for creating Others objects from XML.
Definition PoolFactory.h:155
static auto extractFromXml(const XmlElementPtr &element, const dom::DocumentPtr &document, ElementLinker &elementLinker, const OthersPoolPtr &pool)
Extracts an OthersBase object from an XML element.
Definition PoolFactory.h:172
Factory class for creating a dom::ObjectPool from XML.
Definition PoolFactory.h:51
static std::shared_ptr< PoolType > create(const XmlElementPtr &element, const dom::DocumentPtr &document, ElementLinker &elementLinker)
Creates a OthersPool object from an XML element.
Definition PoolFactory.h:68
Factory class for creating Texts objects from XML.
Definition PoolFactory.h:300
static auto extractFromXml(const XmlElementPtr &element, const dom::DocumentPtr &document, ElementLinker &elementLinker, const TextsPoolPtr &pool)
Extracts a TextsBase object from an XML element.
Definition PoolFactory.h:317
static std::optional< CreatedInstanceInfo > createInstance(const PoolPtr &pool, const XmlElementPtr &node, ElementLinker &elementLinker, const DocumentPtr &document, Args &&... args)
Creates an instance of the registered type corresponding to the provided node name.
Definition TypeRegistry.h:147
@ Verbose
Informational messages that should only displayed when verbose logging is requested.
static void log(LogLevel level, const std::string &message)
Logs a message with a specific severity level.
Definition Logger.h:87
std::shared_ptr< OthersPool > OthersPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:445
std::shared_ptr< DetailsPool > DetailsPoolPtr
Shared DetailsPool pointer.
Definition ObjectPool.h:532
int16_t Inci
Enigma "incident" key type.
Definition Fundamentals.h:56
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
std::shared_ptr< TextsPool > TextsPoolPtr
Shared OthersPool pointer.
Definition ObjectPool.h:604
std::shared_ptr< OptionsPool > OptionsPoolPtr
Shared OptionsPool pointer.
Definition ObjectPool.h:392
int32_t EntryNumber
Entry identifier.
Definition Fundamentals.h:69
std::shared_ptr< Document > DocumentPtr
Shared Document pointer.
Definition BaseClasses.h:55
std::shared_ptr< EntryPool > EntryPoolPtr
Shared EntryPool pointer.
Definition ObjectPool.h:565
std::shared_ptr< IXmlElement > XmlElementPtr
shared pointer to IXmlElement
Definition XmlInterface.h:121
object model for musx file (enigmaxml)
Definition BaseClasses.h:36