QtBase  v6.3.1
qstringconverter.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QSTRINGCONVERTER_H
41 #define QSTRINGCONVERTER_H
42 
43 #include <QtCore/qstring.h>
44 #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
45 #include <QtCore/qstringbuilder.h>
46 #endif
47 
48 #include <optional>
49 
50 #include <cstring>
51 
53 
54 // work around a compiler bug in GCC 7
55 #if (defined(Q_CC_GNU) && __GNUC__ == 7) || defined(Q_QDOC)
56 #define QSTRINGCONVERTER_CONSTEXPR
57 #else
58 #define QSTRINGCONVERTER_CONSTEXPR constexpr
59 #endif
60 
62 {
63 public:
64  enum class Flag {
65  Default = 0,
66  Stateless = 0x1,
68  WriteBom = 0x4,
69  ConvertInitialBom = 0x8
70  };
72 
73  struct State {
74  constexpr State(Flags f = Flag::Default)
75  : flags(f), state_data{0, 0, 0, 0} {}
76  ~State() { clear(); }
78  : flags(other.flags),
79  remainingChars(other.remainingChars),
80  invalidChars(other.invalidChars),
81  state_data{other.state_data[0], other.state_data[1],
82  other.state_data[2], other.state_data[3]},
83  clearFn(other.clearFn)
84  { other.clearFn = nullptr; }
86  {
87  clear();
88  flags = other.flags;
89  remainingChars = other.remainingChars;
90  invalidChars = other.invalidChars;
91  std::memmove(state_data, other.state_data, sizeof state_data); // self-assignment-safe
92  clearFn = other.clearFn;
93  other.clearFn = nullptr;
94  return *this;
95  }
96  Q_CORE_EXPORT void clear();
97 
99  int internalState = 0;
100  qsizetype remainingChars = 0;
101  qsizetype invalidChars = 0;
102 
103  union {
104  uint state_data[4];
105  void *d[2];
106  };
107  using ClearDataFn = void (*)(State *);
108  ClearDataFn clearFn = nullptr;
109  private:
111  };
112 };
114 
116 {
117 public:
118 
119  enum Encoding {
129  LastEncoding = System
130  };
131 #ifdef Q_QDOC
132  // document the flags here
133  enum class Flag {
134  Default = 0,
135  Stateless = 0x1,
136  ConvertInvalidToNull = 0x2,
137  WriteBom = 0x4,
138  ConvertInitialBom = 0x8
139  };
140  Q_DECLARE_FLAGS(Flags, Flag)
141 #endif
142 
143 protected:
144 
145  struct Interface
146  {
148  using LengthFn = qsizetype (*)(qsizetype inLength);
149  using EncoderFn = char * (*)(char *out, QStringView in, State *state);
150  const char *name = nullptr;
151  DecoderFn toUtf16 = nullptr;
152  LengthFn toUtf16Len = nullptr;
153  EncoderFn fromUtf16 = nullptr;
154  LengthFn fromUtf16Len = nullptr;
155  };
156 
158  : iface(nullptr)
159  {}
161  : iface(&encodingInterfaces[int(encoding)]), state(f)
162  {}
164  : iface(i)
165  {}
166  Q_CORE_EXPORT QStringConverter(const char *name, Flags f);
167 
168 
169 public:
170  bool isValid() const { return iface != nullptr; }
171 
172  void resetState()
173  {
174  state.clear();
175  }
176  bool hasError() const { return state.invalidChars != 0; }
177 
178  const char *name() const
179  { return isValid() ? iface->name : nullptr; }
180 
181  Q_CORE_EXPORT static std::optional<Encoding> encodingForName(const char *name);
182  Q_CORE_EXPORT static const char *nameForEncoding(Encoding e);
183  Q_CORE_EXPORT static std::optional<Encoding> encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0);
184  Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);
185 
186 protected:
187  const Interface *iface;
189 private:
190  Q_CORE_EXPORT static const Interface encodingInterfaces[Encoding::LastEncoding + 1];
191 };
192 
194 {
195 protected:
198  {}
199 public:
201  : QStringConverter()
202  {}
204  : QStringConverter(encoding, flags)
205  {}
208  {}
209 
210 #if defined(Q_QDOC)
213  QByteArray encode(const QString &in);
215 #else
216  template<typename T>
217  struct DecodedData
218  {
221  operator QByteArray() const { return encoder->encodeAsByteArray(data); }
222  };
225  { return DecodedData<const QString &>{this, str}; }
227  { return DecodedData<QStringView>{this, in}; }
230  { return DecodedData<const QString &>{this, str}; }
232  { return DecodedData<QStringView>{this, in}; }
233 #endif
234 
235  qsizetype requiredSpace(qsizetype inputLength) const
236  { return iface->fromUtf16Len(inputLength); }
238  { return iface->fromUtf16(out, in, &state); }
239 private:
240  QByteArray encodeAsByteArray(QStringView in)
241  {
243  char *out = result.data();
244  out = iface->fromUtf16(out, in, &state);
245  result.truncate(out - result.constData());
246  return result;
247  }
248 
249 };
250 
252 {
253 protected:
256  {}
257 public:
259  : QStringConverter(encoding, flags)
260  {}
262  : QStringConverter()
263  {}
266  {}
267 
268 #if defined(Q_QDOC)
271  QString decode(const QByteArray &ba);
273 #else
274  template<typename T>
275  struct EncodedData
276  {
279  operator QString() const { return decoder->decodeAsString(data); }
280  };
283  { return EncodedData<const QByteArray &>{this, ba}; }
285  { return EncodedData<QByteArrayView>{this, ba}; }
288  { return EncodedData<const QByteArray &>{this, ba}; }
290  { return EncodedData<QByteArrayView>{this, ba}; }
291 #endif
292 
293  qsizetype requiredSpace(qsizetype inputLength) const
294  { return iface->toUtf16Len(inputLength); }
296  { return iface->toUtf16(out, ba, &state); }
297 private:
298  QString decodeAsString(QByteArrayView in)
299  {
301  const QChar *out = iface->toUtf16(result.data(), in, &state);
302  result.truncate(out - result.constData());
303  return result;
304  }
305 };
306 
307 
308 #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
309 template <typename T>
310 struct QConcatenable<QStringDecoder::EncodedData<T>>
311  : private QAbstractConcatenable
312 {
313  typedef QChar type;
314  typedef QString ConvertTo;
315  enum { ExactSize = false };
316  static qsizetype size(const QStringDecoder::EncodedData<T> &s) { return s.decoder->requiredSpace(s.data.size()); }
317  static inline void appendTo(const QStringDecoder::EncodedData<T> &s, QChar *&out)
318  {
319  out = s.decoder->appendToBuffer(out, s.data);
320  }
321 };
322 
323 template <typename T>
324 struct QConcatenable<QStringEncoder::DecodedData<T>>
325  : private QAbstractConcatenable
326 {
327  typedef char type;
328  typedef QByteArray ConvertTo;
329  enum { ExactSize = false };
330  static qsizetype size(const QStringEncoder::DecodedData<T> &s) { return s.encoder->requiredSpace(s.data.size()); }
331  static inline void appendTo(const QStringEncoder::DecodedData<T> &s, char *&out)
332  {
333  out = s.encoder->appendToBuffer(out, s.data);
334  }
335 };
336 
337 template <typename T>
339 {
341  a.reserve(len);
342  QChar *it = a.data() + a.size();
344  a.resize(qsizetype(it - a.constData())); //may be smaller than len
345  return a;
346 }
347 
348 template <typename T>
350 {
352  a.reserve(len);
353  char *it = a.data() + a.size();
355  a.resize(qsizetype(it - a.constData())); //may be smaller than len
356  return a;
357 }
358 #endif
359 
361 
362 #undef QSTRINGCONVERTER_CONSTEXPR
363 
364 #endif
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
The QStringConverter class provides a base class for encoding and decoding text. \reentrant.
QSTRINGCONVERTER_CONSTEXPR QStringConverter(Encoding encoding, Flags f)
const char * name() const
bool isValid() const
QSTRINGCONVERTER_CONSTEXPR QStringConverter(const Interface *i)
QSTRINGCONVERTER_CONSTEXPR QStringConverter()
const Interface * iface
bool hasError() const
The QStringDecoder class provides a state-based decoder for text. \reentrant.
QSTRINGCONVERTER_CONSTEXPR QStringDecoder(Encoding encoding, Flags flags=Flag::Default)
EncodedData< QByteArrayView > decode(QByteArrayView ba)
qsizetype requiredSpace(qsizetype inputLength) const
QChar * appendToBuffer(QChar *out, QByteArrayView ba)
QSTRINGCONVERTER_CONSTEXPR QStringDecoder(const Interface *i)
Q_WEAK_OVERLOAD EncodedData< const QByteArray & > decode(const QByteArray &ba)
Q_WEAK_OVERLOAD EncodedData< const QByteArray & > operator()(const QByteArray &ba)
QStringDecoder(const char *name, Flags f=Flag::Default)
EncodedData< QByteArrayView > operator()(QByteArrayView ba)
QSTRINGCONVERTER_CONSTEXPR QStringDecoder()
The QStringEncoder class provides a state-based encoder for text. \reentrant.
QStringEncoder(const char *name, Flags flags=Flag::Default)
char * appendToBuffer(char *out, QStringView in)
QSTRINGCONVERTER_CONSTEXPR QStringEncoder(Encoding encoding, Flags flags=Flag::Default)
DecodedData< QStringView > operator()(QStringView in)
qsizetype requiredSpace(qsizetype inputLength) const
DecodedData< QStringView > encode(QStringView in)
Q_WEAK_OVERLOAD DecodedData< const QString & > encode(const QString &str)
QSTRINGCONVERTER_CONSTEXPR QStringEncoder()
QSTRINGCONVERTER_CONSTEXPR QStringEncoder(const Interface *i)
Q_WEAK_OVERLOAD DecodedData< const QString & > operator()(const QString &str)
The QString class provides a Unicode character string.
Definition: qstring.h:388
qsizetype size() const
Definition: qstring.h:413
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
b clear()
QString str
[2]
double e
else opt state
[0]
constexpr Initialization Uninitialized
Definition: qnamespace.h:1613
#define QString()
Definition: parse-defines.h:51
void *PRIV() memmove(void *d, const void *s, size_t n)
void
Definition: png.h:1080
QString & operator+=(QString &that, const ProString &other)
Definition: proitems.h:262
#define Q_WEAK_OVERLOAD
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition: qflags.h:210
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition: qflags.h:227
Flags
ptrdiff_t qsizetype
Definition: qglobal.h:308
unsigned int uint
Definition: qglobal.h:334
#define Q_DISABLE_COPY(Class)
Definition: qglobal.h:515
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLfloat GLfloat f
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLenum GLsizei len
Definition: qopenglext.h:3292
GLuint in
Definition: qopenglext.h:8870
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
#define QSTRINGCONVERTER_CONSTEXPR
QByteArray ba
[0]
QTextStream out(stdout)
[7]
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QStringList::Iterator it
QChar *(*)(QChar *out, QByteArrayView in, State *state) DecoderFn
qsizetype(*)(qsizetype inLength) LengthFn
char *(*)(char *out, QStringView in, State *state) EncoderFn
constexpr State(Flags f=Flag::Default)
State & operator=(State &&other)
Definition: main.cpp:38