Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #ifndef MUSE_GLOBAL_XMLDOM_H
23 : #define MUSE_GLOBAL_XMLDOM_H
24 :
25 : #include <memory>
26 :
27 : #include "types/bytearray.h"
28 : #include "types/string.h"
29 :
30 : namespace muse {
31 : struct XmlDomImplData;
32 : // avoid external dependency on a particular xml library
33 : // Opaque, backend-agnostic handle storage (two machine words)
34 : using xml_handle_slot = std::uintptr_t;
35 :
36 : struct xml_handle {
37 : xml_handle_slot slot0 = 0;
38 : xml_handle_slot slot1 = 0;
39 259258 : explicit operator bool() const noexcept {
40 259258 : return !(slot0 == 0 && slot1 == 0);
41 : }
42 : };
43 : static_assert(std::is_trivially_copyable_v<xml_handle>,
44 : "Xml handle struct must be trivially copyable");
45 : using xml_node_handle = xml_handle;
46 : using xml_attr_handle = xml_handle;
47 :
48 : class XmlDomElement;
49 : class XmlDomAttribute;
50 : class XmlDomNode
51 : {
52 : public:
53 :
54 : XmlDomNode() = default;
55 :
56 : bool isNull() const;
57 : String nodeName() const;
58 :
59 : bool hasChildNodes() const;
60 : XmlDomNode firstChild() const;
61 : XmlDomElement firstChildElement(const char* name) const;
62 : XmlDomNode nextSibling() const;
63 : XmlDomNode previousSibling() const;
64 : XmlDomNode parent() const;
65 :
66 : XmlDomElement nextSiblingElement(const char* name = nullptr) const;
67 : XmlDomElement previousSiblingElement(const char* name = nullptr) const;
68 : XmlDomElement toElement() const;
69 :
70 : protected:
71 : friend class XmlDomDocument;
72 : friend class XmlDomElement;
73 :
74 : XmlDomNode(const std::shared_ptr<XmlDomImplData>& xml, xml_node_handle node);
75 :
76 : std::shared_ptr<XmlDomImplData> m_xml = nullptr;
77 : xml_node_handle m_node{};
78 : };
79 :
80 : class XmlDomElement : public XmlDomNode
81 : {
82 : public:
83 :
84 : String text() const;
85 :
86 : XmlDomAttribute firstAttribute() const;
87 : XmlDomAttribute attribute(const char* name) const;
88 :
89 : private:
90 :
91 : friend class XmlDomDocument;
92 : friend class XmlDomNode;
93 :
94 : XmlDomElement(const std::shared_ptr<XmlDomImplData>& data, xml_node_handle node);
95 : };
96 :
97 : class XmlDomAttribute
98 : {
99 : public:
100 :
101 : bool isNull() const;
102 : String attributeName() const;
103 :
104 : String value() const;
105 :
106 : XmlDomAttribute nextAttribute() const;
107 :
108 : private:
109 : friend class XmlDomElement;
110 :
111 : explicit XmlDomAttribute(const std::shared_ptr<XmlDomImplData>& data, xml_attr_handle attribute);
112 :
113 : std::shared_ptr<XmlDomImplData> m_xml = nullptr;
114 : xml_attr_handle m_attribute{};
115 : };
116 :
117 : class XmlDomDocument
118 : {
119 : public:
120 : XmlDomDocument();
121 :
122 : void setContent(const ByteArray& data);
123 :
124 : XmlDomElement rootElement() const;
125 :
126 : bool hasError() const;
127 : String errorString() const;
128 :
129 : private:
130 : std::shared_ptr<XmlDomImplData> m_xml = nullptr;
131 : };
132 : }
133 :
134 : #endif // MUSE_GLOBAL_XMLDOM_H
|