File indexing completed on 2024-04-21 03:52:04
0001 /* 0002 * BluezQt - Asynchronous BlueZ wrapper library 0003 * 0004 * SPDX-FileCopyrightText: 2019 Manuel Weichselbaumer <mincequi@web.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "XmlGenerator.h" 0010 0011 #include <QDebug> 0012 #include <QFile> 0013 0014 #include "BluezApiParser.h" 0015 #include "TypeAnnotation.h" 0016 0017 XmlGenerator::XmlGenerator(const Config &config) 0018 : m_config(config) 0019 { 0020 } 0021 0022 bool XmlGenerator::generate(const BluezApiParser &parser) 0023 { 0024 // Iterate interfaces 0025 for (const auto &interface : parser.interfaces()) { 0026 // Only consider interfaces with methods 0027 if (interface.methods().methods().empty()) { 0028 continue; 0029 } 0030 0031 // Create file 0032 QFile file(interface.name() + QStringLiteral(".xml")); 0033 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { 0034 qWarning() << "Error opening file for writing:" << file.fileName(); 0035 return false; 0036 } 0037 0038 // Write content 0039 QTextStream stream(&file); 0040 writeHeader(stream); 0041 writeInterface(stream, interface.name()); 0042 0043 // Iterate methods 0044 for (const auto &method : interface.methods().methods()) { 0045 // Respect config 0046 if ((method.tags().isDeprecated && !m_config.useDeprecated) || (method.tags().isOptional && !m_config.useOptional) 0047 || (method.tags().isExperimental && !m_config.useExperimental)) { 0048 continue; 0049 } 0050 0051 writeMethod(stream, method); 0052 } 0053 0054 closeInterface(stream); 0055 writeFooter(stream); 0056 file.close(); 0057 } 0058 0059 return true; 0060 } 0061 0062 void XmlGenerator::writeHeader(QTextStream &stream) 0063 { 0064 stream << "<?xml version=\"1.0\"?>\n"; 0065 stream << "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" " 0066 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"; 0067 stream << "<node>\n"; 0068 } 0069 0070 void XmlGenerator::writeFooter(QTextStream &stream) 0071 { 0072 stream << "</node>\n"; 0073 } 0074 0075 void XmlGenerator::writeInterface(QTextStream &stream, const QString &name) 0076 { 0077 stream << " <interface name=\"" << name << "\">\n"; 0078 } 0079 0080 void XmlGenerator::closeInterface(QTextStream &stream) 0081 { 0082 stream << " </interface>\n"; 0083 } 0084 0085 bool XmlGenerator::writeMethod(QTextStream &stream, const Method &method) 0086 { 0087 stream << " <method name=\"" << method.name() << "\""; 0088 0089 // Some beautification 0090 if (method.inParameters().empty() && method.outParameters().empty()) { 0091 stream << "/>\n"; 0092 return true; 0093 } 0094 0095 stream << ">\n"; 0096 0097 for (const auto ¶m : method.inParameters()) { 0098 if (!writeArg(stream, param, QStringLiteral("in"))) { 0099 return false; 0100 } 0101 } 0102 for (const auto ¶m : method.outParameters()) { 0103 if (!writeArg(stream, param, QStringLiteral("out"))) { 0104 return false; 0105 } 0106 } 0107 for (int i = 0; i < method.inParameters().size(); ++i) { 0108 writeAnnotation(stream, method.inParameters().at(i), QStringLiteral("In"), i); 0109 } 0110 for (int i = 0; i < method.outParameters().size(); ++i) { 0111 writeAnnotation(stream, method.outParameters().at(i), QStringLiteral("Out"), i); 0112 } 0113 0114 stream << " </method>\n"; 0115 0116 return true; 0117 } 0118 0119 bool XmlGenerator::writeArg(QTextStream &stream, const Parameter ¶m, const QString &dir) 0120 { 0121 auto dbusType = annotateType(AnnotationType::Bluez, AnnotationType::Dbus, param.type()); 0122 if (dbusType.isEmpty()) { 0123 return false; 0124 } 0125 stream << " <arg name=\"" << param.name() << "\" type=\"" << dbusType << "\" direction=\"" << dir << "\"/>\n"; 0126 0127 return true; 0128 } 0129 0130 void XmlGenerator::writeAnnotation(QTextStream &stream, const Parameter ¶m, const QString &dir, int i) 0131 { 0132 auto qtType = annotateType(AnnotationType::Bluez, AnnotationType::Qt, param.type()); 0133 if (qtType.isEmpty()) { 0134 return; 0135 } 0136 stream << " <annotation name=\"org.qtproject.QtDBus.QtTypeName." << dir << QString::number(i) << "\" value=\"" << qtType << "\"/>\n"; 0137 0138 return; 0139 }