6.5.3 clean

This commit is contained in:
kleuter
2023-11-01 18:02:52 +01:00
parent bbe896803b
commit 7018d9e6c8
2170 changed files with 57471 additions and 43550 deletions

View File

@ -4,6 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(convert LANGUAGES CXX)
if (ANDROID)
message(FATAL_ERROR "This project cannot be built on Android.")
endif()
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@ -18,6 +22,7 @@ qt_add_executable(convert
cborconverter.cpp cborconverter.h
converter.h
datastreamconverter.cpp datastreamconverter.h
debugtextdumper.cpp debugtextdumper.h
jsonconverter.cpp jsonconverter.h
main.cpp
nullconverter.cpp nullconverter.h

View File

@ -3,19 +3,21 @@
#include "cborconverter.h"
#include <QCborArray>
#include <QCborMap>
#include <QCborStreamReader>
#include <QCborStreamWriter>
#include <QCborMap>
#include <QCborArray>
#include <QCborValue>
#include <QDataStream>
#include <QFloat16>
#include <QFile>
#include <QFloat16>
#include <QMetaType>
#include <QTextStream>
#include <stdio.h>
using namespace Qt::StringLiterals;
static CborConverter cborConverter;
static CborDiagnosticDumper cborDiagnosticDumper;
@ -118,33 +120,33 @@ static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrim
}
//! [1]
QString CborDiagnosticDumper::name()
QString CborDiagnosticDumper::name() const
{
return QStringLiteral("cbor-dump");
return "cbor-dump"_L1;
}
Converter::Direction CborDiagnosticDumper::directions()
Converter::Directions CborDiagnosticDumper::directions() const
{
return Out;
return Direction::Out;
}
Converter::Options CborDiagnosticDumper::outputOptions()
Converter::Options CborDiagnosticDumper::outputOptions() const
{
return SupportsArbitraryMapKeys;
}
const char *CborDiagnosticDumper::optionsHelp()
const char *CborDiagnosticDumper::optionsHelp() const
{
return diagnosticHelp;
}
bool CborDiagnosticDumper::probeFile(QIODevice *f)
bool CborDiagnosticDumper::probeFile(QIODevice *f) const
{
Q_UNUSED(f);
return false;
}
QVariant CborDiagnosticDumper::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant CborDiagnosticDumper::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
Q_UNREACHABLE();
Q_UNUSED(f);
@ -152,7 +154,8 @@ QVariant CborDiagnosticDumper::loadFile(QIODevice *f, Converter *&outputConverte
return QVariant();
}
void CborDiagnosticDumper::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void CborDiagnosticDumper::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
QCborValue::DiagnosticNotationOptions opts = QCborValue::LineWrapped;
for (const QString &s : options) {
@ -181,8 +184,7 @@ void CborDiagnosticDumper::saveFile(QIODevice *f, const QVariant &contents, cons
}
QTextStream out(f);
out << convertFromVariant(contents, Double).toDiagnosticNotation(opts)
<< Qt::endl;
out << convertFromVariant(contents, Double).toDiagnosticNotation(opts) << Qt::endl;
}
CborConverter::CborConverter()
@ -190,37 +192,37 @@ CborConverter::CborConverter()
qRegisterMetaType<QCborTag>();
}
QString CborConverter::name()
QString CborConverter::name() const
{
return "cbor";
}
Converter::Direction CborConverter::directions()
Converter::Directions CborConverter::directions() const
{
return InOut;
return Direction::InOut;
}
Converter::Options CborConverter::outputOptions()
Converter::Options CborConverter::outputOptions() const
{
return SupportsArbitraryMapKeys;
}
const char *CborConverter::optionsHelp()
const char *CborConverter::optionsHelp() const
{
return cborOptionHelp;
}
bool CborConverter::probeFile(QIODevice *f)
bool CborConverter::probeFile(QIODevice *f) const
{
if (QFile *file = qobject_cast<QFile *>(f)) {
if (file->fileName().endsWith(QLatin1String(".cbor")))
if (file->fileName().endsWith(".cbor"_L1))
return true;
}
return f->isReadable() && f->peek(3) == QByteArray("\xd9\xd9\xf7", 3);
}
//! [2]
QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant CborConverter::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
const char *ptr = nullptr;
if (auto file = qobject_cast<QFile *>(f))
@ -256,7 +258,7 @@ QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter)
}
//! [2]
//! [3]
void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) const
{
//! [3]
bool useSignature = true;
@ -318,8 +320,9 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri
exit(EXIT_FAILURE);
}
//! [4]
QCborValue v = convertFromVariant(contents,
useFloat16 == Always ? Float16 : useFloat == Always ? Float : Double);
QCborValue v =
convertFromVariant(contents,
useFloat16 == Always ? Float16 : useFloat == Always ? Float : Double);
QCborStreamWriter writer(f);
if (useSignature)
writer.append(QCborKnownTags::Signature);

