MUSX Document Model
Loading...
Searching...
No Matches
HeaderFactory.h
1/*
2 * Copyright (C) 2025, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#include <memory>
25#include <stdexcept>
26
27#include "musx/factory/FactoryBase.h"
28#include "musx/dom/Header.h"
29#include "musx/xml/XmlInterface.h"
30
31namespace musx {
32namespace factory {
33
38{
39public:
48 {
49 auto headerDataElement = getFirstChildElement(element, "headerData");
50 if (!headerDataElement) {
51 throw std::invalid_argument("Missing <headerData> element.");
52 }
53
54 auto header = std::make_shared<dom::header::Header>();
55 getFieldFromXml(headerDataElement, "wordOrder", header->wordOrder, parseWordOrder);
56 getFieldFromXml(headerDataElement, "textEncoding", header->textEncoding, parseTextEncoding);
57 getFieldFromXml(headerDataElement, "created", header->created, parseFileInfo);
58 getFieldFromXml(headerDataElement, "modified", header->modified, parseFileInfo);
59
60 return header;
61 }
62
63private:
71 static musx::dom::header::WordOrder parseWordOrder(const XmlElementPtr& element)
72 {
73 std::string value = element->getText();
74 if (value == "lo-endian") return musx::dom::header::WordOrder::LittleEndian;
75 if (value == "hi-endian") return musx::dom::header::WordOrder::BigEndian;
76 throw std::invalid_argument("Invalid word order value: " + value);
77 }
78
85 static musx::dom::header::TextEncoding parseTextEncoding(const XmlElementPtr& element)
86 {
87 std::string value = element->getText();
88 if (value == "Mac") return musx::dom::header::TextEncoding::Mac;
89 if (value == "Windows") return musx::dom::header::TextEncoding::Windows;
91 }
92
99 static musx::dom::header::Platform parsePlatform(const XmlElementPtr& element)
100 {
101 std::string value = element->getText();
102 if (value == "MAC") return musx::dom::header::Platform::Mac;
103 if (value == "WIN") return musx::dom::header::Platform::Windows;
105 }
106
113 static musx::dom::header::FileInfo parseFileInfo(const XmlElementPtr& element)
114 {
116 getFieldFromXml(element, "year", fileInfo.year, [](auto element) { return element->template getTextAs<int>(); });
117 getFieldFromXml(element, "month", fileInfo.month, [](auto element) { return element->template getTextAs<int>(); });
118 getFieldFromXml(element, "day", fileInfo.day, [](auto element) { return element->template getTextAs<int>(); });
119 getFieldFromXml(element, "modifiedBy", fileInfo.modifiedBy, [](auto element) { return element->getText(); });
120 getFieldFromXml(element, "enigmaVersion", fileInfo.finaleVersion, parseFinaleVersion);
121 getFieldFromXml(element, "application", fileInfo.application, [](auto element) { return element->getText(); });
122 getFieldFromXml(element, "platform", fileInfo.platform, parsePlatform);
123 getFieldFromXml(element, "appVersion", fileInfo.appVersion, parseFinaleVersion);
124 getFieldFromXml(element, "fileVersion", fileInfo.fileVersion, parseFinaleVersion);
125 getFieldFromXml(element, "appRegion", fileInfo.appRegion, [](auto element) { return element->getText(); });
126
127 return fileInfo;
128 }
129
137 static musx::dom::header::FinaleVersion parseFinaleVersion(const XmlElementPtr& element) {
138 if (!element) {
139 throw std::runtime_error("Missing version element.");
140 }
141
143 getFieldFromXml(element, "major", version.major, [](auto element) { return element->template getTextAs<int>(); });
144 getFieldFromXml(element, "minor", version.minor, [](auto element) { return element->template getTextAs<int>(); });
145 version.maint = getOptionalChildTextAs<int>(element, "maint");
146 getFieldFromXml(element, "devStatus", version.devStatus, [](auto element) { return element->getText(); });
147 version.build = getOptionalChildTextAs<int>(element, "build");
148
149 return version;
150 }
151};
152
153} // namespace factory
154} // namespace musx
Factory base class.
Definition FactoryBase.h:132
static void getFieldFromXml(const XmlElementPtr &element, const std::string &nodeName, DataType &dataField, ParserFunc parserFunc, bool expected=false)
Helper function to check if a child exists and populate it if so.
Definition FactoryBase.h:145
static XmlElementPtr getFirstChildElement(const XmlElementPtr &element, const std::string &childElementName)
Helper function to throw when child element does not exist.
Definition FactoryBase.h:160
Factory class for creating Header objects from XML.
Definition HeaderFactory.h:38
static musx::dom::header::HeaderPtr create(const XmlElementPtr &element)
Creates a Header object from an XML element.
Definition HeaderFactory.h:47
TextEncoding
Enum representing the text encoding used in the document.
Definition Header.h:49
@ Other
Other/unknown text encoding.
@ Windows
Windows text encoding.
WordOrder
Enum representing the word order used in the document.
Definition Header.h:40
@ BigEndian
Big-endian word order.
@ LittleEndian
Little-endian word order.
Platform
Enum representing the platform on which the document was created.
Definition Header.h:59
@ Other
Other/unknown platform.
@ Windows
Windows platform.
std::shared_ptr< Header > HeaderPtr
Shared Header pointer.
Definition Header.h:106
std::shared_ptr< IXmlElement > XmlElementPtr
shared pointer to IXmlElement
Definition XmlInterface.h:121
object model for musx file (enigmaxml)
Definition BaseClasses.h:32
Struct representing a date with associated metadata.
Definition Header.h:81
int year
Year (4 digits)
Definition Header.h:82
std::string modifiedBy
Initials of person who modified the file (often blank)
Definition Header.h:85
FinaleVersion fileVersion
Version of the file format.
Definition Header.h:90
Platform platform
Platform on which the file was created.
Definition Header.h:88
std::string appRegion
Region information (e.g., "US")
Definition Header.h:91
int month
Month (1-12)
Definition Header.h:83
FinaleVersion appVersion
Version of the application.
Definition Header.h:89
int day
Day (1-31)
Definition Header.h:84
FinaleVersion finaleVersion
Version of the Finale software.
Definition Header.h:86
std::string application
Application that created or modified the file.
Definition Header.h:87
Struct representing version information.
Definition Header.h:69
int minor
Minor version number.
Definition Header.h:71
int major
Major version number.
Definition Header.h:70
std::string devStatus
Development status (e.g., "dev", "release")
Definition Header.h:73
std::optional< int > build
Optional build number.
Definition Header.h:74
std::optional< int > maint
Optional maintenance version number.
Definition Header.h:72