Separate streaming dumper and converter in the convert example

The two were in the same files but mostly unrelated to one another -
aside from the converter defaulting to the dumper for output.
Furthermore, the dumper actually uses QDebug and QTextStream, not
QDataStream; rename it to reflect this reality.

Task-number: QTBUG-111228
Change-Id: Id65c120c319b555039f7fd186ed262f35ff5260a
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit eaebb5c4d2e2a87b23d63c5406bf54458b4c4a24)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Edward Welbourne 2023-08-29 19:10:48 +02:00 committed by Qt Cherry-pick Bot
parent ca9a3ba6c8
commit 2d9935cc6d
7 changed files with 124 additions and 102 deletions

View File

@ -22,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

@ -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

@ -2,10 +2,9 @@
// 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;
@ -16,8 +15,8 @@ static const char dataStreamOptionHelp[] =
static const char signature[] = "qds";
static DataStreamDumper dataStreamDumper;
static DataStreamConverter DataStreamConverter;
static DataStreamConverter dataStreamConverter;
static DebugTextDumper debugTextDumper;
QDataStream &operator<<(QDataStream &ds, const VariantOrderedMap &map)
{
@ -44,83 +43,6 @@ QDataStream &operator>>(QDataStream &ds, VariantOrderedMap &map)
return ds;
}
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 DataStreamDumper::name()
{
return "datastream-dump"_L1;
}
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>();
@ -154,7 +76,7 @@ bool DataStreamConverter::probeFile(QIODevice *f)
QVariant DataStreamConverter::loadFile(QIODevice *f, Converter *&outputConverter)
{
if (!outputConverter)
outputConverter = &dataStreamDumper;
outputConverter = &debugTextDumper;
char c;
if (f->read(sizeof(signature) - 1) != signature || !f->getChar(&c) || (c != 'l' && c != 'B')) {

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:

View File

@ -0,0 +1,88 @@
// 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()
{
return "debugtext-dump"_L1;
}
Converter::Direction DebugTextDumper::directions()
{
return Out;
}
Converter::Options DebugTextDumper::outputOptions()
{
return SupportsArbitraryMapKeys;
}
const char *DebugTextDumper::optionsHelp()
{
return nullptr;
}
bool DebugTextDumper::probeFile(QIODevice *f)
{
Q_UNUSED(f);
return false;
}
QVariant DebugTextDumper::loadFile(QIODevice *f, Converter *&outputConverter)
{
Q_UNREACHABLE();
Q_UNUSED(f);
Q_UNUSED(outputConverter);
return QVariant();
}
void DebugTextDumper::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
{
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,22 @@
// 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() 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;
};
#endif // DEBUGTEXTDUMPER_H

View File

@ -60,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