64 public: |
64 public: |
65 int size() const { return m_size; } |
65 int size() const { return m_size; } |
66 const char *data() const { return m_data; } |
66 const char *data() const { return m_data; } |
67 |
67 |
68 template <int N> |
68 template <int N> |
69 QLatin1Literal(const char (&str)[N]) |
69 QLatin1Literal(const char (&str)[N]) |
70 : m_size(N - 1), m_data(str) {} |
70 : m_size(N - 1), m_data(str) {} |
71 |
71 |
72 private: |
72 private: |
73 const int m_size; |
73 const int m_size; |
74 const char *m_data; |
74 const char *m_data; |
75 }; |
75 }; |
76 |
76 |
|
77 struct Q_CORE_EXPORT QAbstractConcatenable |
|
78 { |
|
79 protected: |
|
80 static void convertFromAscii(const char *a, int len, QChar *&out); |
|
81 |
|
82 static inline void convertFromAscii(char a, QChar *&out) |
|
83 { |
|
84 #ifndef QT_NO_TEXTCODEC |
|
85 if (QString::codecForCStrings) |
|
86 *out++ = QChar::fromAscii(a); |
|
87 else |
|
88 #endif |
|
89 *out++ = QLatin1Char(a); |
|
90 } |
|
91 }; |
77 |
92 |
78 template <typename T> struct QConcatenable {}; |
93 template <typename T> struct QConcatenable {}; |
79 |
94 |
80 template <typename A, typename B> |
95 template <typename A, typename B> |
81 class QStringBuilder |
96 class QStringBuilder |
85 |
100 |
86 operator QString() const |
101 operator QString() const |
87 { |
102 { |
88 QString s(QConcatenable< QStringBuilder<A, B> >::size(*this), |
103 QString s(QConcatenable< QStringBuilder<A, B> >::size(*this), |
89 Qt::Uninitialized); |
104 Qt::Uninitialized); |
90 |
105 |
91 QChar *d = s.data(); |
106 QChar *d = s.data(); |
92 QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d); |
107 QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d); |
|
108 // this resize is necessary since we allocate a bit too much |
|
109 // when dealing with variable sized 8-bit encodings |
|
110 s.resize(d - s.data()); |
93 return s; |
111 return s; |
94 } |
112 } |
95 QByteArray toLatin1() const { return QString(*this).toLatin1(); } |
113 QByteArray toLatin1() const { return QString(*this).toLatin1(); } |
96 |
114 |
97 const A &a; |
115 const A &a; |
98 const B &b; |
116 const B &b; |
99 }; |
117 }; |
100 |
118 |
101 |
119 |
102 template <> struct QConcatenable<char> |
120 template <> struct QConcatenable<char> : private QAbstractConcatenable |
103 { |
121 { |
104 typedef char type; |
122 typedef char type; |
105 static int size(const char) { return 1; } |
123 static int size(const char) { return 1; } |
106 static inline void appendTo(const char c, QChar *&out) |
124 static inline void appendTo(const char c, QChar *&out) |
107 { |
125 { |
108 *out++ = QLatin1Char(c); |
126 QAbstractConcatenable::convertFromAscii(c, out); |
109 } |
127 } |
110 }; |
128 }; |
111 |
129 |
112 template <> struct QConcatenable<QLatin1Char> |
130 template <> struct QConcatenable<QLatin1Char> |
113 { |
131 { |
180 static int size(const QStringRef &a) { return a.size(); } |
198 static int size(const QStringRef &a) { return a.size(); } |
181 static inline void appendTo(QStringRef a, QChar *&out) |
199 static inline void appendTo(QStringRef a, QChar *&out) |
182 { |
200 { |
183 const int n = a.size(); |
201 const int n = a.size(); |
184 memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n); |
202 memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n); |
185 out += n; |
203 out += n; |
186 } |
204 } |
187 }; |
205 }; |
188 |
206 |
189 #ifndef QT_NO_CAST_FROM_ASCII |
207 #ifndef QT_NO_CAST_FROM_ASCII |
190 template <int N> struct QConcatenable<char[N]> |
208 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable |
191 { |
209 { |
192 typedef char type[N]; |
210 typedef char type[N]; |
193 static int size(const char[N]) { return N - 1; } |
211 static int size(const char[N]) |
|
212 { |
|
213 return N - 1; |
|
214 } |
194 static inline void appendTo(const char a[N], QChar *&out) |
215 static inline void appendTo(const char a[N], QChar *&out) |
195 { |
216 { |
196 for (int i = 0; i < N - 1; ++i) |
217 QAbstractConcatenable::convertFromAscii(a, N, out); |
197 *out++ = QLatin1Char(a[i]); |
218 } |
198 } |
219 }; |
199 }; |
220 |
200 |
221 template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable |
201 template <int N> struct QConcatenable<const char[N]> |
|
202 { |
222 { |
203 typedef const char type[N]; |
223 typedef const char type[N]; |
204 static int size(const char[N]) { return N - 1; } |
224 static int size(const char[N]) { return N - 1; } |
205 static inline void appendTo(const char a[N], QChar *&out) |
225 static inline void appendTo(const char a[N], QChar *&out) |
206 { |
226 { |
207 for (int i = 0; i < N - 1; ++i) |
227 QAbstractConcatenable::convertFromAscii(a, N, out); |
208 *out++ = QLatin1Char(a[i]); |
228 } |
209 } |
229 }; |
210 }; |
230 |
211 |
231 template <> struct QConcatenable<const char *> : private QAbstractConcatenable |
212 template <> struct QConcatenable<const char *> |
|
213 { |
232 { |
214 typedef char const *type; |
233 typedef char const *type; |
215 static int size(const char *a) { return qstrlen(a); } |
234 static int size(const char *a) { return qstrlen(a); } |
216 static inline void appendTo(const char *a, QChar *&out) |
235 static inline void appendTo(const char *a, QChar *&out) |
217 { |
236 { |
218 while (*a) |
237 QAbstractConcatenable::convertFromAscii(a, -1, out); |
219 *out++ = QLatin1Char(*a++); |
238 } |
220 } |
239 }; |
221 }; |
240 |
222 |
241 template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable |
223 template <> struct QConcatenable<QByteArray> |
|
224 { |
242 { |
225 typedef QByteArray type; |
243 typedef QByteArray type; |
226 static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); } |
244 static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); } |
227 static inline void appendTo(const QByteArray &ba, QChar *&out) |
245 static inline void appendTo(const QByteArray &ba, QChar *&out) |
228 { |
246 { |
229 const char *data = ba.constData(); |
247 QAbstractConcatenable::convertFromAscii(ba.constData(), -1, out); |
230 while (*data) |
|
231 *out++ = QLatin1Char(*data++); |
|
232 } |
248 } |
233 }; |
249 }; |
234 #endif |
250 #endif |
235 |
251 |
236 template <typename A, typename B> |
252 template <typename A, typename B> |
237 struct QConcatenable< QStringBuilder<A, B> > |
253 struct QConcatenable< QStringBuilder<A, B> > |
238 { |
254 { |
239 typedef QStringBuilder<A, B> type; |
255 typedef QStringBuilder<A, B> type; |
240 static int size(const type &p) |
256 static int size(const type &p) |
241 { |
257 { |
242 return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b); |
258 return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b); |
243 } |
259 } |
244 static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out) |
260 static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out) |
245 { |
261 { |