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