Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / wtf / text / StringConcatenate.h
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef StringConcatenate_h
27 #define StringConcatenate_h
28
29 #include <string.h>
30
31 #ifndef WTFString_h
32 #include "wtf/text/AtomicString.h"
33 #endif
34
35 // This macro is helpful for testing how many intermediate Strings are created while evaluating an
36 // expression containing operator+.
37 #ifndef WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING
38 #define WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING() ((void)0)
39 #endif
40
41 namespace WTF {
42
43 template<typename StringType>
44 class StringTypeAdapter {
45 };
46
47 template<>
48 class StringTypeAdapter<char> {
49 public:
50     StringTypeAdapter<char>(char buffer)
51         : m_buffer(buffer)
52     {
53     }
54
55     unsigned length() { return 1; }
56
57     bool is8Bit() { return true; }
58
59     void writeTo(LChar* destination)
60     {
61         *destination = m_buffer;
62     }
63
64     void writeTo(UChar* destination) { *destination = m_buffer; }
65
66 private:
67     unsigned char m_buffer;
68 };
69
70 template<>
71 class StringTypeAdapter<LChar> {
72 public:
73     StringTypeAdapter<LChar>(LChar buffer)
74         : m_buffer(buffer)
75     {
76     }
77
78     unsigned length() { return 1; }
79
80     bool is8Bit() { return true; }
81
82     void writeTo(LChar* destination)
83     {
84         *destination = m_buffer;
85     }
86
87     void writeTo(UChar* destination) { *destination = m_buffer; }
88
89 private:
90     LChar m_buffer;
91 };
92
93 template<>
94 class StringTypeAdapter<UChar> {
95 public:
96     StringTypeAdapter<UChar>(UChar buffer)
97         : m_buffer(buffer)
98     {
99     }
100
101     unsigned length() { return 1; }
102
103     bool is8Bit() { return m_buffer <= 0xff; }
104
105     void writeTo(LChar* destination)
106     {
107         ASSERT(is8Bit());
108         *destination = static_cast<LChar>(m_buffer);
109     }
110
111     void writeTo(UChar* destination) { *destination = m_buffer; }
112
113 private:
114     UChar m_buffer;
115 };
116
117 template<>
118 class WTF_EXPORT StringTypeAdapter<char*> {
119 public:
120     StringTypeAdapter<char*>(char* buffer)
121         : m_buffer(buffer)
122         , m_length(strlen(buffer))
123     {
124     }
125
126     unsigned length() { return m_length; }
127
128     bool is8Bit() { return true; }
129
130     void writeTo(LChar* destination);
131
132     void writeTo(UChar* destination);
133
134 private:
135     const char* m_buffer;
136     unsigned m_length;
137 };
138
139 template<>
140 class WTF_EXPORT StringTypeAdapter<LChar*> {
141 public:
142     StringTypeAdapter<LChar*>(LChar* buffer);
143
144     unsigned length() { return m_length; }
145
146     bool is8Bit() { return true; }
147
148     void writeTo(LChar* destination);
149
150     void writeTo(UChar* destination);
151
152 private:
153     const LChar* m_buffer;
154     unsigned m_length;
155 };
156
157 template<>
158 class WTF_EXPORT StringTypeAdapter<const UChar*> {
159 public:
160     StringTypeAdapter(const UChar* buffer);
161
162     unsigned length() { return m_length; }
163
164     bool is8Bit() { return false; }
165
166     NO_RETURN_DUE_TO_CRASH void writeTo(LChar*)
167     {
168         RELEASE_ASSERT(false);
169     }
170
171     void writeTo(UChar* destination);
172
173 private:
174     const UChar* m_buffer;
175     unsigned m_length;
176 };
177
178 template<>
179 class WTF_EXPORT StringTypeAdapter<const char*> {
180 public:
181     StringTypeAdapter<const char*>(const char* buffer);
182
183     unsigned length() { return m_length; }
184
185     bool is8Bit() { return true; }
186
187     void writeTo(LChar* destination);
188
189     void writeTo(UChar* destination);
190
191 private:
192     const char* m_buffer;
193     unsigned m_length;
194 };
195
196 template<>
197 class WTF_EXPORT StringTypeAdapter<const LChar*> {
198 public:
199     StringTypeAdapter<const LChar*>(const LChar* buffer);
200
201     unsigned length() { return m_length; }
202
203     bool is8Bit() { return true; }
204
205     void writeTo(LChar* destination);
206
207     void writeTo(UChar* destination);
208
209 private:
210     const LChar* m_buffer;
211     unsigned m_length;
212 };
213
214 template<>
215 class WTF_EXPORT StringTypeAdapter<Vector<char> > {
216 public:
217     StringTypeAdapter<Vector<char> >(const Vector<char>& buffer)
218         : m_buffer(buffer)
219     {
220     }
221
222     size_t length() { return m_buffer.size(); }
223
224     bool is8Bit() { return true; }
225
226     void writeTo(LChar* destination);
227
228     void writeTo(UChar* destination);
229
230 private:
231     const Vector<char>& m_buffer;
232 };
233
234 template<>
235 class StringTypeAdapter<Vector<LChar> > {
236 public:
237     StringTypeAdapter<Vector<LChar> >(const Vector<LChar>& buffer)
238         : m_buffer(buffer)
239     {
240     }
241
242     size_t length() { return m_buffer.size(); }
243
244     bool is8Bit() { return true; }
245
246     void writeTo(LChar* destination);
247
248     void writeTo(UChar* destination);
249
250 private:
251     const Vector<LChar>& m_buffer;
252 };
253
254 template<>
255 class WTF_EXPORT StringTypeAdapter<String> {
256 public:
257     StringTypeAdapter<String>(const String& string)
258         : m_buffer(string)
259     {
260     }
261
262     unsigned length() { return m_buffer.length(); }
263
264     bool is8Bit() { return m_buffer.isNull() || m_buffer.is8Bit(); }
265
266     void writeTo(LChar* destination);
267
268     void writeTo(UChar* destination);
269
270 private:
271     const String& m_buffer;
272 };
273
274 template<>
275 class StringTypeAdapter<AtomicString> {
276 public:
277     StringTypeAdapter<AtomicString>(const AtomicString& string)
278         : m_adapter(string.string())
279     {
280     }
281
282     unsigned length() { return m_adapter.length(); }
283
284     bool is8Bit() { return m_adapter.is8Bit(); }
285
286     void writeTo(LChar* destination) { m_adapter.writeTo(destination); }
287     void writeTo(UChar* destination) { m_adapter.writeTo(destination); }
288
289 private:
290     StringTypeAdapter<String> m_adapter;
291 };
292
293 inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
294 {
295     unsigned oldTotal = total;
296     total = oldTotal + addend;
297     if (total < oldTotal)
298         overflow = true;
299 }
300
301 template<typename StringType1, typename StringType2>
302 PassRefPtr<StringImpl> makeString(StringType1 string1, StringType2 string2)
303 {
304     StringTypeAdapter<StringType1> adapter1(string1);
305     StringTypeAdapter<StringType2> adapter2(string2);
306
307     bool overflow = false;
308     unsigned length = adapter1.length();
309     sumWithOverflow(length, adapter2.length(), overflow);
310     if (overflow)
311         return nullptr;
312
313     if (adapter1.is8Bit() && adapter2.is8Bit()) {
314         LChar* buffer;
315         RefPtr<StringImpl> resultImpl = StringImpl::createUninitialized(length, buffer);
316         if (!resultImpl)
317             return nullptr;
318
319         LChar* result = buffer;
320         adapter1.writeTo(result);
321         result += adapter1.length();
322         adapter2.writeTo(result);
323
324         return resultImpl.release();
325     }
326
327     UChar* buffer;
328     RefPtr<StringImpl> resultImpl = StringImpl::createUninitialized(length, buffer);
329     if (!resultImpl)
330         return nullptr;
331
332     UChar* result = buffer;
333     adapter1.writeTo(result);
334     result += adapter1.length();
335     adapter2.writeTo(result);
336
337     return resultImpl.release();
338 }
339
340 } // namespace WTF
341
342 #include "wtf/text/StringOperators.h"
343 #endif