Qt 4.8
qstringbuilder.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QSTRINGBUILDER_H
43 #define QSTRINGBUILDER_H
44 
45 #include <QtCore/qstring.h>
46 #include <QtCore/qbytearray.h>
47 
48 #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
49 # if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
50 # include <QtCore/qmap.h>
51 # endif
52 #endif
53 
54 #include <string.h>
55 
57 
59 
60 QT_MODULE(Core)
61 
62 // ### Qt 5: merge with QLatin1String
64 {
65 public:
66  int size() const { return m_size; }
67  const char *data() const { return m_data; }
68 
69  template <int N>
70  QLatin1Literal(const char (&str)[N])
71  : m_size(N - 1), m_data(str) {}
72 
73 private:
74  const int m_size;
75  const char * const m_data;
76 };
77 
79 {
80 protected:
81  static void convertFromAscii(const char *a, int len, QChar *&out);
82  static void convertToAscii(const QChar *a, int len, char *&out);
83  static inline void convertFromAscii(char a, QChar *&out)
84  {
85 #ifndef QT_NO_TEXTCODEC
87  *out++ = QChar::fromAscii(a);
88  else
89 #endif
90  *out++ = QLatin1Char(a);
91  }
92 
93  static inline void convertToAscii(QChar a, char *&out)
94  {
95 #ifndef QT_NO_TEXTCODEC
97  *out++ = a.toAscii(); //###
98  else
99 #endif
100  convertToLatin1(a, out);
101  }
102 
103  static inline void convertToLatin1(QChar a, char *&out)
104  {
105  *out++ = a.unicode() > 0xff ? '?' : char(a.unicode());
106  }
107 };
108 
109 template <typename T> struct QConcatenable {};
110 
111 template <typename A, typename B>
113 {
114 public:
115  QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {}
116 private:
117  friend class QByteArray;
118  friend class QString;
119  template <typename T> T convertTo() const
120  {
121  const uint len = QConcatenable< QStringBuilder<A, B> >::size(*this);
122  T s(len, Qt::Uninitialized);
123 
124  typename T::iterator d = s.data();
125  typename T::const_iterator const start = d;
126  QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
127 
128  if (!QConcatenable< QStringBuilder<A, B> >::ExactSize && int(len) != d - start) {
129  // this resize is necessary since we allocate a bit too much
130  // when dealing with variable sized 8-bit encodings
131  s.resize(d - start);
132  }
133  return s;
134  }
135 
138 public:
139  operator ConvertTo() const { return convertTo<ConvertTo>(); }
140 
141  QByteArray toLatin1() const { return convertTo<QString>().toLatin1(); }
142  int size() const { return Concatenable::size(*this); }
143 
144  const A &a;
145  const B &b;
146 };
147 
148 template <>
150 {
151  public:
152  QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
153 
154  operator QString() const
155  { QString r(a); r += b; return r; }
156  QByteArray toLatin1() const { return QString(*this).toLatin1(); }
157 
158  const QString &a;
159  const QString &b;
160 };
161 
162 template <>
164 {
165  public:
166  QStringBuilder(const QByteArray &a_, const QByteArray &b_) : a(a_), b(b_) {}
167 
168  operator QByteArray() const
169  { QByteArray r(a); r += b; return r; }
170 
171  const QByteArray &a;
172  const QByteArray &b;
173 };
174 
175 
176 template <> struct QConcatenable<char> : private QAbstractConcatenable
177 {
178  typedef char type;
180  enum { ExactSize = true };
181  static int size(const char) { return 1; }
182 #ifndef QT_NO_CAST_FROM_ASCII
183  static inline QT_ASCII_CAST_WARN void appendTo(const char c, QChar *&out)
184  {
186  }
187 #endif
188  static inline void appendTo(const char c, char *&out)
189  { *out++ = c; }
190 };
191 
192 template <> struct QConcatenable<QLatin1Char>
193 {
194  typedef QLatin1Char type;
196  enum { ExactSize = true };
197  static int size(const QLatin1Char) { return 1; }
198  static inline void appendTo(const QLatin1Char c, QChar *&out)
199  { *out++ = c; }
200  static inline void appendTo(const QLatin1Char c, char *&out)
201  { *out++ = c.toLatin1(); }
202 };
203 
204 template <> struct QConcatenable<QChar> : private QAbstractConcatenable
205 {
206  typedef QChar type;
208  enum { ExactSize = true };
209  static int size(const QChar) { return 1; }
210  static inline void appendTo(const QChar c, QChar *&out)
211  { *out++ = c; }
212 #ifndef QT_NO_CAST_TO_ASCII
213  static inline QT_ASCII_CAST_WARN void appendTo(const QChar c, char *&out)
214  { convertToAscii(c, out); }
215 #endif
216 };
217 
218 template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable
219 {
220  typedef QCharRef type;
222  enum { ExactSize = true };
223  static int size(const QCharRef &) { return 1; }
224  static inline void appendTo(const QCharRef &c, QChar *&out)
225  { *out++ = QChar(c); }
226 #ifndef QT_NO_CAST_TO_ASCII
227  static inline QT_ASCII_CAST_WARN void appendTo(const QCharRef &c, char *&out)
228  { convertToAscii(c, out); }
229 #endif
230 };
231 
232 template <> struct QConcatenable<QLatin1String>
233 {
236  enum { ExactSize = true };
237  static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
238  static inline void appendTo(const QLatin1String &a, QChar *&out)
239  {
240  for (const char *s = a.latin1(); *s; )
241  *out++ = QLatin1Char(*s++);
242  }
243  static inline void appendTo(const QLatin1String &a, char *&out)
244  {
245  for (const char *s = a.latin1(); *s; )
246  *out++ = *s++;
247  }
248 };
249 
250 template <> struct QConcatenable<QLatin1Literal>
251 {
252  typedef QLatin1Literal type;
254  enum { ExactSize = true };
255  static int size(const QLatin1Literal &a) { return a.size(); }
256  static inline void appendTo(const QLatin1Literal &a, QChar *&out)
257  {
258  for (const char *s = a.data(); *s; )
259  *out++ = QLatin1Char(*s++);
260  }
261  static inline void appendTo(const QLatin1Literal &a, char *&out)
262  {
263  for (const char *s = a.data(); *s; )
264  *out++ = *s++;
265  }
266 };
267 
268 template <> struct QConcatenable<QString> : private QAbstractConcatenable
269 {
270  typedef QString type;
272  enum { ExactSize = true };
273  static int size(const QString &a) { return a.size(); }
274  static inline void appendTo(const QString &a, QChar *&out)
275  {
276  const int n = a.size();
277  memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
278  out += n;
279  }
280 #ifndef QT_NO_CAST_TO_ASCII
281  static inline QT_ASCII_CAST_WARN void appendTo(const QString &a, char *&out)
282  { convertToAscii(a.constData(), a.length(), out); }
283 #endif
284 };
285 
286 template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
287 {
288  typedef QStringRef type;
290  enum { ExactSize = true };
291  static int size(const QStringRef &a) { return a.size(); }
292  static inline void appendTo(const QStringRef &a, QChar *&out)
293  {
294  const int n = a.size();
295  memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
296  out += n;
297  }
298 #ifndef QT_NO_CAST_TO_ASCII
299  static inline QT_ASCII_CAST_WARN void appendTo(const QStringRef &a, char *&out)
300  { convertToAscii(a.constData(), a.length(), out); }
301 #endif
302 
303 };
304 
305 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
306 {
307  typedef char type[N];
309  enum { ExactSize = false };
310  static int size(const char[N]) { return N - 1; }
311 #ifndef QT_NO_CAST_FROM_ASCII
312  static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
313  {
315  }
316 #endif
317  static inline void appendTo(const char a[N], char *&out)
318  {
319  while (*a)
320  *out++ = *a++;
321  }
322 };
323 
324 template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
325 {
326  typedef const char type[N];
328  enum { ExactSize = false };
329  static int size(const char[N]) { return N - 1; }
330 #ifndef QT_NO_CAST_FROM_ASCII
331  static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
332  {
334  }
335 #endif
336  static inline void appendTo(const char a[N], char *&out)
337  {
338  while (*a)
339  *out++ = *a++;
340  }
341 };
342 
343 template <> struct QConcatenable<const char *> : private QAbstractConcatenable
344 {
345  typedef char const *type;
347  enum { ExactSize = false };
348  static int size(const char *a) { return qstrlen(a); }
349 #ifndef QT_NO_CAST_FROM_ASCII
350  static inline void QT_ASCII_CAST_WARN appendTo(const char *a, QChar *&out)
352 #endif
353  static inline void appendTo(const char *a, char *&out)
354  {
355  if (!a)
356  return;
357  while (*a)
358  *out++ = *a++;
359  }
360 };
361 
362 template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
363 {
364  typedef QByteArray type;
366  enum { ExactSize = false };
367  static int size(const QByteArray &ba) { return ba.size(); }
368 #ifndef QT_NO_CAST_FROM_ASCII
369  static inline void appendTo(const QByteArray &ba, QChar *&out)
370  {
371  // adding 1 because convertFromAscii expects the size including the null-termination
373  }
374 #endif
375  static inline void appendTo(const QByteArray &ba, char *&out)
376  {
377  const char *a = ba.constData();
378  const char * const end = ba.end();
379  while (a != end)
380  *out++ = *a++;
381  }
382 };
383 
384 namespace QtStringBuilder {
385  template <typename A, typename B> struct ConvertToTypeHelper
386  { typedef A ConvertTo; };
387  template <typename T> struct ConvertToTypeHelper<T, QString>
388  { typedef QString ConvertTo; };
389 }
390 
391 template <typename A, typename B>
393 {
397  static int size(const type &p)
398  {
400  }
401  template<typename T> static inline void appendTo(const type &p, T *&out)
402  {
405  }
406 };
407 
408 template <typename A, typename B>
410 operator%(const A &a, const B &b)
411 {
413 }
414 
415 // QT_USE_FAST_OPERATOR_PLUS was introduced in 4.7, QT_USE_QSTRINGBUILDER is to be used from 4.8 onwards
416 // QT_USE_FAST_OPERATOR_PLUS does not remove the normal operator+ for QByteArray
417 #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
418 template <typename A, typename B>
420 operator+(const A &a, const B &b)
421 {
422  return QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>(a, b);
423 }
424 #endif
425 
426 template <typename A, typename B>
428 {
429 #ifndef QT_NO_CAST_TO_ASCII
430  if (sizeof(typename QConcatenable< QStringBuilder<A, B> >::ConvertTo::value_type) == sizeof(QChar)) {
431  //it is not save to optimize as in utf8 it is not possible to compute the size
432  return a += QString(b);
433  }
434 #endif
435  int len = a.size() + QConcatenable< QStringBuilder<A, B> >::size(b);
436  a.reserve(len);
437  char *it = a.data() + a.size();
438  QConcatenable< QStringBuilder<A, B> >::appendTo(b, it);
439  a.resize(len); //we need to resize after the appendTo for the case str+=foo+str
440  return a;
441 }
442 
443 template <typename A, typename B>
445 {
446  int len = a.size() + QConcatenable< QStringBuilder<A, B> >::size(b);
447  a.reserve(len);
448  QChar *it = a.data() + a.size();
449  QConcatenable< QStringBuilder<A, B> >::appendTo(b, it);
450  a.resize(it - a.constData()); //may be smaller than len if there was conversion from utf8
451  return a;
452 }
453 
454 
456 
458 
459 #endif // QSTRINGBUILDER_H
#define QT_ASCII_CAST_WARN
Definition: qglobal.h:1144
double d
Definition: qnumeric_p.h:62
QConcatenable< QStringBuilder< A, B > > Concatenable
static void appendTo(const QLatin1Char c, char *&out)
static int size(const QLatin1Literal &a)
The QLatin1Literal class provides a thin wrapper around string literals used in source code...
int type
Definition: qmetatype.cpp:239
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static void appendTo(const char a[N], char *&out)
#define QT_MODULE(x)
Definition: qglobal.h:2783
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
int length() const
Returns the number of characters referred to by the string reference.
Definition: qstring.h:1116
char toLatin1() const
Converts a Latin-1 character to an 8-bit ASCII representation of the character.
Definition: qchar.h:63
QByteArray & operator+=(QByteArray &a, const QStringBuilder< A, B > &b)
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
#define QT_BEGIN_HEADER
Definition: qglobal.h:136
#define it(className, varName)
QtStringBuilder::ConvertToTypeHelper< typename QConcatenable< A >::ConvertTo, typename QConcatenable< B >::ConvertTo >::ConvertTo ConvertTo
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static QT_ASCII_CAST_WARN void appendTo(const QStringRef &a, char *&out)
Concatenable::ConvertTo ConvertTo
const int m_size
long ASN1_INTEGER_get ASN1_INTEGER * a
T convertTo() const
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define A(arg)
static void appendTo(const QByteArray &ba, QChar *&out)
static void convertFromAscii(const char *a, int len, QChar *&out)
static void appendTo(const QChar c, QChar *&out)
static QT_ASCII_CAST_WARN void appendTo(const QString &a, char *&out)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
static void appendTo(const char c, char *&out)
QLatin1Literal(const char(&str)[N])
Constructs a new literal from the string str.
const QChar * constData() const
Same as unicode().
Definition: qstring.h:1159
void reserve(int size)
Attempts to allocate memory for at least size characters.
Definition: qstring.h:881
QStringBuilder(const QByteArray &a_, const QByteArray &b_)
static int size(const QLatin1String &a)
static void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
static void appendTo(const char a[N], char *&out)
static void convertToLatin1(QChar a, char *&out)
static int size(const char)
int size() const
Returns the number of characters referred to by the string reference.
Definition: qstring.h:1114
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
const char * latin1() const
Returns the Latin-1 string stored in this object.
Definition: qstring.h:661
The QStringBuilder class is a template class that provides a facility to build up QStrings from small...
static void appendTo(const type &p, T *&out)
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
static void appendTo(const QLatin1Literal &a, char *&out)
static int size(const char *a)
QByteArray toLatin1() const
Returns a Latin-1 representation of the string as a QByteArray.
unsigned int uint
Definition: qglobal.h:996
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
static void appendTo(const QLatin1String &a, QChar *&out)
static void appendTo(const QCharRef &c, QChar *&out)
static void appendTo(const QString &a, QChar *&out)
static void appendTo(const QLatin1Char c, QChar *&out)
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
QStringBuilder< typename QConcatenable< A >::type, typename QConcatenable< B >::type > operator%(const A &a, const B &b)
static void appendTo(const QLatin1String &a, char *&out)
The QStringRef class provides a thin wrapper around QString substrings.
Definition: qstring.h:1099
static int size(const QChar)
const char * data() const
Returns a pointer to the first character of the string literal.
static int size(const QStringRef &a)
static void convertToAscii(QChar a, char *&out)
char toAscii() const
Returns the character value of the QChar obtained using the current codec used to read C strings...
Definition: qchar.cpp:1490
void resize(int size)
Sets the size of the string to size characters.
Definition: qstring.cpp:1353
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
uint qstrlen(const char *str)
Definition: qbytearray.h:79
static int size(const char[N])
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
static QT_ASCII_CAST_WARN void appendTo(const char c, QChar *&out)
static void appendTo(const QByteArray &ba, char *&out)
static QT_ASCII_CAST_WARN void appendTo(const QCharRef &c, char *&out)
static int size(const QByteArray &ba)
static void QT_ASCII_CAST_WARN appendTo(const char *a, QChar *&out)
int size() const
The QCharRef class is a helper class for QString.
Definition: qstring.h:785
void resize(int size)
Sets the size of the byte array to size bytes.
static QTextCodec * codecForCStrings
Definition: qstring.h:621
static void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
const char *const m_data
static QT_ASCII_CAST_WARN void appendTo(const QChar c, char *&out)
static void appendTo(const QLatin1Literal &a, QChar *&out)
static void appendTo(const QStringRef &a, QChar *&out)
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
static void convertFromAscii(char a, QChar *&out)
static int size(const QLatin1Char)
QStringBuilder(const A &a_, const B &b_)
Constructs a QStringBuilder from a and b.
static void appendTo(const char *a, char *&out)
static int size(const QCharRef &)
void reserve(int size)
Attempts to allocate memory for at least size bytes.
Definition: qbytearray.h:449
#define class
static const KeyPair *const end
static QChar fromAscii(char c)
Converts the ASCII character c to its equivalent QChar.
Definition: qchar.cpp:1521
#define QT_END_HEADER
Definition: qglobal.h:137
iterator end()
Definition: qbytearray.h:499
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QByteArray convertToLatin1(const JSC::UString &str)
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
QStringBuilder(const QString &a_, const QString &b_)
int size() const
Returns the number of characters in the literal excluding the trailing NULL char. ...
static int size(const QString &a)
static int size(const char[N])
timeval operator+(const timeval &t1, const timeval &t2)
Definition: qcore_unix_p.h:126