View File

@ -10,13 +10,14 @@ class CborDiagnosticDumper : public Converter
{
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
class CborConverter : public Converter
@ -26,13 +27,14 @@ public:
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // CBORCONVERTER_H

View File

@ -12,17 +12,19 @@ INSTALLS += target
SOURCES += main.cpp \
cborconverter.cpp \
jsonconverter.cpp \
datastreamconverter.cpp \
debugtextdumper.cpp \
jsonconverter.cpp \
nullconverter.cpp \
textconverter.cpp \
xmlconverter.cpp \
nullconverter.cpp
xmlconverter.cpp
HEADERS += \
converter.h \
cborconverter.h \
jsonconverter.h \
datastreamconverter.h \
debugtextdumper.h \
jsonconverter.h \
nullconverter.h \
textconverter.h \
xmlconverter.h \
nullconverter.h
xmlconverter.h

View File

@ -5,10 +5,10 @@
#define CONVERTER_H
#include <QIODevice>
#include <QList>
#include <QPair>
#include <QVariant>
#include <QVariantMap>
#include <QList>
class VariantOrderedMap : public QList<QPair<QVariant, QVariant>>
{
@ -32,26 +32,25 @@ protected:
public:
static Converter *null;
enum Direction {
In = 1, Out = 2, InOut = 3
};
enum class Direction { In = 1, Out = 2, InOut = In | Out };
Q_DECLARE_FLAGS(Directions, Direction)
enum Option {
SupportsArbitraryMapKeys = 0x01
};
enum Option { SupportsArbitraryMapKeys = 0x01 };
Q_DECLARE_FLAGS(Options, Option)
virtual ~Converter() = 0;
virtual QString name() = 0;
virtual Direction directions() = 0;
virtual Options outputOptions() = 0;
virtual const char *optionsHelp() = 0;
virtual bool probeFile(QIODevice *f) = 0;
virtual QVariant loadFile(QIODevice *f, Converter *&outputConverter) = 0;
virtual void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) = 0;
virtual QString name() const = 0;
virtual Directions directions() const = 0;
virtual Options outputOptions() const = 0;
virtual const char *optionsHelp() const = 0;
virtual bool probeFile(QIODevice *f) const = 0;
virtual QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const = 0;
virtual void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const = 0;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Converter::Directions)
Q_DECLARE_OPERATORS_FOR_FLAGS(Converter::Options)
#endif // CONVERTER_H

View File

