diff options
Diffstat (limited to 'examples/corelib/serialization/convert')
22 files changed, 734 insertions, 1272 deletions
diff --git a/examples/corelib/serialization/convert/CMakeLists.txt b/examples/corelib/serialization/convert/CMakeLists.txt index 14de45381a..24ad5bbb6a 100644 --- a/examples/corelib/serialization/convert/CMakeLists.txt +++ b/examples/corelib/serialization/convert/CMakeLists.txt @@ -1,42 +1,43 @@ -# Generated from convert.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(convert LANGUAGES CXX) -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") +if (ANDROID) + message(FATAL_ERROR "This project cannot be built on Android.") endif() -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/convert") +find_package(Qt6 REQUIRED COMPONENTS Core) -find_package(Qt6 COMPONENTS Core) +qt_standard_project_setup() qt_add_executable(convert cborconverter.cpp cborconverter.h - converter.h + converter.cpp converter.h datastreamconverter.cpp datastreamconverter.h + debugtextdumper.cpp debugtextdumper.h jsonconverter.cpp jsonconverter.h main.cpp nullconverter.cpp nullconverter.h textconverter.cpp textconverter.h + variantorderedmap.h xmlconverter.cpp xmlconverter.h ) -set_target_properties(convert PROPERTIES - WIN32_EXECUTABLE FALSE - MACOSX_BUNDLE FALSE -) -target_link_libraries(convert PUBLIC - Qt::Core + +target_link_libraries(convert PRIVATE + Qt6::Core ) install(TARGETS convert - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION . + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +qt_generate_deploy_app_script( + TARGET convert + OUTPUT_SCRIPT deploy_script + NO_UNSUPPORTED_PLATFORM_ERROR ) +install(SCRIPT ${deploy_script}) diff --git a/examples/corelib/serialization/convert/cborconverter.cpp b/examples/corelib/serialization/convert/cborconverter.cpp index 4fc8408983..969f2741e0 100644 --- a/examples/corelib/serialization/convert/cborconverter.cpp +++ b/examples/corelib/serialization/convert/cborconverter.cpp @@ -1,72 +1,29 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "cborconverter.h" +#include "variantorderedmap.h" +#include <QCborArray> +#include <QCborMap> #include <QCborStreamReader> #include <QCborStreamWriter> -#include <QCborMap> -#include <QCborArray> #include <QCborValue> #include <QDataStream> -#include <QFloat16> +#include <QDebug> #include <QFile> +#include <QFloat16> #include <QMetaType> #include <QTextStream> #include <stdio.h> +using namespace Qt::StringLiterals; + static CborConverter cborConverter; static CborDiagnosticDumper cborDiagnosticDumper; -static const char optionHelp[] = +static const char cborOptionHelp[] = "convert-float-to-int=yes|no Write integers instead of floating point, if no\n" " loss of precision occurs on conversion.\n" "float16=yes|always|no Write using half-precision floating point.\n" @@ -102,6 +59,7 @@ QT_END_NAMESPACE // non-string keys in CBOR maps (QVariantMap can't handle those). Instead, we // have our own set of converter functions so we can keep the keys properly. +//! [0] static QVariant convertCborValue(const QCborValue &value); static QVariant convertCborMap(const QCborMap &map) @@ -130,7 +88,9 @@ static QVariant convertCborValue(const QCborValue &value) return convertCborMap(value.toMap()); return value.toVariant(); } +//! [0] +//! [1] enum TrimFloatingPoint { Double, Float, Float16 }; static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrimming) { @@ -161,42 +121,30 @@ static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrim return QCborValue::fromVariant(v); } +//! [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) -{ - Q_UNUSED(f); - return false; -} - -QVariant CborDiagnosticDumper::loadFile(QIODevice *f, Converter *&outputConverter) -{ - Q_UNREACHABLE(); - Q_UNUSED(f); - Q_UNUSED(outputConverter); - 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) { @@ -219,14 +167,12 @@ void CborDiagnosticDumper::saveFile(QIODevice *f, const QVariant &contents, cons } } - fprintf(stderr, "Unknown CBOR diagnostic option '%s'. Available options are:\n%s", - qPrintable(s), diagnosticHelp); - exit(EXIT_FAILURE); + qFatal("Unknown CBOR diagnostic option '%s'. Available options are:\n%s", + qPrintable(s), diagnosticHelp); } QTextStream out(f); - out << convertFromVariant(contents, Double).toDiagnosticNotation(opts) - << Qt::endl; + out << convertFromVariant(contents, Double).toDiagnosticNotation(opts) << Qt::endl; } CborConverter::CborConverter() @@ -234,36 +180,36 @@ 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 optionHelp; + 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); } -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)) @@ -280,25 +226,24 @@ QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter) QCborValue contents = QCborValue::fromCbor(reader); qint64 offset = reader.currentOffset(); if (reader.lastError()) { - fprintf(stderr, "Error loading CBOR contents (byte %lld): %s\n", offset, - qPrintable(reader.lastError().toString())); - fprintf(stderr, " bytes: %s\n", - (ptr ? mapped.mid(offset, 9) : f->read(9)).toHex(' ').constData()); - exit(EXIT_FAILURE); + qFatal().nospace() + << "Error loading CBOR contents (byte " << offset + << "): " << reader.lastError().toString() + << "\n bytes: " << (ptr ? mapped.mid(offset, 9) : f->read(9)); } else if (offset < mapped.size() || (!ptr && f->bytesAvailable())) { - fprintf(stderr, "Warning: bytes remaining at the end of the CBOR stream\n"); + qWarning("Warning: bytes remaining at the end of the CBOR stream"); } if (outputConverter == nullptr) outputConverter = &cborDiagnosticDumper; - else if (outputConverter == null) + else if (isNull(outputConverter)) return QVariant(); else if (!outputConverter->outputOptions().testFlag(SupportsArbitraryMapKeys)) return contents.toVariant(); return convertCborValue(contents); } -void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) +void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) const { bool useSignature = true; bool useIntegers = true; @@ -354,13 +299,13 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri } } - fprintf(stderr, "Unknown CBOR format option '%s'. Valid options are:\n%s", - qPrintable(s), optionHelp); - exit(EXIT_FAILURE); + qFatal("Unknown CBOR format option '%s'. Valid options are:\n%s", + qPrintable(s), cborOptionHelp); } - 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); @@ -374,4 +319,3 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri opts |= QCborValue::UseFloat16; v.toCbor(writer, opts); } - diff --git a/examples/corelib/serialization/convert/cborconverter.h b/examples/corelib/serialization/convert/cborconverter.h index f0a89cb141..db68f99fda 100644 --- a/examples/corelib/serialization/convert/cborconverter.h +++ b/examples/corelib/serialization/convert/cborconverter.h @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef CBORCONVERTER_H #define CBORCONVERTER_H @@ -57,13 +10,12 @@ 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; + void saveFile(QIODevice *f, const QVariant &contents, + const QStringList &options) const override; }; class CborConverter : public Converter @@ -73,13 +25,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 diff --git a/examples/corelib/serialization/convert/convert.pro b/examples/corelib/serialization/convert/convert.pro index 4c6b0b557a..7592de7a22 100644 --- a/examples/corelib/serialization/convert/convert.pro +++ b/examples/corelib/serialization/convert/convert.pro @@ -11,18 +11,22 @@ target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/convert INSTALLS += target SOURCES += main.cpp \ + converter.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 + variantorderedmap.h \ + xmlconverter.h diff --git a/examples/corelib/serialization/convert/converter.cpp b/examples/corelib/serialization/convert/converter.cpp new file mode 100644 index 0000000000..a57f305971 --- /dev/null +++ b/examples/corelib/serialization/convert/converter.cpp @@ -0,0 +1,44 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "converter.h" + +//! [0] +Converter::Converter() +{ + converters().append(this); +} + +Converter::~Converter() +{ + converters().removeAll(this); +} + +QList<const Converter *> &Converter::converters() +{ + Q_CONSTINIT static QList<const Converter *> store; + return store; +} + +const QList<const Converter *> &Converter::allConverters() +{ + return converters(); +} +//! [0] + +// Some virtual methods that Converter classes needn't override, when not relevant: +Converter::Options Converter::outputOptions() const { return {}; } +const char *Converter::optionsHelp() const { return nullptr; } +bool Converter::probeFile(QIODevice *) const { return false; } + +// The virtual method they should override if they claim to support In: +QVariant Converter::loadFile(QIODevice *, const Converter *&outputConverter) const +{ + Q_ASSERT(!directions().testFlag(Converter::Direction::In)); + // For those that don't, this should never be called. + Q_UNIMPLEMENTED(); + // But every implementation should at least do this: + if (!outputConverter) + outputConverter = this; + return QVariant(); +} diff --git a/examples/corelib/serialization/convert/converter.h b/examples/corelib/serialization/convert/converter.h index 56b501a076..40b7575a1e 100644 --- a/examples/corelib/serialization/convert/converter.h +++ b/examples/corelib/serialization/convert/converter.h @@ -1,103 +1,45 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef CONVERTER_H #define CONVERTER_H #include <QIODevice> -#include <QPair> -#include <QVariant> #include <QList> +#include <QStringList> +#include <QVariant> -class VariantOrderedMap : public QList<QPair<QVariant, QVariant>> -{ -public: - VariantOrderedMap() = default; - VariantOrderedMap(const QVariantMap &map) - { - reserve(map.size()); - for (auto it = map.begin(); it != map.end(); ++it) - append({it.key(), it.value()}); - } -}; -using Map = VariantOrderedMap; -Q_DECLARE_METATYPE(Map) - +//! [0] class Converter { + static QList<const Converter *> &converters(); protected: Converter(); + static bool isNull(const Converter *converter); // in nullconverter.cpp public: - static Converter *null; + static const QList<const Converter *> &allConverters(); - 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; + virtual const char *optionsHelp() const; + virtual bool probeFile(QIODevice *f) const; + virtual QVariant loadFile(QIODevice *f, const Converter *&outputConverter) const; + 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) +//! [0] #endif // CONVERTER_H diff --git a/examples/corelib/serialization/convert/datastreamconverter.cpp b/examples/corelib/serialization/convert/datastreamconverter.cpp index c459696b26..ce28fcb98e 100644 --- a/examples/corelib/serialization/convert/datastreamconverter.cpp +++ b/examples/corelib/serialization/convert/datastreamconverter.cpp @@ -1,68 +1,23 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "datastreamconverter.h" +#include "debugtextdumper.h" +#include "variantorderedmap.h" #include <QDataStream> -#include <QDebug> -#include <QTextStream> -static const char optionHelp[] = +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) { @@ -89,126 +44,44 @@ 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 optionHelp; + 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')) { - fprintf(stderr, "Could not load QDataStream file: invalid signature.\n"); - exit(EXIT_FAILURE); - } + if (f->read(sizeof(signature) - 1) != signature || !f->getChar(&c) || (c != 'l' && c != 'B')) + qFatal("Could not load QDataStream file: invalid signature."); QDataStream ds(f); ds.setByteOrder(c == 'l' ? QDataStream::LittleEndian : QDataStream::BigEndian); @@ -222,9 +95,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('='); @@ -249,18 +123,16 @@ void DataStreamConverter::saveFile(QIODevice *f, const QVariant &contents, const continue; } - fprintf(stderr, "Invalid version number '%s': must be a number from 1 to %d.\n", - qPrintable(pair.last()), QDataStream::Qt_DefaultCompiledVersion); - exit(EXIT_FAILURE); + qFatal("Invalid version number '%s': must be a number from 1 to %d.", + qPrintable(pair.last()), QDataStream::Qt_DefaultCompiledVersion); } } - fprintf(stderr, "Unknown QDataStream formatting option '%s'. Available options are:\n%s", - qPrintable(option), optionHelp); - exit(EXIT_FAILURE); + qFatal("Unknown QDataStream formatting option '%s'. Available options are:\n%s", + qPrintable(option), dataStreamOptionHelp); } - char c = order == QDataStream::LittleEndian ? 'l' : 'B'; + char c = order == QDataStream::LittleEndian ? 'l' : 'B'; f->write(signature); f->write(&c, 1); diff --git a/examples/corelib/serialization/convert/datastreamconverter.h b/examples/corelib/serialization/convert/datastreamconverter.h index 1b74abc54f..201f3c4754 100644 --- a/examples/corelib/serialization/convert/datastreamconverter.h +++ b/examples/corelib/serialization/convert/datastreamconverter.h @@ -1,71 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef DATASTREAMCONVERTER_H #define DATASTREAMCONVERTER_H #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: @@ -73,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 diff --git a/examples/corelib/serialization/convert/debugtextdumper.cpp b/examples/corelib/serialization/convert/debugtextdumper.cpp new file mode 100644 index 0000000000..f010bd8e2a --- /dev/null +++ b/examples/corelib/serialization/convert/debugtextdumper.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "debugtextdumper.h" +#include "variantorderedmap.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; +} + +void DebugTextDumper::saveFile(QIODevice *f, const QVariant &contents, + const QStringList &options) const +{ + if (!options.isEmpty()) { + qFatal("Unknown option '%s' to debug text output. This format has no options.", + qPrintable(options.first())); + } + QString s = dumpVariant(contents); + s[s.size() - 1] = u'\n'; // replace the comma with newline + + QTextStream out(f); + out << s; +} diff --git a/examples/corelib/serialization/convert/debugtextdumper.h b/examples/corelib/serialization/convert/debugtextdumper.h new file mode 100644 index 0000000000..7d3d762104 --- /dev/null +++ b/examples/corelib/serialization/convert/debugtextdumper.h @@ -0,0 +1,20 @@ +// 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; + void saveFile(QIODevice *f, const QVariant &contents, + const QStringList &options) const override; +}; + +#endif // DEBUGTEXTDUMPER_H diff --git a/examples/corelib/serialization/convert/doc/images/convert.png b/examples/corelib/serialization/convert/doc/images/convert.png Binary files differnew file mode 100644 index 0000000000..53e05b4333 --- /dev/null +++ b/examples/corelib/serialization/convert/doc/images/convert.png diff --git a/examples/corelib/serialization/convert/doc/src/convert.qdoc b/examples/corelib/serialization/convert/doc/src/convert.qdoc new file mode 100644 index 0000000000..187e81a85e --- /dev/null +++ b/examples/corelib/serialization/convert/doc/src/convert.qdoc @@ -0,0 +1,156 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example serialization/convert + \examplecategory {Data Processing & I/O} + \meta tag {network} + \title Serialization Converter + + \brief How to convert between different serialization formats. + + This example converts between JSON, CBOR, XML, QDataStream and some simple + text formats. It can auto-detect the format being used, or be told which + format to use. Not all formats support both input and output, and they have + different sets of which content datatypes they support. QDataStream and XML + are the richest, followed by CBOR, then JSON, and then the plain text + formats. Conversion via the less capable formats is apt to lose structure + from the data. + + \image convert.png + + \sa {Parsing and displaying CBOR data}, {Saving and Loading a Game} + + \section1 The Converter Class + + The Converter class is the abstract superclass for all the converters to and + from all the formats. They all convert from or to the QVariant class, which + is used to represent all the datastructures internally. + + \snippet serialization/convert/converter.h 0 + + The Converter constructor and destructor manage a list of available + converters used by the main program so that it knows what converters are + available. Each converter type defines a static instance that ensures it is + constructed and thus available to the main program via this list. The \c + allConverters() method provides \c main()'s code with access to the list. + + \snippet serialization/convert/converter.cpp 0 + + The name() function returns the name of the converter. The directions() + function is used to determine if a converter can be used for input, output, + or both. These enable the main program to report what converters are + available in its help text for the command-line options to select input and + output formats. + + \snippet serialization/convert/main.cpp 0 + + The optionsHelp() function is used to report the various command-line + options supported by the available formats, when queried using its \c + {--format-options <format>} command-line option. + + \snippet serialization/convert/main.cpp 1 + + The outputOptions() function reports the output capabilities of a converter. + At present the only optional feature is support for arbitrary keys in + mappings from keys to values. An input converter's loadFile() can use this + information to tailor the form in which it presents the data it has read, to + be as faithfully represented by the output converter as its capabilities + permit. + + The probeFile() function is used to determine if a file matches the format + of the converter. The main program uses this to determine what format to use + when reading or writing a file, based on its name and potentially content, + when the user has not specified the format to use on the command-line. + + The loadFile() function deserializes data. The caller tells loadFile() which + serializer it intends to use, so that loadFile() can query its + outputOptions() to determine the form in which to represent the loaded data. + If the caller hasn't settled on a choice of output converter, loadFile() + supplies it with a default output converter suitable to the data it is + returning. + + The saveFile() function serializes data. It is passed options from the + command-line, as described by loadHelp(), that can tune the details of how + it represents the data when saving to file. + + Both loadFile() and saveFile() can be used with an arbitrary \l QIODevice. + This means that a Converter could also be used with a network socket or + other source of data, to read from or write to. In the present program, the + main program always passes a \l QFile, accessing either a file on disk or + one of the standard streams of the process. + + \section2 The Available Converters + + Several converters are supported, illustrating how the converter program + could be adapted to other formats, should the need arise. See the source + code for each for its details. The CBOR converters serve as a relatively + full-featured illustration of the ways converters can work, that we'll look + into in more detail below. This table summarizes the available converters: + + \table + \header \li Class \li mode \li format + \row \li CborConverter \li In/Out \li CBOR + \row \li CborDiagnosticDumper \li Out \li CBOR diagnostic + \row \li DataStreamConverter \li In/Out \li QDataStream + \row \li DebugTextDumper \li Out \li Lossless, non-standard, human-readable + \row \li JsonConverter \li In/Out \li JSON + \row \li NullConverter \li Out \li No output + \row \li TextConverter \li In/Out \li Structured plain text + \row \li XmlConverter \li In/Out \li XML + \endtable + + Those that support input use themselves as loadFile()'s fallback converter, + except for the CBOR and QDataStream converters, which use their respective + output-only dumper companion classes. The null converter can be used as + output converter when running the program for the sake of any validation or + verification that an input converter may perform. + + \section2 The CborConverter and CborDiagnosticDumper Classes + + The CborConverter class supports serializing to and from the CBOR format. + It supports various options to configure the output of floating point values + and a \c{signature} option to determine whether to start its output with a + CBOR tag that serves as a file header, identifying the file as containing + CBOR data. + + There is also a CborDiagnosticDumper class to output in CBOR diagnostic + notation. It does not support loading data. The form of its output can be + configured using two options. One selects whether to use the (more verbose) + extended CBOR diagnostic format. The other control whether each CBOR value + appears on a separate line. + + The plain diagnostic notation is similar to JSON, but not exactly, because + it supports displaying the contents of a CBOR stream losslessly, while a + conversion to JSON can be lossy. CborConverter's loadFile() uses + CborDiagnosticDumper for the fallback output converter, if its caller hasn't + determined the output format for itself. + + The convertCborValue(), convertCborMap() and convertCborArray() helper + functions are used to convert a QCborValue to a QVariant, for the benefit of + CborConverter::loadFile(). + + \snippet serialization/convert/cborconverter.cpp 0 + + The convertFromVariant() function is used to convert a QVariant to a + QCborValue for output by the \c saveFile() of either class. + + \snippet serialization/convert/cborconverter.cpp 1 + + \sa {CBOR Support in Qt} + + \section1 The convert program + + The \c main() function sets up a \l QApplication and a \l QCommandLineParser + to make sense of the options the user has specified and provide help if the + user asks for it. It uses the values obtained for the various \l + QCommandLineOption instances describing the user's choices, plus the + positional arguments for file names, to prepare the converters it will use. + + It then uses its input converter to load data (and possibly resolve its + choice of output converter, if it hasn't selected one yet) and its output + converter to serialize that data, taking account of any output options the + user has supplied on the command-line. + + \snippet serialization/convert/main.cpp 2 +*/ diff --git a/examples/corelib/serialization/convert/jsonconverter.cpp b/examples/corelib/serialization/convert/jsonconverter.cpp index ec24af703d..1b59ed5c1f 100644 --- a/examples/corelib/serialization/convert/jsonconverter.cpp +++ b/examples/corelib/serialization/convert/jsonconverter.cpp @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "jsonconverter.h" @@ -56,49 +9,39 @@ #include <QJsonObject> #include <QJsonValue> +using namespace Qt::StringLiterals; + static JsonConverter jsonConverter; -static const char optionHelp[] = - "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) { QJsonDocument doc = QJsonDocument::fromVariant(v); - if (!doc.isObject() && !doc.isArray()) { - fprintf(stderr, "Could not convert contents to JSON.\n"); - exit(EXIT_FAILURE); - } + if (!doc.isObject() && !doc.isArray()) + qFatal("Could not convert contents to JSON."); return doc; } -JsonConverter::JsonConverter() -{ -} - -QString JsonConverter::name() -{ - return "json"; -} - -Converter::Direction JsonConverter::directions() +QString JsonConverter::name() const { - return InOut; + return "json"_L1; } -Converter::Options JsonConverter::outputOptions() +Converter::Directions JsonConverter::directions() const { - return {}; + return Direction::InOut; } -const char *JsonConverter::optionsHelp() +const char *JsonConverter::optionsHelp() const { - return optionHelp; + 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; } @@ -109,7 +52,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; @@ -125,26 +68,26 @@ QVariant JsonConverter::loadFile(QIODevice *f, Converter *&outputConverter) if (doc.isNull()) doc = QJsonDocument::fromJson(f->readAll(), &error); if (error.error) { - fprintf(stderr, "Could not parse JSON content: offset %d: %s", - error.offset, qPrintable(error.errorString())); - exit(EXIT_FAILURE); + qFatal("Could not parse JSON content: offset %d: %s", + error.offset, qPrintable(error.errorString())); } - if (outputConverter == null) + if (isNull(outputConverter)) return QVariant(); 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", qPrintable(s), optionHelp); - exit(EXIT_FAILURE); + qFatal("Unknown option '%s' to JSON output. Valid options are:\n%s", + qPrintable(s), jsonOptionHelp); } } diff --git a/examples/corelib/serialization/convert/jsonconverter.h b/examples/corelib/serialization/convert/jsonconverter.h index 445a0e6695..e1dd1ecdb4 100644 --- a/examples/corelib/serialization/convert/jsonconverter.h +++ b/examples/corelib/serialization/convert/jsonconverter.h @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef JSONCONVERTER_H #define JSONCONVERTER_H @@ -55,18 +8,15 @@ 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; + 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 diff --git a/examples/corelib/serialization/convert/main.cpp b/examples/corelib/serialization/convert/main.cpp index 161fec6bcd..d3021fadca 100644 --- a/examples/corelib/serialization/convert/main.cpp +++ b/examples/corelib/serialization/convert/main.cpp @@ -1,52 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "converter.h" @@ -58,177 +12,144 @@ #include <stdio.h> -static QList<Converter *> *availableConverters; +using namespace Qt::StringLiterals; -Converter::Converter() +static const Converter *prepareConverter(QString format, Converter::Direction direction, + QFile *stream) { - if (!availableConverters) - availableConverters = new QList<Converter *>; - availableConverters->append(this); -} + const bool out = direction == Converter::Direction::Out; + const QIODevice::OpenMode mode = out + ? QIODevice::WriteOnly | QIODevice::Truncate + : QIODevice::ReadOnly; + const char *dirn = out ? "output" : "input"; + + if (stream->fileName().isEmpty()) + stream->open(out ? stdout : stdin, mode); + else + stream->open(mode); + + if (!stream->isOpen()) { + qFatal("Could not open \"%s\" for %s: %s", + qPrintable(stream->fileName()), dirn, qPrintable(stream->errorString())); + } else if (format == "auto"_L1) { + for (const Converter *conv : Converter::allConverters()) { + if (conv->directions().testFlag(direction) && conv->probeFile(stream)) + return conv; + } + if (out) // Failure to identify output format can be remedied by loadFile(). + return nullptr; -Converter::~Converter() -{ - availableConverters->removeAll(this); + // Input format, however, we must know before we can call that: + qFatal("Could not determine input format. Specify it with the -I option."); + } else { + for (const Converter *conv : Converter::allConverters()) { + if (conv->name() == format) { + if (!conv->directions().testFlag(direction)) { + qWarning("File format \"%s\" cannot be used for %s", + qPrintable(format), dirn); + continue; // on the off chance there's another with the same name + } + return conv; + } + } + qFatal("Unknown %s file format \"%s\"", dirn, qPrintable(format)); + } + Q_UNREACHABLE_RETURN(nullptr); } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); +//! [0] QStringList inputFormats; QStringList outputFormats; - for (Converter *conv : qAsConst(*availableConverters)) { + for (const Converter *conv : Converter::allConverters()) { 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; } +//! [0] 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 serialization 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 : qAsConst(*availableConverters)) { +//! [1] + for (const Converter *conv : Converter::allConverters()) { 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 - printf("Format '%s' supports no options.\n", qPrintable(format)); + if (help) { + qInfo("The following options are available for format '%s':\n\n%s", + qPrintable(format), help); + } else { + qInfo("Format '%s' supports no options.", qPrintable(format)); + } return EXIT_SUCCESS; } } +//! [1] - fprintf(stderr, "Unknown file format '%s'\n", qPrintable(format)); - return EXIT_FAILURE; - } - - Converter *inconv = nullptr; - QString format = parser.value(inputFormatOption); - if (format != "auto") { - for (Converter *conv : qAsConst(*availableConverters)) { - if (conv->name() == format) { - inconv = conv; - break; - } - } - - if (!inconv) { - fprintf(stderr, "Unknown file format \"%s\"\n", qPrintable(format)); - return EXIT_FAILURE; - } - } - - Converter *outconv = nullptr; - format = parser.value(outputFormatOption); - if (format != "auto") { - for (Converter *conv : qAsConst(*availableConverters)) { - if (conv->name() == format) { - outconv = conv; - break; - } - } - - if (!outconv) { - fprintf(stderr, "Unknown file format \"%s\"\n", qPrintable(format)); - return EXIT_FAILURE; - } + qFatal("Unknown file format '%s'", qPrintable(format)); } +//! [2] QStringList files = parser.positionalArguments(); QFile input(files.value(0)); QFile output(files.value(1)); + const Converter *inconv = prepareConverter(parser.value(inputFormatOption), + Converter::Direction::In, &input); + const Converter *outconv = prepareConverter(parser.value(outputFormatOption), + Converter::Direction::Out, &output); - if (input.fileName().isEmpty()) - input.open(stdin, QIODevice::ReadOnly); - else - input.open(QIODevice::ReadOnly); - if (!input.isOpen()) { - fprintf(stderr, "Could not open \"%s\" for reading: %s\n", - qPrintable(input.fileName()), qPrintable(input.errorString())); - return EXIT_FAILURE; - } - - if (output.fileName().isEmpty()) - output.open(stdout, QIODevice::WriteOnly | QIODevice::Truncate); - else - output.open(QIODevice::WriteOnly | QIODevice::Truncate); - if (!output.isOpen()) { - fprintf(stderr, "Could not open \"%s\" for writing: %s\n", - qPrintable(output.fileName()), qPrintable(output.errorString())); - return EXIT_FAILURE; - } - - if (!inconv) { - // probe the input to find a file format - for (Converter *conv : qAsConst(*availableConverters)) { - if (conv->directions() & Converter::In && conv->probeFile(&input)) { - inconv = conv; - break; - } - } - - if (!inconv) { - fprintf(stderr, "Could not determine input format. pass -I option.\n"); - return EXIT_FAILURE; - } - } - - if (!outconv) { - // probe the output to find a file format - for (Converter *conv : qAsConst(*availableConverters)) { - if (conv->directions() & Converter::Out && conv->probeFile(&output)) { - outconv = conv; - break; - } - } - } - - // now finally perform the conversion + // Now finally perform the conversion: QVariant data = inconv->loadFile(&input, outconv); - Q_ASSERT_X(outconv, "Converter Tool", + Q_ASSERT_X(outconv, "Serialization Converter", "Internal error: converter format did not provide default"); outconv->saveFile(&output, data, parser.values(optionOption)); return EXIT_SUCCESS; +//! [2] } diff --git a/examples/corelib/serialization/convert/nullconverter.cpp b/examples/corelib/serialization/convert/nullconverter.cpp index 2de492e64e..fb8be5c944 100644 --- a/examples/corelib/serialization/convert/nullconverter.cpp +++ b/examples/corelib/serialization/convert/nullconverter.cpp @@ -1,97 +1,37 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "nullconverter.h" -static NullConverter nullConverter; -Converter* Converter::null = &nullConverter; - -QString NullConverter::name() -{ - return QLatin1String("null"); -} - -Converter::Direction NullConverter::directions() -{ - return Out; -} +using namespace Qt::StringLiterals; -Converter::Options NullConverter::outputOptions() +static NullConverter nullConverter; +bool Converter::isNull(const Converter *converter) { - return SupportsArbitraryMapKeys; + return converter == &nullConverter; } -const char *NullConverter::optionsHelp() +QString NullConverter::name() const { - return nullptr; + return "null"_L1; } -bool NullConverter::probeFile(QIODevice *f) +Converter::Directions NullConverter::directions() const { - Q_UNUSED(f); - return false; + return Direction::Out; } -QVariant NullConverter::loadFile(QIODevice *f, Converter *&outputConverter) +Converter::Options NullConverter::outputOptions() const { - Q_UNUSED(f); - Q_UNUSED(outputConverter); - outputConverter = this; - return QVariant(); + return SupportsArbitraryMapKeys; } -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())); - exit(EXIT_FAILURE); + qFatal("Unknown option '%s' to null output. This format has no options.", + qPrintable(options.first())); } Q_UNUSED(f); diff --git a/examples/corelib/serialization/convert/nullconverter.h b/examples/corelib/serialization/convert/nullconverter.h index af7339f092..1bdf9f22f7 100644 --- a/examples/corelib/serialization/convert/nullconverter.h +++ b/examples/corelib/serialization/convert/nullconverter.h @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef NULLCONVERTER_H #define NULLCONVERTER_H @@ -57,13 +10,11 @@ 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; + void saveFile(QIODevice *f, const QVariant &contents, + const QStringList &options) const override; }; #endif // NULLCONVERTER_H diff --git a/examples/corelib/serialization/convert/textconverter.cpp b/examples/corelib/serialization/convert/textconverter.cpp index ae03b9a334..1f8b4f9c19 100644 --- a/examples/corelib/serialization/convert/textconverter.cpp +++ b/examples/corelib/serialization/convert/textconverter.cpp @@ -1,58 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "textconverter.h" #include <QFile> #include <QTextStream> +using namespace Qt::StringLiterals; + static void dumpVariant(QTextStream &out, const QVariant &v) { switch (v.userType()) { @@ -89,68 +44,52 @@ static void dumpVariant(QTextStream &out, const QVariant &v) } } -QString TextConverter::name() -{ - return QStringLiteral("text"); -} - -Converter::Direction TextConverter::directions() -{ - return InOut; -} - -Converter::Options TextConverter::outputOptions() +QString TextConverter::name() const { - return {}; + return "text"_L1; } -const char *TextConverter::optionsHelp() +Converter::Directions TextConverter::directions() const { - return nullptr; + return Direction::InOut; } -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) { - list.append(v); - continue; - } - double d = line.toDouble(&ok); - if (ok) { + if (qint64 v = line.toLongLong(&ok); ok) + list.append(v); + 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())); - exit(EXIT_FAILURE); + qFatal("Unknown option '%s' to text output. This format has no options.", + qPrintable(options.first())); } QTextStream out(f); diff --git a/examples/corelib/serialization/convert/textconverter.h b/examples/corelib/serialization/convert/textconverter.h index 66f5136c02..526f295517 100644 --- a/examples/corelib/serialization/convert/textconverter.h +++ b/examples/corelib/serialization/convert/textconverter.h @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef TEXTCONVERTER_H #define TEXTCONVERTER_H @@ -55,16 +8,14 @@ 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; + 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 diff --git a/examples/corelib/serialization/convert/variantorderedmap.h b/examples/corelib/serialization/convert/variantorderedmap.h new file mode 100644 index 0000000000..c65316b182 --- /dev/null +++ b/examples/corelib/serialization/convert/variantorderedmap.h @@ -0,0 +1,24 @@ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef VARIANTORDEREDMAP_H +#define VARIANTORDEREDMAP_H + +#include <QList> +#include <QPair> +#include <QVariant> +#include <QVariantMap> + +class VariantOrderedMap : public QList<QPair<QVariant, QVariant>> +{ +public: + VariantOrderedMap() = default; + VariantOrderedMap(const QVariantMap &map) + { + reserve(map.size()); + for (auto it = map.begin(); it != map.end(); ++it) + append({it.key(), it.value()}); + } +}; + +#endif // VARIANTORDEREDMAP_H diff --git a/examples/corelib/serialization/convert/xmlconverter.cpp b/examples/corelib/serialization/convert/xmlconverter.cpp index c2811c5745..ef71fecb9f 100644 --- a/examples/corelib/serialization/convert/xmlconverter.cpp +++ b/examples/corelib/serialization/convert/xmlconverter.cpp @@ -1,54 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "xmlconverter.h" +#include "variantorderedmap.h" #include <QBitArray> #include <QtCborCommon> @@ -60,8 +14,9 @@ #include <QXmlStreamReader> #include <QXmlStreamWriter> -static const char optionHelp[] = - "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; @@ -70,7 +25,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: @@ -94,20 +49,19 @@ static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options option break; } - fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", - xml.lineNumber(), xml.columnNumber(), - qPrintable(xml.tokenString()), qPrintable(xml.name().toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML %s '%s'.", xml.lineNumber(), xml.columnNumber(), + qPrintable(xml.tokenString()), qPrintable(xml.name().toString())); } xml.readNext(); 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: @@ -136,10 +90,8 @@ static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml, Conv break; } - fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", - xml.lineNumber(), xml.columnNumber(), - qPrintable(xml.tokenString()), qPrintable(xml.name().toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML %s '%s'.", xml.lineNumber(), xml.columnNumber(), + qPrintable(xml.tokenString()), qPrintable(xml.name().toString())); } return { key, value }; @@ -150,11 +102,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); @@ -181,10 +133,8 @@ static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options) break; } - fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n", - xml.lineNumber(), xml.columnNumber(), - qPrintable(xml.tokenString()), qPrintable(xml.name().toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML %s '%s'.", xml.lineNumber(), xml.columnNumber(), + qPrintable(xml.tokenString()), qPrintable(xml.name().toString())); } xml.readNext(); @@ -196,18 +146,17 @@ 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")) { - fprintf(stderr, "%lld:%lld: Invalid XML key '%s'.\n", - xml.lineNumber(), xml.columnNumber(), qPrintable(name.toString())); - exit(EXIT_FAILURE); + if (name != "value"_L1) { + qFatal("%lld:%lld: Invalid XML key '%s'.", + xml.lineNumber(), xml.columnNumber(), qPrintable(name.toString())); } QXmlStreamAttributes attrs = xml.attributes(); - QStringView type = attrs.value(QLatin1String("type")); + QStringView type = attrs.value("type"_L1); forever { xml.readNext(); @@ -216,10 +165,8 @@ 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(), - qPrintable(xml.tokenString()), qPrintable(name.toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML %s '%s'.", xml.lineNumber(), xml.columnNumber(), + qPrintable(xml.tokenString()), qPrintable(name.toString())); } QStringView text = xml.text(); @@ -227,45 +174,43 @@ 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); + qFatal("%lld:%lld: Invalid XML: could not interpret '%s' as a number.", + xml.lineNumber(), xml.columnNumber(), qPrintable(text.toString())); } + 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); + qFatal("%lld:%lld: Invalid XML: unknown encoding '%s' for bytes.", + xml.lineNumber(), xml.columnNumber(), qPrintable(encoding.toString())); } - } 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; @@ -276,36 +221,33 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options } else if (c == '0') { ++n; } else if (!c.isSpace()) { - fprintf(stderr, "%lld:%lld: Invalid XML: invalid bit string '%s'.\n", - xml.lineNumber(), xml.columnNumber(), qPrintable(text.toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML: invalid bit string '%s'.", + xml.lineNumber(), xml.columnNumber(), qPrintable(text.toString())); } } ba.resize(n); 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(); if (id == QMetaType::UnknownType) { - fprintf(stderr, "%lld:%lld: Invalid XML: unknown type '%s'.\n", - xml.lineNumber(), xml.columnNumber(), qPrintable(type.toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML: unknown type '%s'.", + xml.lineNumber(), xml.columnNumber(), qPrintable(type.toString())); } result = text.toString(); if (!result.convert(QMetaType(id))) { - fprintf(stderr, "%lld:%lld: Invalid XML: could not parse content as type '%s'.\n", - xml.lineNumber(), xml.columnNumber(), qPrintable(type.toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML: could not parse content as type '%s'.", + xml.lineNumber(), xml.columnNumber(), qPrintable(type.toString())); } } @@ -314,10 +256,8 @@ 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(), - qPrintable(xml.tokenString()), qPrintable(name.toString())); - exit(EXIT_FAILURE); + qFatal("%lld:%lld: Invalid XML %s '%s'.", xml.lineNumber(), xml.columnNumber(), + qPrintable(xml.tokenString()), qPrintable(name.toString())); } xml.readNext(); @@ -334,9 +274,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) { @@ -348,7 +288,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: @@ -437,8 +377,7 @@ static void variantToXml(QXmlStreamWriter &xml, const QVariant &v) xml.writeAttribute(typeString, QString::fromLatin1(typeName)); xml.writeCharacters(copy.toString()); } else { - fprintf(stderr, "XML: don't know how to serialize type '%s'.\n", typeName); - exit(EXIT_FAILURE); + qFatal("XML: don't know how to serialize type '%s'.", typeName); } } } @@ -446,37 +385,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 optionHelp; + 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; @@ -484,25 +423,24 @@ QVariant XmlConverter::loadFile(QIODevice *f, Converter *&outputConverter) QXmlStreamReader xml(f); xml.readNextStartElement(); QVariant v = variantFromXml(xml, outputConverter->outputOptions()); - if (xml.hasError()) { - fprintf(stderr, "XML error: %s", qPrintable(xml.errorString())); - exit(EXIT_FAILURE); - } + if (xml.hasError()) + qFatal("XML error: %s", qPrintable(xml.errorString())); 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", qPrintable(s), optionHelp); - exit(EXIT_FAILURE); + qFatal("Unknown option '%s' to XML output. Valid options are:\n%s", + qPrintable(s), xmlOptionHelp); } } diff --git a/examples/corelib/serialization/convert/xmlconverter.h b/examples/corelib/serialization/convert/xmlconverter.h index 8fc0fea592..4888b0616f 100644 --- a/examples/corelib/serialization/convert/xmlconverter.h +++ b/examples/corelib/serialization/convert/xmlconverter.h @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef XMLCONVERTER_H #define XMLCONVERTER_H @@ -57,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 |