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