@ -2,20 +2,21 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "datastreamconverter.h"
#include "debugtextdumper.h"
#include <QDataStream>
#include <QDebug>
#include <QTextStream>
using namespace Qt::StringLiterals;
static const char dataStreamOptionHelp[] =
"byteorder=host|big|little Byte order to use.\n"
"version=<n> QDataStream version (default: Qt 5.0).\n"
"version=<n> QDataStream version (default: Qt 6.0).\n"
;
static const char signature[] = "qds";
static DataStreamDumper dataStreamDumper;
static DataStreamConverter DataStreamConverter;
static DataStreamConverter dataStreamConverter;
static DebugTextDumper debugTextDumper;
QDataStream &operator<<(QDataStream &ds, const VariantOrderedMap &map)
{
@ -42,123 +43,43 @@ QDataStream &operator>>(QDataStream &ds, VariantOrderedMap &map)
return ds;
}
static QString dumpVariant(const QVariant &v, const QString &indent = QLatin1String("\n"))
{
QString result;
QString indented = indent + QLatin1String(" ");
int type = v.userType();
if (type == qMetaTypeId<VariantOrderedMap>() || type == QMetaType::QVariantMap) {
const auto map = (type == QMetaType::QVariantMap) ?
VariantOrderedMap(v.toMap()) : qvariant_cast<VariantOrderedMap>(v);
result = QLatin1String("Map {");
for (const auto &pair : map) {
result += indented + dumpVariant(pair.first, indented);
result.chop(1); // remove comma
result += QLatin1String(" => ") + dumpVariant(pair.second, indented);
}
result.chop(1); // remove comma
result += indent + QLatin1String("},");
} else if (type == QMetaType::QVariantList) {
const QVariantList list = v.toList();
result = QLatin1String("List [");
for (const auto &item : list)
result += indented + dumpVariant(item, indented);
result.chop(1); // remove comma
result += indent + QLatin1String("],");
} else {
QDebug debug(&result);
debug.nospace() << v << ',';
}
return result;
}
QString DataStreamDumper::name()
{
return QStringLiteral("datastream-dump");
}
Converter::Direction DataStreamDumper::directions()
{
return Out;
}
Converter::Options DataStreamDumper::outputOptions()
{
return SupportsArbitraryMapKeys;
}
const char *DataStreamDumper::optionsHelp()
{
return nullptr;
}
bool DataStreamDumper::probeFile(QIODevice *f)
{
Q_UNUSED(f);
return false;
}
QVariant DataStreamDumper::loadFile(QIODevice *f, Converter *&outputConverter)
{
Q_UNREACHABLE();
Q_UNUSED(f);
Q_UNUSED(outputConverter);
return QVariant();
}
void DataStreamDumper::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
{
Q_UNUSED(options);
QString s = dumpVariant(contents);
s[s.size() - 1] = QLatin1Char('\n'); // replace the comma with newline
QTextStream out(f);
out << s;
}
DataStreamConverter::DataStreamConverter()
{
qRegisterMetaType<VariantOrderedMap>();
}
QString DataStreamConverter::name()
QString DataStreamConverter::name() const
{
return QStringLiteral("datastream");
return "datastream"_L1;
}
Converter::Direction DataStreamConverter::directions()
Converter::Directions DataStreamConverter::directions() const
{
return InOut;
return Direction::InOut;
}
Converter::Options DataStreamConverter::outputOptions()
Converter::Options DataStreamConverter::outputOptions() const
{
return SupportsArbitraryMapKeys;
}
const char *DataStreamConverter::optionsHelp()
const char *DataStreamConverter::optionsHelp() const
{
return dataStreamOptionHelp;
}
bool DataStreamConverter::probeFile(QIODevice *f)
bool DataStreamConverter::probeFile(QIODevice *f) const
{
return f->isReadable() && f->peek(sizeof(signature) - 1) == signature;
}
QVariant DataStreamConverter::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant DataStreamConverter::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
if (!outputConverter)
outputConverter = &dataStreamDumper;
outputConverter = &debugTextDumper;
char c;
if (f->read(sizeof(signature) -1) != signature ||
!f->getChar(&c) || (c != 'l' && c != 'B')) {
if (f->read(sizeof(signature) - 1) != signature || !f->getChar(&c) || (c != 'l' && c != 'B')) {
fprintf(stderr, "Could not load QDataStream file: invalid signature.\n");
exit(EXIT_FAILURE);
}
@ -175,9 +96,10 @@ QVariant DataStreamConverter::loadFile(QIODevice *f, Converter *&outputConverter
return result;
}
void DataStreamConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void DataStreamConverter::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
QDataStream::Version version = QDataStream::Qt_5_0;
QDataStream::Version version = QDataStream::Qt_6_0;
auto order = QDataStream::ByteOrder(QSysInfo::ByteOrder);
for (const QString &option : options) {
const QStringList pair = option.split('=');
@ -213,7 +135,7 @@ void DataStreamConverter::saveFile(QIODevice *f, const QVariant &contents, const
exit(EXIT_FAILURE);
}
char c = order == QDataStream::LittleEndian ? 'l' : 'B';
char c = order == QDataStream::LittleEndian ? 'l' : 'B';
f->write(signature);
f->write(&c, 1);

View File

@ -6,19 +6,6 @@
#include "converter.h"
class DataStreamDumper : public Converter
{
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
};
class DataStreamConverter : public Converter
{
public:
@ -26,13 +13,14 @@ public:
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // DATASTREAMCONVERTER_H

View File

@ -0,0 +1,89 @@
// Copyright (C) 2018 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "debugtextdumper.h"
#include <QDebug>
#include <QTextStream>
using namespace Qt::StringLiterals;
// Static instance is declared in datastreamconverter.cpp, since it uses it.
static QString dumpVariant(const QVariant &v, const QString &indent = "\n"_L1)
{
QString result;
QString indented = indent + " "_L1;
int type = v.userType();
if (type == qMetaTypeId<VariantOrderedMap>() || type == QMetaType::QVariantMap) {
const auto map = (type == QMetaType::QVariantMap) ? VariantOrderedMap(v.toMap())
: qvariant_cast<VariantOrderedMap>(v);
result = "Map {"_L1;
for (const auto &pair : map) {
result += indented + dumpVariant(pair.first, indented);
result.chop(1); // remove comma
result += " => "_L1 + dumpVariant(pair.second, indented);
}
result.chop(1); // remove comma
result += indent + "},"_L1;
} else if (type == QMetaType::QVariantList) {
const QVariantList list = v.toList();
result = "List ["_L1;
for (const auto &item : list)
result += indented + dumpVariant(item, indented);
result.chop(1); // remove comma
result += indent + "],"_L1;
} else {
QDebug debug(&result);
debug.nospace() << v << ',';
}
return result;
}
QString DebugTextDumper::name() const
{
return "debugtext-dump"_L1;
}
Converter::Directions DebugTextDumper::directions() const
{
return Direction::Out;
}
Converter::Options DebugTextDumper::outputOptions() const
{
return SupportsArbitraryMapKeys;
}
const char *DebugTextDumper::optionsHelp() const
{
return nullptr;
}
bool DebugTextDumper::probeFile(QIODevice *f) const
{
Q_UNUSED(f);
return false;
}
QVariant DebugTextDumper::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
Q_UNREACHABLE();
Q_UNUSED(f);
Q_UNUSED(outputConverter);
return QVariant();
}
void DebugTextDumper::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
Q_UNUSED(options);
QString s = dumpVariant(contents);
s[s.size() - 1] = u'\n'; // replace the comma with newline
QTextStream out(f);
out << s;
}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2018 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef DEBUGTEXTDUMPER_H
#define DEBUGTEXTDUMPER_H
#include "converter.h"
class DebugTextDumper : public Converter
{
// Converter interface
public:
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // DEBUGTEXTDUMPER_H

View File

@ -3,7 +3,8 @@
/*!
\example serialization/convert
\examplecategory {Input/Output}
\examplecategory {Data Processing & I/O}
\meta tag {network}
\title Convert Example
\brief The Convert example demonstrates how to convert between different
@ -59,7 +60,7 @@
\section1 The DataStreamConverter Class
The DataStreamConverter class is used to serialize to and from the
QDataStream format. There is also the DataStreamDumper class for outputting
QDataStream format. There is also the DebugTextDumper class for outputting
the data lossless in a non-standardized human readable format.
\section1 The JsonConverter Class

View File

@ -9,10 +9,11 @@
#include <QJsonObject>
#include <QJsonValue>
using namespace Qt::StringLiterals;
static JsonConverter jsonConverter;
static const char jsonOptionHelp[] =
"compact=no|yes Use compact JSON form.\n";
static const char jsonOptionHelp[] = "compact=no|yes Use compact JSON form.\n";
static QJsonDocument convertFromVariant(const QVariant &v)
{
@ -24,34 +25,30 @@ static QJsonDocument convertFromVariant(const QVariant &v)
return doc;
}
JsonConverter::JsonConverter()
QString JsonConverter::name() const
{
return "json"_L1;
}
QString JsonConverter::name()
Converter::Directions JsonConverter::directions() const
{
return "json";
return Direction::InOut;
}
Converter::Direction JsonConverter::directions()
{
return InOut;
}
Converter::Options JsonConverter::outputOptions()
Converter::Options JsonConverter::outputOptions() const
{
return {};
}
const char *JsonConverter::optionsHelp()
const char *JsonConverter::optionsHelp() const
{
return jsonOptionHelp;
}
bool JsonConverter::probeFile(QIODevice *f)
bool JsonConverter::probeFile(QIODevice *f) const
{
if (QFile *file = qobject_cast<QFile *>(f)) {
if (file->fileName().endsWith(QLatin1String(".json")))
if (file->fileName().endsWith(".json"_L1))
return true;
}
@ -62,7 +59,7 @@ bool JsonConverter::probeFile(QIODevice *f)
return false;
}
QVariant JsonConverter::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant JsonConverter::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
if (!outputConverter)
outputConverter = this;
@ -87,13 +84,14 @@ QVariant JsonConverter::loadFile(QIODevice *f, Converter *&outputConverter)
return doc.toVariant();
}
void JsonConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void JsonConverter::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
QJsonDocument::JsonFormat format = QJsonDocument::Indented;
for (const QString &s : options) {
if (s == QLatin1String("compact=no")) {
if (s == "compact=no"_L1) {
format = QJsonDocument::Indented;
} else if (s == QLatin1String("compact=yes")) {
} else if (s == "compact=yes"_L1) {
format = QJsonDocument::Compact;
} else {
fprintf(stderr, "Unknown option '%s' to JSON output. Valid options are:\n%s",

View File

@ -8,18 +8,16 @@
class JsonConverter : public Converter
{
public:
JsonConverter();
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // JSONCONVERTER_H

View File

@ -11,12 +11,14 @@
#include <stdio.h>
static QList<Converter *> *availableConverters;
using namespace Qt::StringLiterals;
static QList<const Converter *> *availableConverters;
Converter::Converter()
{
if (!availableConverters)
availableConverters = new QList<Converter *>;
availableConverters = new QList<const Converter *>;
availableConverters->append(this);
}
@ -31,64 +33,68 @@ int main(int argc, char *argv[])
QStringList inputFormats;
QStringList outputFormats;
for (Converter *conv : std::as_const(*availableConverters)) {
for (const Converter *conv : std::as_const(*availableConverters)) {
auto direction = conv->directions();
QString name = conv->name();
if (direction & Converter::In)
if (direction.testFlag(Converter::Direction::In))
inputFormats << name;
if (direction & Converter::Out)
if (direction.testFlag(Converter::Direction::Out))
outputFormats << name;
}
inputFormats.sort();
outputFormats.sort();
inputFormats.prepend("auto");
outputFormats.prepend("auto");
inputFormats.prepend("auto"_L1);
outputFormats.prepend("auto"_L1);
QCommandLineParser parser;
parser.setApplicationDescription(QStringLiteral("Qt file format conversion tool"));
parser.setApplicationDescription("Qt file format conversion tool"_L1);
parser.addHelpOption();
QCommandLineOption inputFormatOption(QStringList{"I", "input-format"});
inputFormatOption.setDescription(QLatin1String("Select the input format for the input file. Available formats: ") +
inputFormats.join(", "));
inputFormatOption.setValueName("format");
QCommandLineOption inputFormatOption(QStringList{ "I"_L1, "input-format"_L1 });
inputFormatOption.setDescription(
"Select the input format for the input file. Available formats: "_L1
+ inputFormats.join(", "_L1));
inputFormatOption.setValueName("format"_L1);
inputFormatOption.setDefaultValue(inputFormats.constFirst());
parser.addOption(inputFormatOption);
QCommandLineOption outputFormatOption(QStringList{"O", "output-format"});
outputFormatOption.setDescription(QLatin1String("Select the output format for the output file. Available formats: ") +
outputFormats.join(", "));
outputFormatOption.setValueName("format");
QCommandLineOption outputFormatOption(QStringList{ "O"_L1, "output-format"_L1 });
outputFormatOption.setDescription(
"Select the output format for the output file. Available formats: "_L1
+ outputFormats.join(", "_L1));
outputFormatOption.setValueName("format"_L1);
outputFormatOption.setDefaultValue(outputFormats.constFirst());
parser.addOption(outputFormatOption);
QCommandLineOption optionOption(QStringList{"o", "option"});
optionOption.setDescription(QStringLiteral("Format-specific options. Use --format-options to find out what options are available."));
optionOption.setValueName("options...");
QCommandLineOption optionOption(QStringList{ "o"_L1, "option"_L1 });
optionOption.setDescription(
"Format-specific options. Use --format-options to find out what options are available."_L1);
optionOption.setValueName("options..."_L1);
optionOption.setDefaultValues({});
parser.addOption(optionOption);
QCommandLineOption formatOptionsOption("format-options");
formatOptionsOption.setDescription(QStringLiteral("Prints the list of valid options for --option for the converter format <format>."));
formatOptionsOption.setValueName("format");
QCommandLineOption formatOptionsOption("format-options"_L1);
formatOptionsOption.setDescription(
"Prints the list of valid options for --option for the converter format <format>."_L1);
formatOptionsOption.setValueName("format"_L1);
parser.addOption(formatOptionsOption);
parser.addPositionalArgument(QStringLiteral("[source]"),
QStringLiteral("File to read from (stdin if none)"));
parser.addPositionalArgument(QStringLiteral("[destination]"),
QStringLiteral("File to write to (stdout if none)"));
parser.addPositionalArgument("[source]"_L1, "File to read from (stdin if none)"_L1);
parser.addPositionalArgument("[destination]"_L1, "File to write to (stdout if none)"_L1);
parser.process(app);
if (parser.isSet(formatOptionsOption)) {
QString format = parser.value(formatOptionsOption);
for (Converter *conv : std::as_const(*availableConverters)) {
for (const Converter *conv : std::as_const(*availableConverters)) {
if (conv->name() == format) {
const char *help = conv->optionsHelp();
if (help)
printf("The following options are available for format '%s':\n\n%s", qPrintable(format), help);
else
if (help) {
printf("The following options are available for format '%s':\n\n%s",
qPrintable(format), help);
} else {
printf("Format '%s' supports no options.\n", qPrintable(format));
}
return EXIT_SUCCESS;
}
}
@ -97,10 +103,10 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
Converter *inconv = nullptr;
const Converter *inconv = nullptr;
QString format = parser.value(inputFormatOption);
if (format != "auto") {
for (Converter *conv : std::as_const(*availableConverters)) {
if (format != "auto"_L1) {
for (const Converter *conv : std::as_const(*availableConverters)) {
if (conv->name() == format) {
inconv = conv;
break;
@ -113,10 +119,10 @@ int main(int argc, char *argv[])
}
}
Converter *outconv = nullptr;
const Converter *outconv = nullptr;
format = parser.value(outputFormatOption);
if (format != "auto") {
for (Converter *conv : std::as_const(*availableConverters)) {
if (format != "auto"_L1) {
for (const Converter *conv : std::as_const(*availableConverters)) {
if (conv->name() == format) {
outconv = conv;
break;
@ -155,8 +161,9 @@ int main(int argc, char *argv[])
if (!inconv) {
// probe the input to find a file format
for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->directions() & Converter::In && conv->probeFile(&input)) {
for (const Converter *conv : std::as_const(*availableConverters)) {
if (conv->directions().testFlag(Converter::Direction::In)
&& conv->probeFile(&input)) {
inconv = conv;
break;
}
@ -170,8 +177,9 @@ int main(int argc, char *argv[])
if (!outconv) {
// probe the output to find a file format
for (Converter *conv : std::as_const(*availableConverters)) {
if (conv->directions() & Converter::Out && conv->probeFile(&output)) {
for (const Converter *conv : std::as_const(*availableConverters)) {
if (conv->directions().testFlag(Converter::Direction::Out)
&& conv->probeFile(&output)) {
outconv = conv;
break;
}

View File

@ -3,36 +3,38 @@
#include "nullconverter.h"
using namespace Qt::StringLiterals;
static NullConverter nullConverter;
Converter* Converter::null = &nullConverter;
Converter *Converter::null = &nullConverter;
QString NullConverter::name()
QString NullConverter::name() const
{
return QLatin1String("null");
return "null"_L1;
}
Converter::Direction NullConverter::directions()
Converter::Directions NullConverter::directions() const
{
return Out;
return Direction::Out;
}
Converter::Options NullConverter::outputOptions()
Converter::Options NullConverter::outputOptions() const
{
return SupportsArbitraryMapKeys;
}
const char *NullConverter::optionsHelp()
const char *NullConverter::optionsHelp() const
{
return nullptr;
}
bool NullConverter::probeFile(QIODevice *f)
bool NullConverter::probeFile(QIODevice *f) const
{
Q_UNUSED(f);
return false;
}
QVariant NullConverter::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant NullConverter::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
Q_UNUSED(f);
Q_UNUSED(outputConverter);
@ -40,10 +42,12 @@ QVariant NullConverter::loadFile(QIODevice *f, Converter *&outputConverter)
return QVariant();
}
void NullConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void NullConverter::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
if (!options.isEmpty()) {
fprintf(stderr, "Unknown option '%s' to null output. This format has no options.\n", qPrintable(options.first()));
fprintf(stderr, "Unknown option '%s' to null output. This format has no options.\n",
qPrintable(options.first()));
exit(EXIT_FAILURE);
}

View File

@ -10,13 +10,14 @@ class NullConverter : public Converter
{
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // NULLCONVERTER_H

View File

@ -6,6 +6,8 @@
#include <QFile>
#include <QTextStream>
using namespace Qt::StringLiterals;
static void dumpVariant(QTextStream &out, const QVariant &v)
{
switch (v.userType()) {
@ -42,67 +44,62 @@ static void dumpVariant(QTextStream &out, const QVariant &v)
}
}
QString TextConverter::name()
QString TextConverter::name() const
{
return QStringLiteral("text");
return "text"_L1;
}
Converter::Direction TextConverter::directions()
Converter::Directions TextConverter::directions() const
{
return InOut;
return Direction::InOut;
}
Converter::Options TextConverter::outputOptions()
Converter::Options TextConverter::outputOptions() const
{
return {};
}
const char *TextConverter::optionsHelp()
const char *TextConverter::optionsHelp() const
{
return nullptr;
}
bool TextConverter::probeFile(QIODevice *f)
bool TextConverter::probeFile(QIODevice *f) const
{
if (QFile *file = qobject_cast<QFile *>(f))
return file->fileName().endsWith(QLatin1String(".txt"));
return file->fileName().endsWith(".txt"_L1);
return false;
}
QVariant TextConverter::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant TextConverter::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
if (!outputConverter)
outputConverter = this;
QVariantList list;
QTextStream in(f);
QString line ;
QString line;
while (!in.atEnd()) {
in.readLineInto(&line);
bool ok;
qint64 v = line.toLongLong(&ok);
if (ok) {
if (qint64 v = line.toLongLong(&ok); ok)
list.append(v);
continue;
}
double d = line.toDouble(&ok);
if (ok) {
else if (double d = line.toDouble(&ok); ok)
list.append(d);
continue;
}
list.append(line);
else
list.append(line);
}
return list;
}
void TextConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void TextConverter::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
if (!options.isEmpty()) {
fprintf(stderr, "Unknown option '%s' to text output. This format has no options.\n", qPrintable(options.first()));
fprintf(stderr, "Unknown option '%s' to text output. This format has no options.\n",
qPrintable(options.first()));
exit(EXIT_FAILURE);
}

View File

@ -8,16 +8,16 @@
class TextConverter : public Converter
{
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // TEXTCONVERTER_H

View File

@ -13,8 +13,9 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
static const char xmlOptionHelp[] =
"compact=no|yes Use compact XML form.\n";
using namespace Qt::StringLiterals;
static const char xmlOptionHelp[] = "compact=no|yes Use compact XML form.\n";
static XmlConverter xmlConverter;
@ -23,7 +24,7 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options
static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options options)
{
QVariantList list;
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("list"))) {
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == "list"_L1)) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::StartElement:
@ -47,8 +48,7 @@ static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options option
break;
}
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
xml.lineNumber(), xml.columnNumber(),
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", xml.lineNumber(), xml.columnNumber(),
qPrintable(xml.tokenString()), qPrintable(xml.name().toString()));
exit(EXIT_FAILURE);
}
@ -57,10 +57,11 @@ static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options option
return list;
}
static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml, Converter::Options options)
static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml,
Converter::Options options)
{
QVariant key, value;
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("entry"))) {
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == "entry"_L1)) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::StartElement:
@ -89,8 +90,7 @@ static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml, Conv
break;
}
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
xml.lineNumber(), xml.columnNumber(),
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", xml.lineNumber(), xml.columnNumber(),
qPrintable(xml.tokenString()), qPrintable(xml.name().toString()));
exit(EXIT_FAILURE);
}
@ -103,11 +103,11 @@ static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options)
QVariantMap map1;
VariantOrderedMap map2;
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("map"))) {
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == "map"_L1)) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::StartElement:
if (xml.name() == QLatin1String("entry")) {
if (xml.name() == "entry"_L1) {
auto pair = mapEntryFromXml(xml, options);
if (options & Converter::SupportsArbitraryMapKeys)
map2.append(pair);
@ -134,8 +134,7 @@ static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options)
break;
}
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
xml.lineNumber(), xml.columnNumber(),
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", xml.lineNumber(), xml.columnNumber(),
qPrintable(xml.tokenString()), qPrintable(xml.name().toString()));
exit(EXIT_FAILURE);
}
@ -149,18 +148,18 @@ static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options)
static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options)
{
QStringView name = xml.name();
if (name == QLatin1String("list"))
if (name == "list"_L1)
return listFromXml(xml, options);
if (name == QLatin1String("map"))
if (name == "map"_L1)
return mapFromXml(xml, options);
if (name != QLatin1String("value")) {
if (name != "value"_L1) {
fprintf(stderr, "%lld:%lld: Invalid XML key '%s'.\n",
xml.lineNumber(), xml.columnNumber(), qPrintable(name.toString()));
exit(EXIT_FAILURE);
}
QXmlStreamAttributes attrs = xml.attributes();
QStringView type = attrs.value(QLatin1String("type"));
QStringView type = attrs.value("type"_L1);
forever {
xml.readNext();
@ -169,8 +168,7 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options
if (xml.isCDATA() || xml.isCharacters() || xml.isEndElement())
break;
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
xml.lineNumber(), xml.columnNumber(),
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", xml.lineNumber(), xml.columnNumber(),
qPrintable(xml.tokenString()), qPrintable(name.toString()));
exit(EXIT_FAILURE);
}
@ -180,45 +178,45 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options
text = text.trimmed();
QVariant result;
bool ok;
if (type.isEmpty()) {
// ok
} else if (type == QLatin1String("number")) {
} else if (type == "number"_L1) {
// try integer first
bool ok;
qint64 v = text.toLongLong(&ok);
if (ok) {
result = v;
} else {
// let's see floating point
double d = text.toDouble(&ok);
result = d;
if (!ok) {
fprintf(stderr, "%lld:%lld: Invalid XML: could not interpret '%s' as a number.\n",
xml.lineNumber(), xml.columnNumber(), qPrintable(text.toString()));
exit(EXIT_FAILURE);
}
result = d;
}
} else if (type == QLatin1String("bytes")) {
} else if (type == "bytes"_L1) {
QByteArray data = text.toLatin1();
QStringView encoding = attrs.value("encoding");
if (encoding == QLatin1String("base64url")) {
if (encoding == "base64url"_L1) {
result = QByteArray::fromBase64(data, QByteArray::Base64UrlEncoding);
} else if (encoding == QLatin1String("hex")) {
} else if (encoding == "hex"_L1) {
result = QByteArray::fromHex(data);
} else if (encoding.isEmpty() || encoding == QLatin1String("base64")) {
} else if (encoding.isEmpty() || encoding == "base64"_L1) {
result = QByteArray::fromBase64(data);
} else {
fprintf(stderr, "%lld:%lld: Invalid XML: unknown encoding '%s' for bytes.\n",
xml.lineNumber(), xml.columnNumber(), qPrintable(encoding.toString()));
exit(EXIT_FAILURE);
}
} else if (type == QLatin1String("string")) {
} else if (type == "string"_L1) {
result = text.toString();
} else if (type == QLatin1String("null")) {
} else if (type == "null"_L1) {
result = QVariant::fromValue(nullptr);
} else if (type == QLatin1String("CBOR simple type")) {
} else if (type == "CBOR simple type"_L1) {
result = QVariant::fromValue(QCborSimpleType(text.toShort()));
} else if (type == QLatin1String("bits")) {
} else if (type == "bits"_L1) {
QBitArray ba;
ba.resize(text.size());
qsizetype n = 0;
@ -238,13 +236,13 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options
result = ba;
} else {
int id = QMetaType::UnknownType;
if (type == QLatin1String("datetime"))
if (type == "datetime"_L1)
id = QMetaType::QDateTime;
else if (type == QLatin1String("url"))
else if (type == "url"_L1)
id = QMetaType::QUrl;
else if (type == QLatin1String("uuid"))
else if (type == "uuid"_L1)
id = QMetaType::QUuid;
else if (type == QLatin1String("regex"))
else if (type == "regex"_L1)
id = QMetaType::QRegularExpression;
else
id = QMetaType::fromName(type.toLatin1()).id();
@ -267,8 +265,7 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options
} while (xml.isComment() || xml.isWhitespace());
if (!xml.isEndElement()) {
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
xml.lineNumber(), xml.columnNumber(),
fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", xml.lineNumber(), xml.columnNumber(),
qPrintable(xml.tokenString()), qPrintable(name.toString()));
exit(EXIT_FAILURE);
}
@ -287,9 +284,9 @@ static void variantToXml(QXmlStreamWriter &xml, const QVariant &v)
variantToXml(xml, v);
xml.writeEndElement();
} else if (type == QMetaType::QVariantMap || type == qMetaTypeId<VariantOrderedMap>()) {
const VariantOrderedMap map = (type == QMetaType::QVariantMap) ?
VariantOrderedMap(v.toMap()) :
qvariant_cast<VariantOrderedMap>(v);
const VariantOrderedMap map = (type == QMetaType::QVariantMap)
? VariantOrderedMap(v.toMap())
: qvariant_cast<VariantOrderedMap>(v);
xml.writeStartElement("map");
for (const auto &pair : map) {
@ -301,7 +298,7 @@ static void variantToXml(QXmlStreamWriter &xml, const QVariant &v)
xml.writeEndElement();
} else {
xml.writeStartElement("value");
QString typeString = QStringLiteral("type");
QString typeString = "type"_L1;
switch (type) {
case QMetaType::Short:
case QMetaType::UShort:
@ -399,37 +396,37 @@ static void variantToXml(QXmlStreamWriter &xml, const QVariant &v)
}
}
QString XmlConverter::name()
QString XmlConverter::name() const
{
return QStringLiteral("xml");
return "xml"_L1;
}
Converter::Direction XmlConverter::directions()
Converter::Directions XmlConverter::directions() const
{
return InOut;
return Direction::InOut;
}
Converter::Options XmlConverter::outputOptions()
Converter::Options XmlConverter::outputOptions() const
{
return SupportsArbitraryMapKeys;
}
const char *XmlConverter::optionsHelp()
const char *XmlConverter::optionsHelp() const
{
return xmlOptionHelp;
}
bool XmlConverter::probeFile(QIODevice *f)
bool XmlConverter::probeFile(QIODevice *f) const
{
if (QFile *file = qobject_cast<QFile *>(f)) {
if (file->fileName().endsWith(QLatin1String(".xml")))
if (file->fileName().endsWith(".xml"_L1))
return true;
}
return f->isReadable() && f->peek(5) == "<?xml";
}
QVariant XmlConverter::loadFile(QIODevice *f, Converter *&outputConverter)
QVariant XmlConverter::loadFile(QIODevice *f, const Converter *&outputConverter) const
{
if (!outputConverter)
outputConverter = this;
@ -445,13 +442,14 @@ QVariant XmlConverter::loadFile(QIODevice *f, Converter *&outputConverter)
return v;
}
void XmlConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
void XmlConverter::saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const
{
bool compact = false;
for (const QString &s : options) {
if (s == QLatin1String("compact=no")) {
if (s == "compact=no"_L1) {
compact = false;
} else if (s == QLatin1String("compact=yes")) {
} else if (s == "compact=yes"_L1) {
compact = true;
} else {
fprintf(stderr, "Unknown option '%s' to XML output. Valid options are:\n%s",

View File

@ -10,13 +10,14 @@ class XmlConverter : public Converter
{
// Converter interface
public:
QString name() override;
Direction directions() override;
Options outputOptions() override;
const char *optionsHelp() override;
bool probeFile(QIODevice *f) override;
QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
QString name() const override;
Directions directions() const override;
Options outputOptions() const override;
const char *optionsHelp() const override;
bool probeFile(QIODevice *f) const override;
QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const override;
void saveFile(QIODevice *f, const QVariant &contents,
const QStringList &options) const override;
};
#endif // XMLCONVERTER_H