Warning, file /include/QtCore/qstringconverter.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005 #if 0
0006
0007
0008 #pragma qt_class(QStringConverter)
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(QAnyStringView 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
0066 using FinalizeResult = FinalizeResultChar<char>;
0067 [[nodiscard]] Q_CORE_EXPORT FinalizeResult finalize(char *out, qsizetype maxlen);
0068 [[nodiscard]] FinalizeResult finalize() { return finalize(nullptr, 0); }
0069
0070 private:
0071 QByteArray invalidateAndReturnNull()
0072 {
0073
0074 state.invalidChars = 1;
0075 return QByteArray();
0076 }
0077 QByteArray encodeAsByteArrayImpl(QStringView in)
0078 {
0079 QByteArray result(iface->fromUtf16Len(in.size()), Qt::Uninitialized);
0080 char *out = result.data();
0081 out = iface->fromUtf16(out, in, &state);
0082 result.truncate(out - result.constData());
0083 return result;
0084 }
0085 QByteArray encodeAsByteArray(QStringView in)
0086 {
0087 return iface ? encodeAsByteArrayImpl(in) : invalidateAndReturnNull();
0088 }
0089 };
0090
0091 class QStringDecoder : public QStringConverter
0092 {
0093 protected:
0094 constexpr explicit QStringDecoder(const Interface *i) noexcept
0095 : QStringConverter(i)
0096 {}
0097 public:
0098 constexpr explicit QStringDecoder(Encoding encoding, Flags flags = Flag::Default)
0099 : QStringConverter(encoding, flags)
0100 {}
0101 constexpr QStringDecoder() noexcept
0102 : QStringConverter()
0103 {}
0104 explicit QStringDecoder(QAnyStringView name, Flags f = Flag::Default)
0105 : QStringConverter(name, f)
0106 {}
0107
0108 template<typename T>
0109 struct EncodedData
0110 {
0111 QStringDecoder *decoder;
0112 T data;
0113 operator QString() const { return decoder->decodeAsString(data); }
0114 };
0115 Q_WEAK_OVERLOAD
0116 EncodedData<const QByteArray &> operator()(const QByteArray &ba)
0117 { return EncodedData<const QByteArray &>{this, ba}; }
0118 EncodedData<QByteArrayView> operator()(QByteArrayView ba)
0119 { return EncodedData<QByteArrayView>{this, ba}; }
0120 Q_WEAK_OVERLOAD
0121 EncodedData<const QByteArray &> decode(const QByteArray &ba)
0122 { return EncodedData<const QByteArray &>{this, ba}; }
0123 EncodedData<QByteArrayView> decode(QByteArrayView ba)
0124 { return EncodedData<QByteArrayView>{this, ba}; }
0125
0126 qsizetype requiredSpace(qsizetype inputLength) const
0127 { return iface ? iface->toUtf16Len(inputLength) : 0; }
0128 QChar *appendToBuffer(QChar *out, QByteArrayView ba)
0129 {
0130 if (!iface) {
0131 state.invalidChars = 1;
0132 return out;
0133 }
0134 return iface->toUtf16(out, ba, &state);
0135 }
0136 char16_t *appendToBuffer(char16_t *out, QByteArrayView ba)
0137 { return reinterpret_cast<char16_t *>(appendToBuffer(reinterpret_cast<QChar *>(out), ba)); }
0138
0139
0140 using FinalizeResult = FinalizeResultChar<char16_t>;
0141 using FinalizeResultQChar = FinalizeResultChar<QChar>;
0142 [[nodiscard]] FinalizeResultQChar finalize(QChar *out, qsizetype maxlen)
0143 {
0144 auto r = finalize(reinterpret_cast<char16_t *>(out), maxlen);
0145 return {reinterpret_cast<QChar *>(r.next), r.invalidChars, r.error};
0146 }
0147 [[nodiscard]] Q_CORE_EXPORT FinalizeResult finalize(char16_t *out, qsizetype maxlen);
0148 [[nodiscard]] FinalizeResult finalize()
0149 {
0150 return finalize(static_cast<char16_t *>(nullptr), 0);
0151 }
0152
0153 Q_CORE_EXPORT static QStringDecoder decoderForHtml(QByteArrayView data);
0154
0155 private:
0156 QString invalidateAndReturnNull()
0157 {
0158
0159 state.invalidChars = 1;
0160 return QString();
0161 }
0162 QString decodeAsStringImpl(QByteArrayView in)
0163 {
0164 QString result(iface->toUtf16Len(in.size()), Qt::Uninitialized);
0165 const QChar *out = iface->toUtf16(result.data(), in, &state);
0166 result.truncate(out - result.constData());
0167 return result;
0168 }
0169 QString decodeAsString(QByteArrayView in)
0170 {
0171 return iface ? decodeAsStringImpl(in) : invalidateAndReturnNull();
0172 }
0173 };
0174
0175
0176 #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
0177 template <typename T>
0178 struct QConcatenable<QStringDecoder::EncodedData<T>>
0179 : private QAbstractConcatenable
0180 {
0181 typedef QChar type;
0182 typedef QString ConvertTo;
0183 enum { ExactSize = false };
0184 static qsizetype size(const QStringDecoder::EncodedData<T> &s) { return s.decoder->requiredSpace(s.data.size()); }
0185 static inline void appendTo(const QStringDecoder::EncodedData<T> &s, QChar *&out)
0186 {
0187 out = s.decoder->appendToBuffer(out, s.data);
0188 }
0189 };
0190
0191 template <typename T>
0192 struct QConcatenable<QStringEncoder::DecodedData<T>>
0193 : private QAbstractConcatenable
0194 {
0195 typedef char type;
0196 typedef QByteArray ConvertTo;
0197 enum { ExactSize = false };
0198 static qsizetype size(const QStringEncoder::DecodedData<T> &s) { return s.encoder->requiredSpace(s.data.size()); }
0199 static inline void appendTo(const QStringEncoder::DecodedData<T> &s, char *&out)
0200 {
0201 out = s.encoder->appendToBuffer(out, s.data);
0202 }
0203 };
0204
0205 template <typename T>
0206 QString &operator+=(QString &a, const QStringDecoder::EncodedData<T> &b)
0207 {
0208 qsizetype len = a.size() + QConcatenable<QStringDecoder::EncodedData<T>>::size(b);
0209 a.reserve(len);
0210 QChar *it = a.data() + a.size();
0211 QConcatenable<QStringDecoder::EncodedData<T>>::appendTo(b, it);
0212 a.resize(qsizetype(it - a.constData()));
0213 return a;
0214 }
0215
0216 template <typename T>
0217 QByteArray &operator+=(QByteArray &a, const QStringEncoder::DecodedData<T> &b)
0218 {
0219 qsizetype len = a.size() + QConcatenable<QStringEncoder::DecodedData<T>>::size(b);
0220 a.reserve(len);
0221 char *it = a.data() + a.size();
0222 QConcatenable<QStringEncoder::DecodedData<T>>::appendTo(b, it);
0223 a.resize(qsizetype(it - a.constData()));
0224 return a;
0225 }
0226 #endif
0227
0228 template <typename InputIterator>
0229 void QString::assign_helper_char8(InputIterator first, InputIterator last)
0230 {
0231 static_assert(!QString::is_contiguous_iterator_v<InputIterator>,
0232 "Internal error: Should have been handed over to the QAnyStringView overload."
0233 );
0234
0235 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
0236 constexpr bool IsFwdIt = std::is_convertible_v<
0237 typename std::iterator_traits<InputIterator>::iterator_category,
0238 std::forward_iterator_tag
0239 >;
0240
0241 resize(0);
0242
0243
0244 if (const auto offset = d.freeSpaceAtBegin())
0245 d.setBegin(d.begin() - offset);
0246
0247 if constexpr (IsFwdIt)
0248 reserve(static_cast<qsizetype>(std::distance(first, last)));
0249
0250 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
0251 auto availableCapacity = d.constAllocatedCapacity();
0252 auto *dst = d.data();
0253 auto *dend = d.data() + availableCapacity;
0254
0255 while (true) {
0256 if (first == last) {
0257 Q_ASSERT(!std::less<>{}(dend, dst));
0258 d.size = dst - d.begin();
0259 return;
0260 }
0261 const ValueType next = *first;
0262 const auto chunk = QUtf8StringView(&next, 1);
0263
0264
0265
0266
0267
0268 if constexpr (!IsFwdIt) {
0269 constexpr qsizetype Pair = 2;
0270 char16_t buf[Pair];
0271 const qptrdiff n = toUtf16.appendToBuffer(buf, chunk) - buf;
0272 if (dend - dst < n) {
0273 const auto offset = dst - d.begin();
0274 reallocData(d.constAllocatedCapacity() + Pair, QArrayData::Grow);
0275
0276 availableCapacity = d.constAllocatedCapacity();
0277 dst = d.data() + offset;
0278 dend = d.data() + availableCapacity;
0279 }
0280 dst = std::copy_n(buf, n, dst);
0281 } else {
0282 dst = toUtf16.appendToBuffer(dst, chunk);
0283 }
0284 ++first;
0285 }
0286 }
0287
0288 QT_END_NAMESPACE
0289
0290 #endif