1 | /* |
2 | * BluezQt - Asynchronous BlueZ wrapper library |
3 | * |
4 | * SPDX-FileCopyrightText: 2019 Manuel Weichselbaumer <mincequi@web.de> |
5 | * |
6 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
7 | */ |
8 | |
9 | #include "XmlGenerator.h" |
10 | |
11 | #include <QDebug> |
12 | #include <QFile> |
13 | |
14 | #include "BluezApiParser.h" |
15 | #include "TypeAnnotation.h" |
16 | |
17 | XmlGenerator::XmlGenerator(const Config &config) |
18 | : m_config(config) |
19 | { |
20 | } |
21 | |
22 | bool XmlGenerator::generate(const BluezApiParser &parser) |
23 | { |
24 | // Iterate interfaces |
25 | for (const auto &interface : parser.interfaces()) { |
26 | // Only consider interfaces with methods |
27 | if (interface.methods().methods().empty()) { |
28 | continue; |
29 | } |
30 | |
31 | // Create file |
32 | QFile file(interface.name() + QStringLiteral(".xml" )); |
33 | if (!file.open(flags: QIODevice::WriteOnly | QIODevice::Text)) { |
34 | qWarning() << "Error opening file for writing:" << file.fileName(); |
35 | return false; |
36 | } |
37 | |
38 | // Write content |
39 | QTextStream stream(&file); |
40 | writeHeader(stream); |
41 | writeInterface(stream, name: interface.name()); |
42 | |
43 | // Iterate methods |
44 | for (const auto &method : interface.methods().methods()) { |
45 | // Respect config |
46 | if ((method.tags().isDeprecated && !m_config.useDeprecated) || (method.tags().isOptional && !m_config.useOptional) |
47 | || (method.tags().isExperimental && !m_config.useExperimental)) { |
48 | continue; |
49 | } |
50 | |
51 | writeMethod(stream, method); |
52 | } |
53 | |
54 | closeInterface(stream); |
55 | writeFooter(stream); |
56 | file.close(); |
57 | } |
58 | |
59 | return true; |
60 | } |
61 | |
62 | void XmlGenerator::(QTextStream &stream) |
63 | { |
64 | stream << "<?xml version=\"1.0\"?>\n" ; |
65 | stream << "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" " |
66 | "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" ; |
67 | stream << "<node>\n" ; |
68 | } |
69 | |
70 | void XmlGenerator::(QTextStream &stream) |
71 | { |
72 | stream << "</node>\n" ; |
73 | } |
74 | |
75 | void XmlGenerator::writeInterface(QTextStream &stream, const QString &name) |
76 | { |
77 | stream << " <interface name=\"" << name << "\">\n" ; |
78 | } |
79 | |
80 | void XmlGenerator::closeInterface(QTextStream &stream) |
81 | { |
82 | stream << " </interface>\n" ; |
83 | } |
84 | |
85 | bool XmlGenerator::writeMethod(QTextStream &stream, const Method &method) |
86 | { |
87 | stream << " <method name=\"" << method.name() << "\"" ; |
88 | |
89 | // Some beautification |
90 | if (method.inParameters().empty() && method.outParameters().empty()) { |
91 | stream << "/>\n" ; |
92 | return true; |
93 | } |
94 | |
95 | stream << ">\n" ; |
96 | |
97 | for (const auto ¶m : method.inParameters()) { |
98 | if (!writeArg(stream, param, QStringLiteral("in" ))) { |
99 | return false; |
100 | } |
101 | } |
102 | for (const auto ¶m : method.outParameters()) { |
103 | if (!writeArg(stream, param, QStringLiteral("out" ))) { |
104 | return false; |
105 | } |
106 | } |
107 | for (int i = 0; i < method.inParameters().size(); ++i) { |
108 | writeAnnotation(stream, param: method.inParameters().at(i), QStringLiteral("In" ), i); |
109 | } |
110 | for (int i = 0; i < method.outParameters().size(); ++i) { |
111 | writeAnnotation(stream, param: method.outParameters().at(i), QStringLiteral("Out" ), i); |
112 | } |
113 | |
114 | stream << " </method>\n" ; |
115 | |
116 | return true; |
117 | } |
118 | |
119 | bool XmlGenerator::writeArg(QTextStream &stream, const Parameter ¶m, const QString &dir) |
120 | { |
121 | auto dbusType = annotateType(from: AnnotationType::Bluez, to: AnnotationType::Dbus, type: param.type()); |
122 | if (dbusType.isEmpty()) { |
123 | return false; |
124 | } |
125 | stream << " <arg name=\"" << param.name() << "\" type=\"" << dbusType << "\" direction=\"" << dir << "\"/>\n" ; |
126 | |
127 | return true; |
128 | } |
129 | |
130 | void XmlGenerator::writeAnnotation(QTextStream &stream, const Parameter ¶m, const QString &dir, int i) |
131 | { |
132 | auto qtType = annotateType(from: AnnotationType::Bluez, to: AnnotationType::Qt, type: param.type()); |
133 | if (qtType.isEmpty()) { |
134 | return; |
135 | } |
136 | stream << " <annotation name=\"org.qtproject.QtDBus.QtTypeName." << dir << QString::number(i) << "\" value=\"" << qtType << "\"/>\n" ; |
137 | |
138 | return; |
139 | } |
140 | |