File indexing completed on 2026-08-05 09:27:40
0001
0002
0003
0004
0005 #ifndef QSTRINGCONVERTER_BASE_H
0006 #define QSTRINGCONVERTER_BASE_H
0007
0008 #if 0
0009
0010
0011 #pragma qt_sync_stop_processing
0012 #endif
0013
0014 #include <optional>
0015
0016 #include <QtCore/qglobal.h> // QT_{BEGIN,END}_NAMESPACE
0017 #include <QtCore/qflags.h> // Q_DECLARE_FLAGS
0018 #include <QtCore/qcontainerfwd.h>
0019 #include <QtCore/qstringfwd.h>
0020
0021 #include <cstring>
0022
0023 QT_BEGIN_NAMESPACE
0024
0025 class QByteArrayView;
0026 class QChar;
0027 class QByteArrayView;
0028 class QStringView;
0029
0030 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(Q_QDOC) && !defined(QT_BOOTSTRAPPED)
0031 class QStringConverterBase
0032 #else
0033 class QStringConverter
0034 #endif
0035 {
0036 public:
0037 enum class Flag {
0038 Default = 0,
0039 Stateless = 0x1,
0040 ConvertInvalidToNull = 0x2,
0041 WriteBom = 0x4,
0042 ConvertInitialBom = 0x8,
0043 UsesIcu = 0x10,
0044 };
0045 Q_DECLARE_FLAGS(Flags, Flag)
0046
0047 struct State {
0048 constexpr State(Flags f = Flag::Default) noexcept
0049 : flags(f), state_data{0, 0, 0, 0} {}
0050 ~State() { clear(); }
0051
0052 State(State &&other) noexcept
0053 : flags(other.flags),
0054 remainingChars(other.remainingChars),
0055 invalidChars(other.invalidChars),
0056 state_data{other.state_data[0], other.state_data[1],
0057 other.state_data[2], other.state_data[3]},
0058 clearFn(other.clearFn)
0059 { other.clearFn = nullptr; }
0060 State &operator=(State &&other) noexcept
0061 {
0062 clear();
0063 flags = other.flags;
0064 remainingChars = other.remainingChars;
0065 invalidChars = other.invalidChars;
0066 std::memmove(state_data, other.state_data, sizeof state_data);
0067 clearFn = other.clearFn;
0068 other.clearFn = nullptr;
0069 return *this;
0070 }
0071 Q_CORE_EXPORT void clear() noexcept;
0072 Q_CORE_EXPORT void reset() noexcept;
0073
0074 Flags flags;
0075 int internalState = 0;
0076 qsizetype remainingChars = 0;
0077 qsizetype invalidChars = 0;
0078
0079 union {
0080 uint state_data[4];
0081 void *d[2];
0082 };
0083 using ClearDataFn = void (*)(State *) noexcept;
0084 ClearDataFn clearFn = nullptr;
0085 private:
0086 Q_DISABLE_COPY(State)
0087 };
0088
0089 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(Q_QDOC) && !defined(QT_BOOTSTRAPPED)
0090 protected:
0091 QStringConverterBase() = default;
0092 ~QStringConverterBase() = default;
0093 QStringConverterBase(QStringConverterBase &&) = default;
0094 QStringConverterBase &operator=(QStringConverterBase &&) = default;
0095 };
0096
0097 class QStringConverter : public QStringConverterBase
0098 {
0099 public:
0100 #endif
0101
0102 enum Encoding {
0103 Utf8,
0104 #ifndef QT_BOOTSTRAPPED
0105 Utf16,
0106 Utf16LE,
0107 Utf16BE,
0108 Utf32,
0109 Utf32LE,
0110 Utf32BE,
0111 #endif
0112 Latin1,
0113 System,
0114 LastEncoding = System
0115 };
0116
0117 protected:
0118
0119 struct Interface
0120 {
0121 using DecoderFn = QChar * (*)(QChar *out, QByteArrayView in, State *state);
0122 using LengthFn = qsizetype (*)(qsizetype inLength);
0123 using EncoderFn = char * (*)(char *out, QStringView in, State *state);
0124 const char *name = nullptr;
0125 DecoderFn toUtf16 = nullptr;
0126 LengthFn toUtf16Len = nullptr;
0127 EncoderFn fromUtf16 = nullptr;
0128 LengthFn fromUtf16Len = nullptr;
0129 };
0130
0131 constexpr QStringConverter() noexcept
0132 : iface(nullptr)
0133 {}
0134 constexpr explicit QStringConverter(Encoding encoding, Flags f)
0135 : iface(&encodingInterfaces[qsizetype(encoding)]), state(f)
0136 {}
0137 constexpr explicit QStringConverter(const Interface *i) noexcept
0138 : iface(i)
0139 {}
0140 #if QT_CORE_REMOVED_SINCE(6, 8)
0141 Q_CORE_EXPORT explicit QStringConverter(const char *name, Flags f);
0142 #endif
0143 Q_CORE_EXPORT explicit QStringConverter(QAnyStringView name, Flags f);
0144
0145
0146 ~QStringConverter() = default;
0147
0148 public:
0149 QStringConverter(QStringConverter &&) = default;
0150 QStringConverter &operator=(QStringConverter &&) = default;
0151
0152 bool isValid() const noexcept { return iface != nullptr; }
0153
0154 void resetState() noexcept
0155 {
0156 state.reset();
0157 }
0158 bool hasError() const noexcept { return state.invalidChars != 0; }
0159
0160 Q_CORE_EXPORT const char *name() const noexcept;
0161
0162 #if QT_CORE_REMOVED_SINCE(6, 8)
0163 Q_CORE_EXPORT static std::optional<Encoding> encodingForName(const char *name) noexcept;
0164 #endif
0165 Q_CORE_EXPORT static std::optional<Encoding> encodingForName(QAnyStringView name) noexcept;
0166 Q_DECL_PURE_FUNCTION Q_CORE_EXPORT static const char *nameForEncoding(Encoding e) noexcept;
0167 Q_CORE_EXPORT static std::optional<Encoding>
0168 encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;
0169 Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);
0170
0171 Q_CORE_EXPORT static QStringList availableCodecs();
0172
0173
0174 enum class FinalizeResultError : quint8 {
0175 NoError,
0176 InvalidCharacters,
0177 NotEnoughSpace,
0178 };
0179 template <typename Char>
0180 struct FinalizeResultChar
0181 {
0182 using Error = FinalizeResultError;
0183
0184 Char *next;
0185 qint16 invalidChars;
0186 Error error;
0187 };
0188
0189 protected:
0190 const Interface *iface;
0191 State state;
0192 private:
0193 Q_CORE_EXPORT static const Interface encodingInterfaces[Encoding::LastEncoding + 1];
0194 };
0195
0196 Q_DECLARE_OPERATORS_FOR_FLAGS(QStringConverter::Flags)
0197
0198 QT_END_NAMESPACE
0199
0200 #endif