OLD | NEW |
| (Empty) |
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 w
hile 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 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 for (unsigned i = 0; i < m_length; ++i) | |
133 destination[i] = static_cast<LChar>(m_buffer[i]); | |
134 } | |
135 | |
136 void writeTo(UChar* destination) | |
137 { | |
138 for (unsigned i = 0; i < m_length; ++i) { | |
139 unsigned char c = m_buffer[i]; | |
140 destination[i] = c; | |
141 } | |
142 } | |
143 | |
144 private: | |
145 const char* m_buffer; | |
146 unsigned m_length; | |
147 }; | |
148 | |
149 template<> | |
150 class StringTypeAdapter<LChar*> { | |
151 public: | |
152 StringTypeAdapter<LChar*>(LChar* buffer) | |
153 : m_buffer(buffer) | |
154 , m_length(strlen(reinterpret_cast<char*>(buffer))) | |
155 { | |
156 } | |
157 | |
158 unsigned length() { return m_length; } | |
159 | |
160 bool is8Bit() { return true; } | |
161 | |
162 void writeTo(LChar* destination) | |
163 { | |
164 memcpy(destination, m_buffer, m_length * sizeof(LChar)); | |
165 } | |
166 | |
167 void writeTo(UChar* destination) | |
168 { | |
169 StringImpl::copyChars(destination, m_buffer, m_length); | |
170 } | |
171 | |
172 private: | |
173 const LChar* m_buffer; | |
174 unsigned m_length; | |
175 }; | |
176 | |
177 template<> | |
178 class StringTypeAdapter<const UChar*> { | |
179 public: | |
180 StringTypeAdapter<const UChar*>(const UChar* buffer) | |
181 : m_buffer(buffer) | |
182 { | |
183 size_t len = 0; | |
184 while (m_buffer[len] != UChar(0)) | |
185 ++len; | |
186 | |
187 RELEASE_ASSERT(len <= std::numeric_limits<unsigned>::max()); | |
188 | |
189 m_length = len; | |
190 } | |
191 | |
192 unsigned length() { return m_length; } | |
193 | |
194 bool is8Bit() { return false; } | |
195 | |
196 NO_RETURN_DUE_TO_CRASH void writeTo(LChar*) | |
197 { | |
198 RELEASE_ASSERT(false); | |
199 } | |
200 | |
201 void writeTo(UChar* destination) | |
202 { | |
203 memcpy(destination, m_buffer, m_length * sizeof(UChar)); | |
204 } | |
205 | |
206 private: | |
207 const UChar* m_buffer; | |
208 unsigned m_length; | |
209 }; | |
210 | |
211 template<> | |
212 class StringTypeAdapter<const char*> { | |
213 public: | |
214 StringTypeAdapter<const char*>(const char* buffer) | |
215 : m_buffer(buffer) | |
216 , m_length(strlen(buffer)) | |
217 { | |
218 } | |
219 | |
220 unsigned length() { return m_length; } | |
221 | |
222 bool is8Bit() { return true; } | |
223 | |
224 void writeTo(LChar* destination) | |
225 { | |
226 memcpy(destination, m_buffer, static_cast<size_t>(m_length) * sizeof(LCh
ar)); | |
227 } | |
228 | |
229 void writeTo(UChar* destination) | |
230 { | |
231 for (unsigned i = 0; i < m_length; ++i) { | |
232 unsigned char c = m_buffer[i]; | |
233 destination[i] = c; | |
234 } | |
235 } | |
236 | |
237 private: | |
238 const char* m_buffer; | |
239 unsigned m_length; | |
240 }; | |
241 | |
242 template<> | |
243 class StringTypeAdapter<const LChar*> { | |
244 public: | |
245 StringTypeAdapter<const LChar*>(const LChar* buffer) | |
246 : m_buffer(buffer) | |
247 , m_length(strlen(reinterpret_cast<const char*>(buffer))) | |
248 { | |
249 } | |
250 | |
251 unsigned length() { return m_length; } | |
252 | |
253 bool is8Bit() { return true; } | |
254 | |
255 void writeTo(LChar* destination) | |
256 { | |
257 memcpy(destination, m_buffer, static_cast<size_t>(m_length) * sizeof(LCh
ar)); | |
258 } | |
259 | |
260 void writeTo(UChar* destination) | |
261 { | |
262 StringImpl::copyChars(destination, m_buffer, m_length); | |
263 } | |
264 | |
265 private: | |
266 const LChar* m_buffer; | |
267 unsigned m_length; | |
268 }; | |
269 | |
270 template<> | |
271 class StringTypeAdapter<ASCIILiteral> { | |
272 public: | |
273 StringTypeAdapter<ASCIILiteral>(ASCIILiteral buffer) | |
274 : m_buffer(reinterpret_cast<const LChar*>(static_cast<const char*>(buffe
r))) | |
275 , m_length(strlen(buffer)) | |
276 { | |
277 } | |
278 | |
279 size_t length() { return m_length; } | |
280 | |
281 bool is8Bit() { return true; } | |
282 | |
283 void writeTo(LChar* destination) | |
284 { | |
285 memcpy(destination, m_buffer, static_cast<size_t>(m_length)); | |
286 } | |
287 | |
288 void writeTo(UChar* destination) | |
289 { | |
290 StringImpl::copyChars(destination, m_buffer, m_length); | |
291 } | |
292 | |
293 private: | |
294 const LChar* m_buffer; | |
295 unsigned m_length; | |
296 }; | |
297 | |
298 template<> | |
299 class StringTypeAdapter<Vector<char> > { | |
300 public: | |
301 StringTypeAdapter<Vector<char> >(const Vector<char>& buffer) | |
302 : m_buffer(buffer) | |
303 { | |
304 } | |
305 | |
306 size_t length() { return m_buffer.size(); } | |
307 | |
308 bool is8Bit() { return true; } | |
309 | |
310 void writeTo(LChar* destination) | |
311 { | |
312 for (size_t i = 0; i < m_buffer.size(); ++i) | |
313 destination[i] = static_cast<unsigned char>(m_buffer[i]); | |
314 } | |
315 | |
316 void writeTo(UChar* destination) | |
317 { | |
318 for (size_t i = 0; i < m_buffer.size(); ++i) | |
319 destination[i] = static_cast<unsigned char>(m_buffer[i]); | |
320 } | |
321 | |
322 private: | |
323 const Vector<char>& m_buffer; | |
324 }; | |
325 | |
326 template<> | |
327 class StringTypeAdapter<Vector<LChar> > { | |
328 public: | |
329 StringTypeAdapter<Vector<LChar> >(const Vector<LChar>& buffer) | |
330 : m_buffer(buffer) | |
331 { | |
332 } | |
333 | |
334 size_t length() { return m_buffer.size(); } | |
335 | |
336 bool is8Bit() { return true; } | |
337 | |
338 void writeTo(LChar* destination) | |
339 { | |
340 for (size_t i = 0; i < m_buffer.size(); ++i) | |
341 destination[i] = m_buffer[i]; | |
342 } | |
343 | |
344 void writeTo(UChar* destination) | |
345 { | |
346 for (size_t i = 0; i < m_buffer.size(); ++i) | |
347 destination[i] = m_buffer[i]; | |
348 } | |
349 | |
350 private: | |
351 const Vector<LChar>& m_buffer; | |
352 }; | |
353 | |
354 template<> | |
355 class StringTypeAdapter<String> { | |
356 public: | |
357 StringTypeAdapter<String>(const String& string) | |
358 : m_buffer(string) | |
359 { | |
360 } | |
361 | |
362 unsigned length() { return m_buffer.length(); } | |
363 | |
364 bool is8Bit() { return m_buffer.isNull() || m_buffer.is8Bit(); } | |
365 | |
366 void writeTo(LChar* destination) | |
367 { | |
368 unsigned length = m_buffer.length(); | |
369 | |
370 ASSERT(is8Bit()); | |
371 const LChar* data = m_buffer.characters8(); | |
372 for (unsigned i = 0; i < length; ++i) | |
373 destination[i] = data[i]; | |
374 | |
375 WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING(); | |
376 } | |
377 | |
378 void writeTo(UChar* destination) | |
379 { | |
380 unsigned length = m_buffer.length(); | |
381 | |
382 if (is8Bit()) { | |
383 const LChar* data = m_buffer.characters8(); | |
384 for (unsigned i = 0; i < length; ++i) | |
385 destination[i] = data[i]; | |
386 } else { | |
387 const UChar* data = m_buffer.characters16(); | |
388 for (unsigned i = 0; i < length; ++i) | |
389 destination[i] = data[i]; | |
390 } | |
391 | |
392 WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING(); | |
393 } | |
394 | |
395 private: | |
396 const String& m_buffer; | |
397 }; | |
398 | |
399 template<> | |
400 class StringTypeAdapter<AtomicString> { | |
401 public: | |
402 StringTypeAdapter<AtomicString>(const AtomicString& string) | |
403 : m_adapter(string.string()) | |
404 { | |
405 } | |
406 | |
407 unsigned length() { return m_adapter.length(); } | |
408 | |
409 bool is8Bit() { return m_adapter.is8Bit(); } | |
410 | |
411 void writeTo(LChar* destination) { m_adapter.writeTo(destination); } | |
412 void writeTo(UChar* destination) { m_adapter.writeTo(destination); } | |
413 | |
414 private: | |
415 StringTypeAdapter<String> m_adapter; | |
416 }; | |
417 | |
418 inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) | |
419 { | |
420 unsigned oldTotal = total; | |
421 total = oldTotal + addend; | |
422 if (total < oldTotal) | |
423 overflow = true; | |
424 } | |
425 | |
426 template<typename StringType1, typename StringType2> | |
427 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2) | |
428 { | |
429 StringTypeAdapter<StringType1> adapter1(string1); | |
430 StringTypeAdapter<StringType2> adapter2(string2); | |
431 | |
432 bool overflow = false; | |
433 unsigned length = adapter1.length(); | |
434 sumWithOverflow(length, adapter2.length(), overflow); | |
435 if (overflow) | |
436 return 0; | |
437 | |
438 if (adapter1.is8Bit() && adapter2.is8Bit()) { | |
439 LChar* buffer; | |
440 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
441 if (!resultImpl) | |
442 return 0; | |
443 | |
444 LChar* result = buffer; | |
445 adapter1.writeTo(result); | |
446 result += adapter1.length(); | |
447 adapter2.writeTo(result); | |
448 | |
449 return resultImpl.release(); | |
450 } | |
451 | |
452 UChar* buffer; | |
453 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
454 if (!resultImpl) | |
455 return 0; | |
456 | |
457 UChar* result = buffer; | |
458 adapter1.writeTo(result); | |
459 result += adapter1.length(); | |
460 adapter2.writeTo(result); | |
461 | |
462 return resultImpl.release(); | |
463 } | |
464 | |
465 template<typename StringType1, typename StringType2, typename StringType3> | |
466 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3) | |
467 { | |
468 StringTypeAdapter<StringType1> adapter1(string1); | |
469 StringTypeAdapter<StringType2> adapter2(string2); | |
470 StringTypeAdapter<StringType3> adapter3(string3); | |
471 | |
472 bool overflow = false; | |
473 unsigned length = adapter1.length(); | |
474 sumWithOverflow(length, adapter2.length(), overflow); | |
475 sumWithOverflow(length, adapter3.length(), overflow); | |
476 if (overflow) | |
477 return 0; | |
478 | |
479 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit()) { | |
480 LChar* buffer; | |
481 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
482 if (!resultImpl) | |
483 return 0; | |
484 | |
485 LChar* result = buffer; | |
486 adapter1.writeTo(result); | |
487 result += adapter1.length(); | |
488 adapter2.writeTo(result); | |
489 result += adapter2.length(); | |
490 adapter3.writeTo(result); | |
491 | |
492 return resultImpl.release(); | |
493 } | |
494 | |
495 UChar* buffer = 0; | |
496 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
497 if (!resultImpl) | |
498 return 0; | |
499 | |
500 UChar* result = buffer; | |
501 adapter1.writeTo(result); | |
502 result += adapter1.length(); | |
503 adapter2.writeTo(result); | |
504 result += adapter2.length(); | |
505 adapter3.writeTo(result); | |
506 | |
507 return resultImpl.release(); | |
508 } | |
509 | |
510 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4> | |
511 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3, StringType4 string4) | |
512 { | |
513 StringTypeAdapter<StringType1> adapter1(string1); | |
514 StringTypeAdapter<StringType2> adapter2(string2); | |
515 StringTypeAdapter<StringType3> adapter3(string3); | |
516 StringTypeAdapter<StringType4> adapter4(string4); | |
517 | |
518 bool overflow = false; | |
519 unsigned length = adapter1.length(); | |
520 sumWithOverflow(length, adapter2.length(), overflow); | |
521 sumWithOverflow(length, adapter3.length(), overflow); | |
522 sumWithOverflow(length, adapter4.length(), overflow); | |
523 if (overflow) | |
524 return 0; | |
525 | |
526 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.
is8Bit()) { | |
527 LChar* buffer; | |
528 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
529 if (!resultImpl) | |
530 return 0; | |
531 | |
532 LChar* result = buffer; | |
533 adapter1.writeTo(result); | |
534 result += adapter1.length(); | |
535 adapter2.writeTo(result); | |
536 result += adapter2.length(); | |
537 adapter3.writeTo(result); | |
538 result += adapter3.length(); | |
539 adapter4.writeTo(result); | |
540 | |
541 return resultImpl.release(); | |
542 } | |
543 | |
544 UChar* buffer; | |
545 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
546 if (!resultImpl) | |
547 return 0; | |
548 | |
549 UChar* result = buffer; | |
550 adapter1.writeTo(result); | |
551 result += adapter1.length(); | |
552 adapter2.writeTo(result); | |
553 result += adapter2.length(); | |
554 adapter3.writeTo(result); | |
555 result += adapter3.length(); | |
556 adapter4.writeTo(result); | |
557 | |
558 return resultImpl.release(); | |
559 } | |
560 | |
561 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5> | |
562 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3, StringType4 string4, StringType5 string5) | |
563 { | |
564 StringTypeAdapter<StringType1> adapter1(string1); | |
565 StringTypeAdapter<StringType2> adapter2(string2); | |
566 StringTypeAdapter<StringType3> adapter3(string3); | |
567 StringTypeAdapter<StringType4> adapter4(string4); | |
568 StringTypeAdapter<StringType5> adapter5(string5); | |
569 | |
570 bool overflow = false; | |
571 unsigned length = adapter1.length(); | |
572 sumWithOverflow(length, adapter2.length(), overflow); | |
573 sumWithOverflow(length, adapter3.length(), overflow); | |
574 sumWithOverflow(length, adapter4.length(), overflow); | |
575 sumWithOverflow(length, adapter5.length(), overflow); | |
576 if (overflow) | |
577 return 0; | |
578 | |
579 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.
is8Bit() && adapter5.is8Bit()) { | |
580 LChar* buffer; | |
581 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
582 if (!resultImpl) | |
583 return 0; | |
584 | |
585 LChar* result = buffer; | |
586 adapter1.writeTo(result); | |
587 result += adapter1.length(); | |
588 adapter2.writeTo(result); | |
589 result += adapter2.length(); | |
590 adapter3.writeTo(result); | |
591 result += adapter3.length(); | |
592 adapter4.writeTo(result); | |
593 result += adapter4.length(); | |
594 adapter5.writeTo(result); | |
595 | |
596 return resultImpl.release(); | |
597 } | |
598 | |
599 UChar* buffer; | |
600 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
601 if (!resultImpl) | |
602 return 0; | |
603 | |
604 UChar* result = buffer; | |
605 adapter1.writeTo(result); | |
606 result += adapter1.length(); | |
607 adapter2.writeTo(result); | |
608 result += adapter2.length(); | |
609 adapter3.writeTo(result); | |
610 result += adapter3.length(); | |
611 adapter4.writeTo(result); | |
612 result += adapter4.length(); | |
613 adapter5.writeTo(result); | |
614 | |
615 return resultImpl.release(); | |
616 } | |
617 | |
618 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6> | |
619 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3, StringType4 string4, StringType5 string5, StringType6 string
6) | |
620 { | |
621 StringTypeAdapter<StringType1> adapter1(string1); | |
622 StringTypeAdapter<StringType2> adapter2(string2); | |
623 StringTypeAdapter<StringType3> adapter3(string3); | |
624 StringTypeAdapter<StringType4> adapter4(string4); | |
625 StringTypeAdapter<StringType5> adapter5(string5); | |
626 StringTypeAdapter<StringType6> adapter6(string6); | |
627 | |
628 bool overflow = false; | |
629 unsigned length = adapter1.length(); | |
630 sumWithOverflow(length, adapter2.length(), overflow); | |
631 sumWithOverflow(length, adapter3.length(), overflow); | |
632 sumWithOverflow(length, adapter4.length(), overflow); | |
633 sumWithOverflow(length, adapter5.length(), overflow); | |
634 sumWithOverflow(length, adapter6.length(), overflow); | |
635 if (overflow) | |
636 return 0; | |
637 | |
638 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.
is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) { | |
639 LChar* buffer; | |
640 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
641 if (!resultImpl) | |
642 return 0; | |
643 | |
644 LChar* result = buffer; | |
645 adapter1.writeTo(result); | |
646 result += adapter1.length(); | |
647 adapter2.writeTo(result); | |
648 result += adapter2.length(); | |
649 adapter3.writeTo(result); | |
650 result += adapter3.length(); | |
651 adapter4.writeTo(result); | |
652 result += adapter4.length(); | |
653 adapter5.writeTo(result); | |
654 result += adapter5.length(); | |
655 adapter6.writeTo(result); | |
656 | |
657 return resultImpl.release(); | |
658 } | |
659 | |
660 UChar* buffer; | |
661 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
662 if (!resultImpl) | |
663 return 0; | |
664 | |
665 UChar* result = buffer; | |
666 adapter1.writeTo(result); | |
667 result += adapter1.length(); | |
668 adapter2.writeTo(result); | |
669 result += adapter2.length(); | |
670 adapter3.writeTo(result); | |
671 result += adapter3.length(); | |
672 adapter4.writeTo(result); | |
673 result += adapter4.length(); | |
674 adapter5.writeTo(result); | |
675 result += adapter5.length(); | |
676 adapter6.writeTo(result); | |
677 | |
678 return resultImpl.release(); | |
679 } | |
680 | |
681 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6, typename StringType
7> | |
682 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3, StringType4 string4, StringType5 string5, StringType6 string
6, StringType7 string7) | |
683 { | |
684 StringTypeAdapter<StringType1> adapter1(string1); | |
685 StringTypeAdapter<StringType2> adapter2(string2); | |
686 StringTypeAdapter<StringType3> adapter3(string3); | |
687 StringTypeAdapter<StringType4> adapter4(string4); | |
688 StringTypeAdapter<StringType5> adapter5(string5); | |
689 StringTypeAdapter<StringType6> adapter6(string6); | |
690 StringTypeAdapter<StringType7> adapter7(string7); | |
691 | |
692 bool overflow = false; | |
693 unsigned length = adapter1.length(); | |
694 sumWithOverflow(length, adapter2.length(), overflow); | |
695 sumWithOverflow(length, adapter3.length(), overflow); | |
696 sumWithOverflow(length, adapter4.length(), overflow); | |
697 sumWithOverflow(length, adapter5.length(), overflow); | |
698 sumWithOverflow(length, adapter6.length(), overflow); | |
699 sumWithOverflow(length, adapter7.length(), overflow); | |
700 if (overflow) | |
701 return 0; | |
702 | |
703 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.
is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) { | |
704 LChar* buffer; | |
705 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
706 if (!resultImpl) | |
707 return 0; | |
708 | |
709 LChar* result = buffer; | |
710 adapter1.writeTo(result); | |
711 result += adapter1.length(); | |
712 adapter2.writeTo(result); | |
713 result += adapter2.length(); | |
714 adapter3.writeTo(result); | |
715 result += adapter3.length(); | |
716 adapter4.writeTo(result); | |
717 result += adapter4.length(); | |
718 adapter5.writeTo(result); | |
719 result += adapter5.length(); | |
720 adapter6.writeTo(result); | |
721 result += adapter6.length(); | |
722 adapter7.writeTo(result); | |
723 | |
724 return resultImpl.release(); | |
725 } | |
726 | |
727 UChar* buffer; | |
728 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
729 if (!resultImpl) | |
730 return 0; | |
731 | |
732 UChar* result = buffer; | |
733 adapter1.writeTo(result); | |
734 result += adapter1.length(); | |
735 adapter2.writeTo(result); | |
736 result += adapter2.length(); | |
737 adapter3.writeTo(result); | |
738 result += adapter3.length(); | |
739 adapter4.writeTo(result); | |
740 result += adapter4.length(); | |
741 adapter5.writeTo(result); | |
742 result += adapter5.length(); | |
743 adapter6.writeTo(result); | |
744 result += adapter6.length(); | |
745 adapter7.writeTo(result); | |
746 | |
747 return resultImpl.release(); | |
748 } | |
749 | |
750 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6, typename StringType
7, typename StringType8> | |
751 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3, StringType4 string4, StringType5 string5, StringType6 string
6, StringType7 string7, StringType8 string8) | |
752 { | |
753 StringTypeAdapter<StringType1> adapter1(string1); | |
754 StringTypeAdapter<StringType2> adapter2(string2); | |
755 StringTypeAdapter<StringType3> adapter3(string3); | |
756 StringTypeAdapter<StringType4> adapter4(string4); | |
757 StringTypeAdapter<StringType5> adapter5(string5); | |
758 StringTypeAdapter<StringType6> adapter6(string6); | |
759 StringTypeAdapter<StringType7> adapter7(string7); | |
760 StringTypeAdapter<StringType8> adapter8(string8); | |
761 | |
762 bool overflow = false; | |
763 unsigned length = adapter1.length(); | |
764 sumWithOverflow(length, adapter2.length(), overflow); | |
765 sumWithOverflow(length, adapter3.length(), overflow); | |
766 sumWithOverflow(length, adapter4.length(), overflow); | |
767 sumWithOverflow(length, adapter5.length(), overflow); | |
768 sumWithOverflow(length, adapter6.length(), overflow); | |
769 sumWithOverflow(length, adapter7.length(), overflow); | |
770 sumWithOverflow(length, adapter8.length(), overflow); | |
771 if (overflow) | |
772 return 0; | |
773 | |
774 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.
is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapt
er8.is8Bit()) { | |
775 LChar* buffer; | |
776 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
777 if (!resultImpl) | |
778 return 0; | |
779 | |
780 LChar* result = buffer; | |
781 adapter1.writeTo(result); | |
782 result += adapter1.length(); | |
783 adapter2.writeTo(result); | |
784 result += adapter2.length(); | |
785 adapter3.writeTo(result); | |
786 result += adapter3.length(); | |
787 adapter4.writeTo(result); | |
788 result += adapter4.length(); | |
789 adapter5.writeTo(result); | |
790 result += adapter5.length(); | |
791 adapter6.writeTo(result); | |
792 result += adapter6.length(); | |
793 adapter7.writeTo(result); | |
794 result += adapter7.length(); | |
795 adapter8.writeTo(result); | |
796 | |
797 return resultImpl.release(); | |
798 } | |
799 | |
800 UChar* buffer; | |
801 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
802 if (!resultImpl) | |
803 return 0; | |
804 | |
805 UChar* result = buffer; | |
806 adapter1.writeTo(result); | |
807 result += adapter1.length(); | |
808 adapter2.writeTo(result); | |
809 result += adapter2.length(); | |
810 adapter3.writeTo(result); | |
811 result += adapter3.length(); | |
812 adapter4.writeTo(result); | |
813 result += adapter4.length(); | |
814 adapter5.writeTo(result); | |
815 result += adapter5.length(); | |
816 adapter6.writeTo(result); | |
817 result += adapter6.length(); | |
818 adapter7.writeTo(result); | |
819 result += adapter7.length(); | |
820 adapter8.writeTo(result); | |
821 | |
822 return resultImpl.release(); | |
823 } | |
824 | |
825 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6, typename StringType
7, typename StringType8, typename StringType9> | |
826 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, S
tringType3 string3, StringType4 string4, StringType5 string5, StringType6 string
6, StringType7 string7, StringType8 string8, StringType9 string9) | |
827 { | |
828 StringTypeAdapter<StringType1> adapter1(string1); | |
829 StringTypeAdapter<StringType2> adapter2(string2); | |
830 StringTypeAdapter<StringType3> adapter3(string3); | |
831 StringTypeAdapter<StringType4> adapter4(string4); | |
832 StringTypeAdapter<StringType5> adapter5(string5); | |
833 StringTypeAdapter<StringType6> adapter6(string6); | |
834 StringTypeAdapter<StringType7> adapter7(string7); | |
835 StringTypeAdapter<StringType8> adapter8(string8); | |
836 StringTypeAdapter<StringType9> adapter9(string9); | |
837 | |
838 bool overflow = false; | |
839 unsigned length = adapter1.length(); | |
840 sumWithOverflow(length, adapter2.length(), overflow); | |
841 sumWithOverflow(length, adapter3.length(), overflow); | |
842 sumWithOverflow(length, adapter4.length(), overflow); | |
843 sumWithOverflow(length, adapter5.length(), overflow); | |
844 sumWithOverflow(length, adapter6.length(), overflow); | |
845 sumWithOverflow(length, adapter7.length(), overflow); | |
846 sumWithOverflow(length, adapter8.length(), overflow); | |
847 sumWithOverflow(length, adapter9.length(), overflow); | |
848 if (overflow) | |
849 return 0; | |
850 | |
851 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.
is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapt
er8.is8Bit() && adapter9.is8Bit()) { | |
852 LChar* buffer; | |
853 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(lengt
h, buffer); | |
854 if (!resultImpl) | |
855 return 0; | |
856 | |
857 LChar* result = buffer; | |
858 adapter1.writeTo(result); | |
859 result += adapter1.length(); | |
860 adapter2.writeTo(result); | |
861 result += adapter2.length(); | |
862 adapter3.writeTo(result); | |
863 result += adapter3.length(); | |
864 adapter4.writeTo(result); | |
865 result += adapter4.length(); | |
866 adapter5.writeTo(result); | |
867 result += adapter5.length(); | |
868 adapter6.writeTo(result); | |
869 result += adapter6.length(); | |
870 adapter7.writeTo(result); | |
871 result += adapter7.length(); | |
872 adapter8.writeTo(result); | |
873 result += adapter8.length(); | |
874 adapter9.writeTo(result); | |
875 | |
876 return resultImpl.release(); | |
877 } | |
878 | |
879 UChar* buffer; | |
880 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, b
uffer); | |
881 if (!resultImpl) | |
882 return 0; | |
883 | |
884 UChar* result = buffer; | |
885 adapter1.writeTo(result); | |
886 result += adapter1.length(); | |
887 adapter2.writeTo(result); | |
888 result += adapter2.length(); | |
889 adapter3.writeTo(result); | |
890 result += adapter3.length(); | |
891 adapter4.writeTo(result); | |
892 result += adapter4.length(); | |
893 adapter5.writeTo(result); | |
894 result += adapter5.length(); | |
895 adapter6.writeTo(result); | |
896 result += adapter6.length(); | |
897 adapter7.writeTo(result); | |
898 result += adapter7.length(); | |
899 adapter8.writeTo(result); | |
900 result += adapter8.length(); | |
901 adapter9.writeTo(result); | |
902 | |
903 return resultImpl.release(); | |
904 } | |
905 | |
906 | |
907 // Convenience only. | |
908 template<typename StringType1> | |
909 String makeString(StringType1 string1) | |
910 { | |
911 return String(string1); | |
912 } | |
913 | |
914 template<typename StringType1, typename StringType2> | |
915 String makeString(StringType1 string1, StringType2 string2) | |
916 { | |
917 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2); | |
918 RELEASE_ASSERT(resultImpl); | |
919 return resultImpl.release(); | |
920 } | |
921 | |
922 template<typename StringType1, typename StringType2, typename StringType3> | |
923 String makeString(StringType1 string1, StringType2 string2, StringType3 string3) | |
924 { | |
925 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3); | |
926 RELEASE_ASSERT(resultImpl); | |
927 return resultImpl.release(); | |
928 } | |
929 | |
930 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4> | |
931 String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
StringType4 string4) | |
932 { | |
933 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, str
ing4); | |
934 RELEASE_ASSERT(resultImpl); | |
935 return resultImpl.release(); | |
936 } | |
937 | |
938 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5> | |
939 String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
StringType4 string4, StringType5 string5) | |
940 { | |
941 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, str
ing4, string5); | |
942 RELEASE_ASSERT(resultImpl); | |
943 return resultImpl.release(); | |
944 } | |
945 | |
946 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6> | |
947 String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
StringType4 string4, StringType5 string5, StringType6 string6) | |
948 { | |
949 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, str
ing4, string5, string6); | |
950 RELEASE_ASSERT(resultImpl); | |
951 return resultImpl.release(); | |
952 } | |
953 | |
954 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6, typename StringType
7> | |
955 String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
StringType4 string4, StringType5 string5, StringType6 string6, StringType7 stri
ng7) | |
956 { | |
957 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, str
ing4, string5, string6, string7); | |
958 RELEASE_ASSERT(resultImpl); | |
959 return resultImpl.release(); | |
960 } | |
961 | |
962 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6, typename StringType
7, typename StringType8> | |
963 String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
StringType4 string4, StringType5 string5, StringType6 string6, StringType7 stri
ng7, StringType8 string8) | |
964 { | |
965 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, str
ing4, string5, string6, string7, string8); | |
966 RELEASE_ASSERT(resultImpl); | |
967 return resultImpl.release(); | |
968 } | |
969 | |
970 template<typename StringType1, typename StringType2, typename StringType3, typen
ame StringType4, typename StringType5, typename StringType6, typename StringType
7, typename StringType8, typename StringType9> | |
971 String makeString(StringType1 string1, StringType2 string2, StringType3 string3,
StringType4 string4, StringType5 string5, StringType6 string6, StringType7 stri
ng7, StringType8 string8, StringType9 string9) | |
972 { | |
973 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, str
ing4, string5, string6, string7, string8, string9); | |
974 RELEASE_ASSERT(resultImpl); | |
975 return resultImpl.release(); | |
976 } | |
977 | |
978 } // namespace WTF | |
979 | |
980 using WTF::makeString; | |
981 | |
982 #include <wtf/text/StringOperators.h> | |
983 #endif | |
OLD | NEW |