summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qstringconverter_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qstringconverter_base.h')
-rw-r--r--src/corelib/text/qstringconverter_base.h176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/corelib/text/qstringconverter_base.h b/src/corelib/text/qstringconverter_base.h
new file mode 100644
index 0000000000..d6b6fcb484
--- /dev/null
+++ b/src/corelib/text/qstringconverter_base.h
@@ -0,0 +1,176 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QSTRINGCONVERTER_BASE_H
+#define QSTRINGCONVERTER_BASE_H
+
+#if 0
+// QStringConverter(Base) class are handled in qstringconverter
+#pragma qt_sync_stop_processing
+#endif
+
+#include <optional>
+
+#include <QtCore/qglobal.h> // QT_{BEGIN,END}_NAMESPACE
+#include <QtCore/qflags.h> // Q_DECLARE_FLAGS
+#include <QtCore/qcontainerfwd.h>
+
+#include <cstring>
+
+QT_BEGIN_NAMESPACE
+
+class QByteArrayView;
+class QChar;
+class QByteArrayView;
+class QStringView;
+
+class QStringConverterBase
+{
+public:
+ enum class Flag {
+ Default = 0,
+ Stateless = 0x1,
+ ConvertInvalidToNull = 0x2,
+ WriteBom = 0x4,
+ ConvertInitialBom = 0x8,
+ UsesIcu = 0x10,
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ struct State {
+ constexpr State(Flags f = Flag::Default) noexcept
+ : flags(f), state_data{0, 0, 0, 0} {}
+ ~State() { clear(); }
+
+ State(State &&other) noexcept
+ : flags(other.flags),
+ remainingChars(other.remainingChars),
+ invalidChars(other.invalidChars),
+ state_data{other.state_data[0], other.state_data[1],
+ other.state_data[2], other.state_data[3]},
+ clearFn(other.clearFn)
+ { other.clearFn = nullptr; }
+ State &operator=(State &&other) noexcept
+ {
+ clear();
+ flags = other.flags;
+ remainingChars = other.remainingChars;
+ invalidChars = other.invalidChars;
+ std::memmove(state_data, other.state_data, sizeof state_data); // self-assignment-safe
+ clearFn = other.clearFn;
+ other.clearFn = nullptr;
+ return *this;
+ }
+ Q_CORE_EXPORT void clear() noexcept;
+ Q_CORE_EXPORT void reset() noexcept;
+
+ Flags flags;
+ int internalState = 0;
+ qsizetype remainingChars = 0;
+ qsizetype invalidChars = 0;
+
+ union {
+ uint state_data[4];
+ void *d[2];
+ };
+ using ClearDataFn = void (*)(State *) noexcept;
+ ClearDataFn clearFn = nullptr;
+ private:
+ Q_DISABLE_COPY(State)
+ };
+protected:
+ ~QStringConverterBase() = default;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStringConverterBase::Flags)
+
+class QStringConverter : public QStringConverterBase
+{
+public:
+
+ enum Encoding {
+ Utf8,
+#ifndef QT_BOOTSTRAPPED
+ Utf16,
+ Utf16LE,
+ Utf16BE,
+ Utf32,
+ Utf32LE,
+ Utf32BE,
+#endif
+ Latin1,
+ System,
+ LastEncoding = System
+ };
+#ifdef Q_QDOC
+ // document the flags here
+ enum class Flag {
+ Default = 0,
+ Stateless = 0x1,
+ ConvertInvalidToNull = 0x2,
+ WriteBom = 0x4,
+ ConvertInitialBom = 0x8,
+ UsesIcu = 0x10,
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+#endif
+
+protected:
+
+ struct Interface
+ {
+ using DecoderFn = QChar * (*)(QChar *out, QByteArrayView in, State *state);
+ using LengthFn = qsizetype (*)(qsizetype inLength);
+ using EncoderFn = char * (*)(char *out, QStringView in, State *state);
+ const char *name = nullptr;
+ DecoderFn toUtf16 = nullptr;
+ LengthFn toUtf16Len = nullptr;
+ EncoderFn fromUtf16 = nullptr;
+ LengthFn fromUtf16Len = nullptr;
+ };
+
+ constexpr QStringConverter() noexcept
+ : iface(nullptr)
+ {}
+ constexpr explicit QStringConverter(Encoding encoding, Flags f)
+ : iface(&encodingInterfaces[qsizetype(encoding)]), state(f)
+ {}
+ constexpr explicit QStringConverter(const Interface *i) noexcept
+ : iface(i)
+ {}
+ Q_CORE_EXPORT explicit QStringConverter(const char *name, Flags f);
+
+
+ ~QStringConverter() = default;
+
+public:
+ QStringConverter(QStringConverter &&) = default;
+ QStringConverter &operator=(QStringConverter &&) = default;
+
+ bool isValid() const noexcept { return iface != nullptr; }
+
+ void resetState() noexcept
+ {
+ state.reset();
+ }
+ bool hasError() const noexcept { return state.invalidChars != 0; }
+
+ Q_CORE_EXPORT const char *name() const noexcept;
+
+ Q_CORE_EXPORT static std::optional<Encoding> encodingForName(const char *name) noexcept;
+ Q_CORE_EXPORT static const char *nameForEncoding(Encoding e);
+ Q_CORE_EXPORT static std::optional<Encoding>
+ encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;
+ Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);
+
+ Q_CORE_EXPORT static QStringList availableCodecs();
+
+protected:
+ const Interface *iface;
+ State state;
+private:
+ Q_CORE_EXPORT static const Interface encodingInterfaces[Encoding::LastEncoding + 1];
+};
+
+QT_END_NAMESPACE
+
+#endif