1 /*
2  * \copyright Copyright (c) 2016-2021 Governikus GmbH & Co. KG, Germany
3  */
4 
5 #include "VersionInfo.h"
6 
7 #include <QCoreApplication>
8 #include <QJsonDocument>
9 #include <QJsonObject>
10 #include <QStringView>
11 #include <QVector>
12 
13 
14 using namespace governikus;
15 
16 namespace
17 {
18 #define VERSION_NAME(_name, _key)\
19 	QString _name(){\
20 		return QStringLiteral(_key);\
21 	}
22 
23 VERSION_NAME(NAME, "Name")
24 VERSION_NAME(IMPL_TITLE, "Implementation-Title")
25 VERSION_NAME(IMPL_VENDOR, "Implementation-Vendor")
26 VERSION_NAME(IMPL_VERSION, "Implementation-Version")
27 VERSION_NAME(SPEC_TITLE, "Specification-Title")
28 VERSION_NAME(SPEC_VENDOR, "Specification-Vendor")
29 VERSION_NAME(SPEC_VERSION, "Specification-Version")
30 } // namespace
31 
32 
VersionInfo(const QMap<QString,QString> & pInfo)33 VersionInfo::VersionInfo(const QMap<QString, QString>& pInfo)
34 	: mInfo(pInfo)
35 {
36 	if (!mInfo.isEmpty() && !mInfo.contains(NAME()))
37 	{
38 		qDebug() << "VersionInfo invalid... clearing";
39 		mInfo.clear();
40 	}
41 }
42 
43 
VersionInfo()44 VersionInfo::VersionInfo()
45 	: VersionInfo(QMap<QString, QString>())
46 {
47 }
48 
49 
getInstance()50 VersionInfo VersionInfo::getInstance()
51 {
52 	return VersionInfo({
53 				{NAME(), QCoreApplication::applicationName()},
54 				{IMPL_TITLE(), QCoreApplication::applicationName()},
55 				{IMPL_VENDOR(), QCoreApplication::organizationName()},
56 				{IMPL_VERSION(), QCoreApplication::applicationVersion()},
57 				{SPEC_TITLE(), QStringLiteral("TR-03124")},
58 				{SPEC_VENDOR(), QStringLiteral("Federal Office for Information Security")},
59 				{SPEC_VERSION(), QStringLiteral("1.3")}
60 			});
61 }
62 
63 
fromText(const QString & pText)64 VersionInfo VersionInfo::fromText(const QString& pText)
65 {
66 	QMap<QString, QString> infos;
67 
68 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
69 	const auto& header = QStringView(pText).split(QLatin1Char('\n'));
70 #else
71 	const auto& header = pText.splitRef(QLatin1Char('\n'));
72 #endif
73 
74 	for (const auto& line : header)
75 	{
76 		const auto pair = line.split(QLatin1Char(':'));
77 		if (pair.size() != 2 || pair[0].trimmed().isEmpty() || pair[1].trimmed().isEmpty())
78 		{
79 			qWarning() << "Cannot parse line:" << line;
80 			continue;
81 		}
82 		infos[pair[0].trimmed().toString()] = pair[1].trimmed().toString();
83 	}
84 	return VersionInfo(infos);
85 }
86 
87 
isNull() const88 bool VersionInfo::isNull() const
89 {
90 	return mInfo.isEmpty();
91 }
92 
93 
getName() const94 QString VersionInfo::getName() const
95 {
96 	return mInfo[NAME()];
97 }
98 
99 
getImplementationTitle() const100 QString VersionInfo::getImplementationTitle() const
101 {
102 	return mInfo[IMPL_TITLE()];
103 }
104 
105 
getImplementationVendor() const106 QString VersionInfo::getImplementationVendor() const
107 {
108 	return mInfo[IMPL_VENDOR()];
109 }
110 
111 
getImplementationVersion() const112 QString VersionInfo::getImplementationVersion() const
113 {
114 	return mInfo[IMPL_VERSION()];
115 }
116 
117 
getSpecificationTitle() const118 QString VersionInfo::getSpecificationTitle() const
119 {
120 	return mInfo[SPEC_TITLE()];
121 }
122 
123 
getSpecificationVendor() const124 QString VersionInfo::getSpecificationVendor() const
125 {
126 	return mInfo[SPEC_VENDOR()];
127 }
128 
129 
getSpecificationVersion() const130 QString VersionInfo::getSpecificationVersion() const
131 {
132 	return mInfo[SPEC_VERSION()];
133 }
134 
135 
toJsonObject() const136 QJsonObject VersionInfo::toJsonObject() const
137 {
138 	QJsonObject jsonObj;
139 	for (auto i = mInfo.constBegin(); i != mInfo.constEnd(); ++i)
140 	{
141 		jsonObj[i.key()] = i.value();
142 	}
143 	return jsonObj;
144 }
145 
146 
toJson(QJsonDocument::JsonFormat pFormat) const147 QByteArray VersionInfo::toJson(QJsonDocument::JsonFormat pFormat) const
148 {
149 	return QJsonDocument(toJsonObject()).toJson(pFormat);
150 }
151 
152 
toText() const153 QString VersionInfo::toText() const
154 {
155 	QStringList list;
156 	for (auto i = mInfo.constBegin(); i != mInfo.constEnd(); ++i)
157 	{
158 		list += QStringLiteral("%1: %2").arg(i.key(), i.value());
159 	}
160 	return list.join(QLatin1Char('\n'));
161 }
162 
163 
operator <<(QDebug pDbg,const VersionInfo & pVersionInfo)164 QDebug operator<<(QDebug pDbg, const VersionInfo& pVersionInfo)
165 {
166 	QDebugStateSaver saver(pDbg);
167 	return pDbg.nospace().noquote() << "VersionInfo(" << pVersionInfo.toJson(QJsonDocument::JsonFormat::Compact) << ")";
168 }
169