File indexing completed on 2025-09-18 09:26:48
0001
0002
0003
0004
0005 #if 0
0006
0007
0008 #pragma qt_class(QStringConverter)
0009 #pragma qt_class(QStringConverterBase)
0010 #endif
0011
0012 #ifndef QSTRINGCONVERTER_H
0013 #define QSTRINGCONVERTER_H
0014
0015 #include <QtCore/qstringconverter_base.h>
0016 #include <QtCore/qstring.h>
0017 #include <QtCore/qstringbuilder.h>
0018
0019 QT_BEGIN_NAMESPACE
0020
0021 class QStringEncoder : public QStringConverter
0022 {
0023 protected:
0024 constexpr explicit QStringEncoder(const Interface *i) noexcept
0025 : QStringConverter(i)
0026 {}
0027 public:
0028 constexpr QStringEncoder() noexcept
0029 : QStringConverter()
0030 {}
0031 constexpr explicit QStringEncoder(Encoding encoding, Flags flags = Flag::Default)
0032 : QStringConverter(encoding, flags)
0033 {}
0034 explicit QStringEncoder(QAnyStringView name, Flags flags = Flag::Default)
0035 : QStringConverter(name, flags)
0036 {}
0037
0038 template<typename T>
0039 struct DecodedData
0040 {
0041 QStringEncoder *encoder;
0042 T data;
0043 operator QByteArray() const { return encoder->encodeAsByteArray(data); }
0044 };
0045 Q_WEAK_OVERLOAD
0046 DecodedData<const QString &> operator()(const QString &str)
0047 { return DecodedData<const QString &>{this, str}; }
0048 DecodedData<QStringView> operator()(QStringView in)
0049 { return DecodedData<QStringView>{this, in}; }
0050 Q_WEAK_OVERLOAD
0051 DecodedData<const QString &> encode(const QString &str)
0052 { return DecodedData<const QString &>{this, str}; }
0053 DecodedData<QStringView> encode(QStringView in)
0054 { return DecodedData<QStringView>{this, in}; }
0055
0056 qsizetype requiredSpace(qsizetype inputLength) const
0057 { return iface ? iface->fromUtf16Len(inputLength) : 0; }
0058 char *appendToBuffer(char *out, QStringView in)
0059 {
0060 if (!iface) {
0061 state.invalidChars = 1;
0062 return out;
0063 }
0064 return iface->fromUtf16(out, in, &state);
0065 }
0066 private:
0067 QByteArray encodeAsByteArray(QStringView in)
0068 {
0069 if (!iface) {
0070
0071 state.invalidChars = 1;
0072 return {};
0073 }
0074 QByteArray result(iface->fromUtf16Len(in.size()), Qt::Uninitialized);
0075 char *out = result.data();
0076 out = iface->fromUtf16(out, in, &state);
0077 result.truncate(out - result.constData());
0078 return result;
0079 }
0080
0081 };
0082
0083 class QStringDecoder : public QStringConverter
0084 {
0085 protected:
0086 constexpr explicit QStringDecoder(const Interface *i) noexcept
0087 : QStringConverter(i)
0088 {}
0089 public:
0090 constexpr explicit QStringDecoder(Encoding encoding, Flags flags = Flag::Default)
0091 : QStringConverter(encoding, flags)
0092 {}
0093 constexpr QStringDecoder() noexcept
0094 : QStringConverter()
0095 {}
0096 explicit QStringDecoder(QAnyStringView name, Flags f = Flag::Default)
0097 : QStringConverter(name, f)
0098 {}
0099
0100 template<typename T>
0101 struct EncodedData
0102 {
0103 QStringDecoder *decoder;
0104 T data;
0105 operator QString() const { return decoder->decodeAsString(data); }
0106 };
0107 Q_WEAK_OVERLOAD
0108 EncodedData<const QByteArray &> operator()(const QByteArray &ba)
0109 { return EncodedData<const QByteArray &>{this, ba}; }
0110 EncodedData<QByteArrayView> operator()(QByteArrayView ba)
0111 { return EncodedData<QByteArrayView>{this, ba}; }
0112 Q_WEAK_OVERLOAD
0113 EncodedData<const QByteArray &> decode(const QByteArray &ba)
0114 { return EncodedData<const QByteArray &>{this, ba}; }
0115 EncodedData<QByteArrayView> decode(QByteArrayView ba)
0116 { return EncodedData<QByteArrayView>{this, ba}; }
0117
0118 qsizetype requiredSpace(qsizetype inputLength) const
0119 { return iface ? iface->toUtf16Len(inputLength) : 0; }
0120 QChar *appendToBuffer(QChar *out, QByteArrayView ba)
0121 {
0122 if (!iface) {
0123 state.invalidChars = 1;
0124 return out;
0125 }
0126 return iface->toUtf16(out, ba, &state);
0127 }
0128 char16_t *appendToBuffer(char16_t *out, QByteArrayView ba)
0129 { return reinterpret_cast<char16_t *>(appendToBuffer(reinterpret_cast<QChar *>(out), ba)); }
0130
0131 Q_CORE_EXPORT static QStringDecoder decoderForHtml(QByteArrayView data);
0132
0133 private:
0134 QString decodeAsString(QByteArrayView in)
0135 {
0136 if (!iface) {
0137
0138 state.invalidChars = 1;
0139 return {};
0140 }
0141 QString result(iface->toUtf16Len(in.size()), Qt::Uninitialized);
0142 const QChar *out = iface->toUtf16(result.data(), in, &state);
0143 result.truncate(out - result.constData());
0144 return result;
0145 }
0146 };
0147
0148
0149 #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
0150 template <typename T>
0151 struct QConcatenable<QStringDecoder::EncodedData<T>>
0152 : private QAbstractConcatenable
0153 {
0154 typedef QChar type;
0155 typedef QString ConvertTo;
0156 enum { ExactSize = false };
0157 static qsizetype size(const QStringDecoder::EncodedData<T> &s) { return s.decoder->requiredSpace(s.data.size()); }
0158 static inline void appendTo(const QStringDecoder::EncodedData<T> &s, QChar *&out)
0159 {
0160 out = s.decoder->appendToBuffer(out, s.data);
0161 }
0162 };
0163
0164 template <typename T>
0165 struct QConcatenable<QStringEncoder::DecodedData<T>>
0166 : private QAbstractConcatenable
0167 {
0168 typedef char type;
0169 typedef QByteArray ConvertTo;
0170 enum { ExactSize = false };
0171 static qsizetype size(const QStringEncoder::DecodedData<T> &s) { return s.encoder->requiredSpace(s.data.size()); }
0172 static inline void appendTo(const QStringEncoder::DecodedData<T> &s, char *&out)
0173 {
0174 out = s.encoder->appendToBuffer(out, s.data);
0175 }
0176 };
0177
0178 template <typename T>
0179 QString &operator+=(QString &a, const QStringDecoder::EncodedData<T> &b)
0180 {
0181 qsizetype len = a.size() + QConcatenable<QStringDecoder::EncodedData<T>>::size(b);
0182 a.reserve(len);
0183 QChar *it = a.data() + a.size();
0184 QConcatenable<QStringDecoder::EncodedData<T>>::appendTo(b, it);
0185 a.resize(qsizetype(it - a.constData()));
0186 return a;
0187 }
0188
0189 template <typename T>
0190 QByteArray &operator+=(QByteArray &a, const QStringEncoder::DecodedData<T> &b)
0191 {
0192 qsizetype len = a.size() + QConcatenable<QStringEncoder::DecodedData<T>>::size(b);
0193 a.reserve(len);
0194 char *it = a.data() + a.size();
0195 QConcatenable<QStringEncoder::DecodedData<T>>::appendTo(b, it);
0196 a.resize(qsizetype(it - a.constData()));
0197 return a;
0198 }
0199 #endif
0200
0201 template <typename InputIterator>
0202 void QString::assign_helper_char8(InputIterator first, InputIterator last)
0203 {
0204 static_assert(!QString::is_contiguous_iterator_v<InputIterator>,
0205 "Internal error: Should have been handed over to the QAnyStringView overload."
0206 );
0207
0208 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
0209 constexpr bool IsFwdIt = std::is_convertible_v<
0210 typename std::iterator_traits<InputIterator>::iterator_category,
0211 std::forward_iterator_tag
0212 >;
0213
0214 resize(0);
0215
0216
0217 if (const auto offset = d.freeSpaceAtBegin())
0218 d.setBegin(d.begin() - offset);
0219
0220 if constexpr (IsFwdIt)
0221 reserve(static_cast<qsizetype>(std::distance(first, last)));
0222
0223 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
0224 auto availableCapacity = d.constAllocatedCapacity();
0225 auto *dst = d.data();
0226 auto *dend = d.data() + availableCapacity;
0227
0228 while (true) {
0229 if (first == last) {
0230 Q_ASSERT(!std::less<>{}(dend, dst));
0231 d.size = dst - d.begin();
0232 return;
0233 }
0234 const ValueType next = *first;
0235 const auto chunk = QUtf8StringView(&next, 1);
0236
0237
0238
0239
0240
0241 if constexpr (!IsFwdIt) {
0242 constexpr qsizetype Pair = 2;
0243 char16_t buf[Pair];
0244 const qptrdiff n = toUtf16.appendToBuffer(buf, chunk) - buf;
0245 if (dend - dst < n) {
0246 const auto offset = dst - d.begin();
0247 reallocData(d.constAllocatedCapacity() + Pair, QArrayData::Grow);
0248
0249 availableCapacity = d.constAllocatedCapacity();
0250 dst = d.data() + offset;
0251 dend = d.data() + availableCapacity;
0252 }
0253 dst = std::copy_n(buf, n, dst);
0254 } else {
0255 dst = toUtf16.appendToBuffer(dst, chunk);
0256 }
0257 ++first;
0258 }
0259 }
0260
0261 QT_END_NAMESPACE
0262
0263 #endif