8#pragma qt_class(QStringConverter)
11#ifndef QSTRINGCONVERTER_H
12#define QSTRINGCONVERTER_H
14#include <QtCore/qstringconverter_base.h>
15#include <QtCore/qstring.h>
16#include <QtCore/qstringbuilder.h>
20class QStringEncoder :
public QStringConverter
23 constexpr explicit QStringEncoder(
const Interface *i)
noexcept
27 constexpr QStringEncoder()
noexcept
30 constexpr explicit QStringEncoder(Encoding encoding, Flags flags = Flag::Default)
31 : QStringConverter(encoding, flags)
33 explicit QStringEncoder(QAnyStringView name, Flags flags = Flag::Default)
34 : QStringConverter(name, flags)
40 QStringEncoder *encoder;
42 operator QByteArray()
const {
return encoder->encodeAsByteArray(data); }
45 DecodedData<
const QString &> operator()(
const QString &str)
46 {
return DecodedData<
const QString &>{
this, str}; }
47 DecodedData<QStringView> operator()(QStringView in)
48 {
return DecodedData<QStringView>{
this, in}; }
50 DecodedData<
const QString &> encode(
const QString &str)
51 {
return DecodedData<
const QString &>{
this, str}; }
52 DecodedData<QStringView> encode(QStringView in)
53 {
return DecodedData<QStringView>{
this, in}; }
55 qsizetype requiredSpace(qsizetype inputLength)
const
56 {
return iface ? iface->fromUtf16Len(inputLength) : 0; }
57 char *appendToBuffer(
char *out, QStringView in)
60 state.invalidChars = 1;
63 return iface->fromUtf16(out, in, &state);
66 using FinalizeResult = FinalizeResultChar<
char>;
67 [[nodiscard]] Q_CORE_EXPORT FinalizeResult finalize(
char *out, qsizetype maxlen);
68 [[nodiscard]] FinalizeResult finalize() {
return finalize(
nullptr, 0); }
71 QByteArray invalidateAndReturnNull()
74 state.invalidChars = 1;
77 QByteArray encodeAsByteArrayImpl(QStringView in)
79 QByteArray result(iface->fromUtf16Len(in.size()), Qt::Uninitialized);
80 char *out = result.data();
81 out = iface->fromUtf16(out, in, &state);
82 result.truncate(out - result.constData());
85 QByteArray encodeAsByteArray(QStringView in)
87 return iface ? encodeAsByteArrayImpl(in) : invalidateAndReturnNull();
144 auto r = finalize(
reinterpret_cast<
char16_t *>(out), maxlen);
145 return {
reinterpret_cast<QChar *>(r.next), r.invalidChars, r.error};
150 return finalize(
static_cast<
char16_t *>(
nullptr), 0);
156 QString invalidateAndReturnNull()
159 state.invalidChars = 1;
162 QString decodeAsStringImpl(QByteArrayView in)
164 QString result(iface->toUtf16Len(in.size()), Qt::Uninitialized);
165 const QChar *out = iface->toUtf16(result.data(), in, &state);
166 result.truncate(out - result.constData());
169 QString decodeAsString(QByteArrayView in)
171 return iface ? decodeAsStringImpl(in) : invalidateAndReturnNull();
176#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
178struct QConcatenable<QStringDecoder::EncodedData<T>>
179 :
private QAbstractConcatenable
182 typedef QString ConvertTo;
183 enum { ExactSize =
false };
184 static qsizetype size(
const QStringDecoder::EncodedData<T> &s) {
return s.decoder->requiredSpace(s.data.size()); }
185 static inline void appendTo(
const QStringDecoder::EncodedData<T> &s, QChar *&out)
187 out = s.decoder->appendToBuffer(out, s.data);
192struct QConcatenable<QStringEncoder::DecodedData<T>>
193 :
private QAbstractConcatenable
196 typedef QByteArray ConvertTo;
197 enum { ExactSize =
false };
198 static qsizetype size(
const QStringEncoder::DecodedData<T> &s) {
return s.encoder->requiredSpace(s.data.size()); }
199 static inline void appendTo(
const QStringEncoder::DecodedData<T> &s,
char *&out)
201 out = s.encoder->appendToBuffer(out, s.data);
206QString &operator+=(QString &a,
const QStringDecoder::EncodedData<T> &b)
208 qsizetype len = a.size() + QConcatenable<QStringDecoder::EncodedData<T>>::size(b);
210 QChar *it = a.data() + a.size();
211 QConcatenable<QStringDecoder::EncodedData<T>>::appendTo(b, it);
212 a.resize(qsizetype(it - a.constData()));
217QByteArray &operator+=(QByteArray &a,
const QStringEncoder::DecodedData<T> &b)
219 qsizetype len = a.size() + QConcatenable<QStringEncoder::DecodedData<T>>::size(b);
221 char *it = a.data() + a.size();
222 QConcatenable<QStringEncoder::DecodedData<T>>::appendTo(b, it);
223 a.resize(qsizetype(it - a.constData()));
228template <
typename InputIterator>
229void QString::assign_helper_char8(InputIterator first, InputIterator last)
231 static_assert(!QString::is_contiguous_iterator_v<InputIterator>,
232 "Internal error: Should have been handed over to the QAnyStringView overload."
235 using ValueType =
typename std::iterator_traits<InputIterator>::value_type;
236 constexpr bool IsFwdIt = std::is_convertible_v<
237 typename std::iterator_traits<InputIterator>::iterator_category,
238 std::forward_iterator_tag
244 if (
const auto offset = d.freeSpaceAtBegin())
245 d.setBegin(d.begin() - offset);
247 if constexpr (IsFwdIt)
248 reserve(
static_cast<qsizetype>(std::distance(first, last)));
250 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
251 auto availableCapacity = d.constAllocatedCapacity();
252 auto *dst = d.data();
253 auto *dend = d.data() + availableCapacity;
257 Q_ASSERT(!std::less<>{}(dend, dst));
258 d.size = dst - d.begin();
261 const ValueType next = *first;
262 const auto chunk = QUtf8StringView(&next, 1);
268 if constexpr (!IsFwdIt) {
269 constexpr qsizetype Pair = 2;
271 const qptrdiff n = toUtf16.appendToBuffer(buf, chunk) - buf;
272 if (dend - dst < n) {
273 const auto offset = dst - d.begin();
274 reallocData(d.constAllocatedCapacity() + Pair, QArrayData::Grow);
276 availableCapacity = d.constAllocatedCapacity();
277 dst = d.data() + offset;
278 dend = d.data() + availableCapacity;
280 dst = std::copy_n(buf, n, dst);
282 dst = toUtf16.appendToBuffer(dst, chunk);
constexpr QStringDecoder(Encoding encoding, Flags flags=Flag::Default)
Creates an decoder object using encoding and flags.
FinalizeResultQChar finalize(QChar *out, qsizetype maxlen)
constexpr QStringDecoder(const Interface *i) noexcept
FinalizeResult finalize()
Signals to the decoder that no further data will arrive.
constexpr QStringDecoder() noexcept
Default constructs an decoder.