1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QSTRINGCONVERTER_BASE_H
5#define QSTRINGCONVERTER_BASE_H
6
7#if 0
8// QStringConverter(Base) class are handled in qstringconverter
9#pragma qt_sync_stop_processing
10#endif
11
12#include <optional>
13
14#include <QtCore/qglobal.h> // QT_{BEGIN,END}_NAMESPACE
15#include <QtCore/qflags.h> // Q_DECLARE_FLAGS
16#include <QtCore/qcontainerfwd.h>
17#include <QtCore/qstringfwd.h>
18
19#include <cstring>
20
21QT_BEGIN_NAMESPACE
22
23class QByteArrayView;
24class QChar;
25class QByteArrayView;
26class QStringView;
27
28class QStringConverterBase
29{
30public:
31 enum class Flag {
32 Default = 0,
33 Stateless = 0x1,
34 ConvertInvalidToNull = 0x2,
35 WriteBom = 0x4,
36 ConvertInitialBom = 0x8,
37 UsesIcu = 0x10,
38 };
39 Q_DECLARE_FLAGS(Flags, Flag)
40
41 struct State {
42 constexpr State(Flags f = Flag::Default) noexcept
43 : flags(f), state_data{0, 0, 0, 0} {}
44 ~State() { clear(); }
45
46 State(State &&other) noexcept
47 : flags(other.flags),
48 remainingChars(other.remainingChars),
49 invalidChars(other.invalidChars),
50 state_data{other.state_data[0], other.state_data[1],
51 other.state_data[2], other.state_data[3]},
52 clearFn(other.clearFn)
53 { other.clearFn = nullptr; }
54 State &operator=(State &&other) noexcept
55 {
56 clear();
57 flags = other.flags;
58 remainingChars = other.remainingChars;
59 invalidChars = other.invalidChars;
60 std::memmove(dest: state_data, src: other.state_data, n: sizeof state_data); // self-assignment-safe
61 clearFn = other.clearFn;
62 other.clearFn = nullptr;
63 return *this;
64 }
65 Q_CORE_EXPORT void clear() noexcept;
66 Q_CORE_EXPORT void reset() noexcept;
67
68 Flags flags;
69 int internalState = 0;
70 qsizetype remainingChars = 0;
71 qsizetype invalidChars = 0;
72
73 union {
74 uint state_data[4];
75 void *d[2];
76 };
77 using ClearDataFn = void (*)(State *) noexcept;
78 ClearDataFn clearFn = nullptr;
79 private:
80 Q_DISABLE_COPY(State)
81 };
82protected:
83 ~QStringConverterBase() = default;
84};
85Q_DECLARE_OPERATORS_FOR_FLAGS(QStringConverterBase::Flags)
86
87class QStringConverter : public QStringConverterBase
88{
89public:
90
91 enum Encoding {
92 Utf8,
93#ifndef QT_BOOTSTRAPPED
94 Utf16,
95 Utf16LE,
96 Utf16BE,
97 Utf32,
98 Utf32LE,
99 Utf32BE,
100#endif
101 Latin1,
102 System,
103 LastEncoding = System
104 };
105#ifdef Q_QDOC
106 // document the flags here
107 enum class Flag {
108 Default = 0,
109 Stateless = 0x1,
110 ConvertInvalidToNull = 0x2,
111 WriteBom = 0x4,
112 ConvertInitialBom = 0x8,
113 UsesIcu = 0x10,
114 };
115 Q_DECLARE_FLAGS(Flags, Flag)
116#endif
117
118protected:
119
120 struct Interface
121 {
122 using DecoderFn = QChar * (*)(QChar *out, QByteArrayView in, State *state);
123 using LengthFn = qsizetype (*)(qsizetype inLength);
124 using EncoderFn = char * (*)(char *out, QStringView in, State *state);
125 const char *name = nullptr;
126 DecoderFn toUtf16 = nullptr;
127 LengthFn toUtf16Len = nullptr;
128 EncoderFn fromUtf16 = nullptr;
129 LengthFn fromUtf16Len = nullptr;
130 };
131
132 constexpr QStringConverter() noexcept
133 : iface(nullptr)
134 {}
135 constexpr explicit QStringConverter(Encoding encoding, Flags f)
136 : iface(&encodingInterfaces[qsizetype(encoding)]), state(f)
137 {}
138 constexpr explicit QStringConverter(const Interface *i) noexcept
139 : iface(i)
140 {}
141#if QT_CORE_REMOVED_SINCE(6, 8)
142 Q_CORE_EXPORT explicit QStringConverter(const char *name, Flags f);
143#endif
144 Q_CORE_EXPORT explicit QStringConverter(QAnyStringView name, Flags f);
145
146
147 ~QStringConverter() = default;
148
149public:
150 QStringConverter(QStringConverter &&) = default;
151 QStringConverter &operator=(QStringConverter &&) = default;
152
153 bool isValid() const noexcept { return iface != nullptr; }
154
155 void resetState() noexcept
156 {
157 state.reset();
158 }
159 bool hasError() const noexcept { return state.invalidChars != 0; }
160
161 Q_CORE_EXPORT const char *name() const noexcept;
162
163#if QT_CORE_REMOVED_SINCE(6, 8)
164 Q_CORE_EXPORT static std::optional<Encoding> encodingForName(const char *name) noexcept;
165#endif
166 Q_CORE_EXPORT static std::optional<Encoding> encodingForName(QAnyStringView name) noexcept;
167 Q_CORE_EXPORT static const char *nameForEncoding(Encoding e);
168 Q_CORE_EXPORT static std::optional<Encoding>
169 encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;
170 Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);
171
172 Q_CORE_EXPORT static QStringList availableCodecs();
173
174protected:
175 const Interface *iface;
176 State state;
177private:
178 Q_CORE_EXPORT static const Interface encodingInterfaces[Encoding::LastEncoding + 1];
179};
180
181QT_END_NAMESPACE
182
183#endif
184

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/corelib/text/qstringconverter_base.h