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 <wtf/text/WTFString.h>
30
31 namespace WTF {
32
33 template<typename StringType>
34 class StringTypeAdapter {
35 };
36
37 template<>
38 class StringTypeAdapter<char> {
39 public:
40 StringTypeAdapter<char>(char buffer)
m_buffer(buffer)41 : m_buffer(buffer)
42 {
43 }
44
length()45 unsigned length() { return 1; }
writeTo(UChar * destination)46 void writeTo(UChar* destination) { *destination = m_buffer; }
47
48 private:
49 unsigned char m_buffer;
50 };
51
52 template<>
53 class StringTypeAdapter<UChar> {
54 public:
55 StringTypeAdapter<UChar>(UChar buffer)
m_buffer(buffer)56 : m_buffer(buffer)
57 {
58 }
59
length()60 unsigned length() { return 1; }
writeTo(UChar * destination)61 void writeTo(UChar* destination) { *destination = m_buffer; }
62
63 private:
64 UChar m_buffer;
65 };
66
67 template<>
68 class StringTypeAdapter<char*> {
69 public:
70 StringTypeAdapter<char*>(char* buffer)
m_buffer(buffer)71 : m_buffer(buffer)
72 , m_length(strlen(buffer))
73 {
74 }
75
length()76 unsigned length() { return m_length; }
77
writeTo(UChar * destination)78 void writeTo(UChar* destination)
79 {
80 for (unsigned i = 0; i < m_length; ++i) {
81 unsigned char c = m_buffer[i];
82 destination[i] = c;
83 }
84 }
85
86 private:
87 const char* m_buffer;
88 unsigned m_length;
89 };
90
91 template<>
92 class StringTypeAdapter<const UChar*> {
93 public:
94 StringTypeAdapter<const UChar*>(const UChar* buffer)
m_buffer(buffer)95 : m_buffer(buffer)
96 {
97 size_t len = 0;
98 while (m_buffer[len] != UChar(0))
99 len++;
100
101 if (len > std::numeric_limits<unsigned>::max())
102 CRASH();
103
104 m_length = len;
105 }
106
length()107 unsigned length() { return m_length; }
108
writeTo(UChar * destination)109 void writeTo(UChar* destination)
110 {
111 memcpy(destination, m_buffer, static_cast<size_t>(m_length) * sizeof(UChar));
112 }
113
114 private:
115 const UChar* m_buffer;
116 unsigned m_length;
117 };
118
119 template<>
120 class StringTypeAdapter<const char*> {
121 public:
122 StringTypeAdapter<const char*>(const char* buffer)
m_buffer(buffer)123 : m_buffer(buffer)
124 , m_length(strlen(buffer))
125 {
126 }
127
length()128 unsigned length() { return m_length; }
129
writeTo(UChar * destination)130 void writeTo(UChar* destination)
131 {
132 for (unsigned i = 0; i < m_length; ++i) {
133 unsigned char c = m_buffer[i];
134 destination[i] = c;
135 }
136 }
137
138 private:
139 const char* m_buffer;
140 unsigned m_length;
141 };
142
143 template<>
144 class StringTypeAdapter<Vector<char> > {
145 public:
146 StringTypeAdapter<Vector<char> >(const Vector<char>& buffer)
m_buffer(buffer)147 : m_buffer(buffer)
148 {
149 }
150
length()151 size_t length() { return m_buffer.size(); }
152
writeTo(UChar * destination)153 void writeTo(UChar* destination)
154 {
155 for (size_t i = 0; i < m_buffer.size(); ++i) {
156 unsigned char c = m_buffer[i];
157 destination[i] = c;
158 }
159 }
160
161 private:
162 const Vector<char>& m_buffer;
163 };
164
165 template<>
166 class StringTypeAdapter<String> {
167 public:
168 StringTypeAdapter<String>(const String& string)
m_buffer(string)169 : m_buffer(string)
170 {
171 }
172
length()173 unsigned length() { return m_buffer.length(); }
174
writeTo(UChar * destination)175 void writeTo(UChar* destination)
176 {
177 const UChar* data = m_buffer.characters();
178 unsigned length = m_buffer.length();
179 for (unsigned i = 0; i < length; ++i)
180 destination[i] = data[i];
181 }
182
183 private:
184 const String& m_buffer;
185 };
186
sumWithOverflow(unsigned & total,unsigned addend,bool & overflow)187 inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
188 {
189 unsigned oldTotal = total;
190 total = oldTotal + addend;
191 if (total < oldTotal)
192 overflow = true;
193 }
194
195 template<typename StringType1, typename StringType2>
tryMakeString(StringType1 string1,StringType2 string2)196 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2)
197 {
198 StringTypeAdapter<StringType1> adapter1(string1);
199 StringTypeAdapter<StringType2> adapter2(string2);
200
201 UChar* buffer;
202 bool overflow = false;
203 unsigned length = adapter1.length();
204 sumWithOverflow(length, adapter2.length(), overflow);
205 if (overflow)
206 return 0;
207 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
208 if (!resultImpl)
209 return 0;
210
211 UChar* result = buffer;
212 adapter1.writeTo(result);
213 result += adapter1.length();
214 adapter2.writeTo(result);
215
216 return resultImpl.release();
217 }
218
219 template<typename StringType1, typename StringType2, typename StringType3>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3)220 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
221 {
222 StringTypeAdapter<StringType1> adapter1(string1);
223 StringTypeAdapter<StringType2> adapter2(string2);
224 StringTypeAdapter<StringType3> adapter3(string3);
225
226 UChar* buffer = 0;
227 bool overflow = false;
228 unsigned length = adapter1.length();
229 sumWithOverflow(length, adapter2.length(), overflow);
230 sumWithOverflow(length, adapter3.length(), overflow);
231 if (overflow)
232 return 0;
233 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
234 if (!resultImpl)
235 return 0;
236
237 UChar* result = buffer;
238 adapter1.writeTo(result);
239 result += adapter1.length();
240 adapter2.writeTo(result);
241 result += adapter2.length();
242 adapter3.writeTo(result);
243
244 return resultImpl.release();
245 }
246
247 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4)248 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
249 {
250 StringTypeAdapter<StringType1> adapter1(string1);
251 StringTypeAdapter<StringType2> adapter2(string2);
252 StringTypeAdapter<StringType3> adapter3(string3);
253 StringTypeAdapter<StringType4> adapter4(string4);
254
255 UChar* buffer;
256 bool overflow = false;
257 unsigned length = adapter1.length();
258 sumWithOverflow(length, adapter2.length(), overflow);
259 sumWithOverflow(length, adapter3.length(), overflow);
260 sumWithOverflow(length, adapter4.length(), overflow);
261 if (overflow)
262 return 0;
263 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
264 if (!resultImpl)
265 return 0;
266
267 UChar* result = buffer;
268 adapter1.writeTo(result);
269 result += adapter1.length();
270 adapter2.writeTo(result);
271 result += adapter2.length();
272 adapter3.writeTo(result);
273 result += adapter3.length();
274 adapter4.writeTo(result);
275
276 return resultImpl.release();
277 }
278
279 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5)280 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
281 {
282 StringTypeAdapter<StringType1> adapter1(string1);
283 StringTypeAdapter<StringType2> adapter2(string2);
284 StringTypeAdapter<StringType3> adapter3(string3);
285 StringTypeAdapter<StringType4> adapter4(string4);
286 StringTypeAdapter<StringType5> adapter5(string5);
287
288 UChar* buffer;
289 bool overflow = false;
290 unsigned length = adapter1.length();
291 sumWithOverflow(length, adapter2.length(), overflow);
292 sumWithOverflow(length, adapter3.length(), overflow);
293 sumWithOverflow(length, adapter4.length(), overflow);
294 sumWithOverflow(length, adapter5.length(), overflow);
295 if (overflow)
296 return 0;
297 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
298 if (!resultImpl)
299 return 0;
300
301 UChar* result = buffer;
302 adapter1.writeTo(result);
303 result += adapter1.length();
304 adapter2.writeTo(result);
305 result += adapter2.length();
306 adapter3.writeTo(result);
307 result += adapter3.length();
308 adapter4.writeTo(result);
309 result += adapter4.length();
310 adapter5.writeTo(result);
311
312 return resultImpl.release();
313 }
314
315 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6)316 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
317 {
318 StringTypeAdapter<StringType1> adapter1(string1);
319 StringTypeAdapter<StringType2> adapter2(string2);
320 StringTypeAdapter<StringType3> adapter3(string3);
321 StringTypeAdapter<StringType4> adapter4(string4);
322 StringTypeAdapter<StringType5> adapter5(string5);
323 StringTypeAdapter<StringType6> adapter6(string6);
324
325 UChar* buffer;
326 bool overflow = false;
327 unsigned length = adapter1.length();
328 sumWithOverflow(length, adapter2.length(), overflow);
329 sumWithOverflow(length, adapter3.length(), overflow);
330 sumWithOverflow(length, adapter4.length(), overflow);
331 sumWithOverflow(length, adapter5.length(), overflow);
332 sumWithOverflow(length, adapter6.length(), overflow);
333 if (overflow)
334 return 0;
335 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
336 if (!resultImpl)
337 return 0;
338
339 UChar* result = buffer;
340 adapter1.writeTo(result);
341 result += adapter1.length();
342 adapter2.writeTo(result);
343 result += adapter2.length();
344 adapter3.writeTo(result);
345 result += adapter3.length();
346 adapter4.writeTo(result);
347 result += adapter4.length();
348 adapter5.writeTo(result);
349 result += adapter5.length();
350 adapter6.writeTo(result);
351
352 return resultImpl.release();
353 }
354
355 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6,StringType7 string7)356 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
357 {
358 StringTypeAdapter<StringType1> adapter1(string1);
359 StringTypeAdapter<StringType2> adapter2(string2);
360 StringTypeAdapter<StringType3> adapter3(string3);
361 StringTypeAdapter<StringType4> adapter4(string4);
362 StringTypeAdapter<StringType5> adapter5(string5);
363 StringTypeAdapter<StringType6> adapter6(string6);
364 StringTypeAdapter<StringType7> adapter7(string7);
365
366 UChar* buffer;
367 bool overflow = false;
368 unsigned length = adapter1.length();
369 sumWithOverflow(length, adapter2.length(), overflow);
370 sumWithOverflow(length, adapter3.length(), overflow);
371 sumWithOverflow(length, adapter4.length(), overflow);
372 sumWithOverflow(length, adapter5.length(), overflow);
373 sumWithOverflow(length, adapter6.length(), overflow);
374 sumWithOverflow(length, adapter7.length(), overflow);
375 if (overflow)
376 return 0;
377 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
378 if (!resultImpl)
379 return 0;
380
381 UChar* result = buffer;
382 adapter1.writeTo(result);
383 result += adapter1.length();
384 adapter2.writeTo(result);
385 result += adapter2.length();
386 adapter3.writeTo(result);
387 result += adapter3.length();
388 adapter4.writeTo(result);
389 result += adapter4.length();
390 adapter5.writeTo(result);
391 result += adapter5.length();
392 adapter6.writeTo(result);
393 result += adapter6.length();
394 adapter7.writeTo(result);
395
396 return resultImpl.release();
397 }
398
399 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6,StringType7 string7,StringType8 string8)400 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
401 {
402 StringTypeAdapter<StringType1> adapter1(string1);
403 StringTypeAdapter<StringType2> adapter2(string2);
404 StringTypeAdapter<StringType3> adapter3(string3);
405 StringTypeAdapter<StringType4> adapter4(string4);
406 StringTypeAdapter<StringType5> adapter5(string5);
407 StringTypeAdapter<StringType6> adapter6(string6);
408 StringTypeAdapter<StringType7> adapter7(string7);
409 StringTypeAdapter<StringType8> adapter8(string8);
410
411 UChar* buffer;
412 bool overflow = false;
413 unsigned length = adapter1.length();
414 sumWithOverflow(length, adapter2.length(), overflow);
415 sumWithOverflow(length, adapter3.length(), overflow);
416 sumWithOverflow(length, adapter4.length(), overflow);
417 sumWithOverflow(length, adapter5.length(), overflow);
418 sumWithOverflow(length, adapter6.length(), overflow);
419 sumWithOverflow(length, adapter7.length(), overflow);
420 sumWithOverflow(length, adapter8.length(), overflow);
421 if (overflow)
422 return 0;
423 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
424 if (!resultImpl)
425 return 0;
426
427 UChar* result = buffer;
428 adapter1.writeTo(result);
429 result += adapter1.length();
430 adapter2.writeTo(result);
431 result += adapter2.length();
432 adapter3.writeTo(result);
433 result += adapter3.length();
434 adapter4.writeTo(result);
435 result += adapter4.length();
436 adapter5.writeTo(result);
437 result += adapter5.length();
438 adapter6.writeTo(result);
439 result += adapter6.length();
440 adapter7.writeTo(result);
441 result += adapter7.length();
442 adapter8.writeTo(result);
443
444 return resultImpl.release();
445 }
446
447 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
tryMakeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6,StringType7 string7,StringType8 string8,StringType9 string9)448 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
449 {
450 StringTypeAdapter<StringType1> adapter1(string1);
451 StringTypeAdapter<StringType2> adapter2(string2);
452 StringTypeAdapter<StringType3> adapter3(string3);
453 StringTypeAdapter<StringType4> adapter4(string4);
454 StringTypeAdapter<StringType5> adapter5(string5);
455 StringTypeAdapter<StringType6> adapter6(string6);
456 StringTypeAdapter<StringType7> adapter7(string7);
457 StringTypeAdapter<StringType8> adapter8(string8);
458 StringTypeAdapter<StringType9> adapter9(string9);
459
460 UChar* buffer;
461 bool overflow = false;
462 unsigned length = adapter1.length();
463 sumWithOverflow(length, adapter2.length(), overflow);
464 sumWithOverflow(length, adapter3.length(), overflow);
465 sumWithOverflow(length, adapter4.length(), overflow);
466 sumWithOverflow(length, adapter5.length(), overflow);
467 sumWithOverflow(length, adapter6.length(), overflow);
468 sumWithOverflow(length, adapter7.length(), overflow);
469 sumWithOverflow(length, adapter8.length(), overflow);
470 sumWithOverflow(length, adapter9.length(), overflow);
471 if (overflow)
472 return 0;
473 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
474 if (!resultImpl)
475 return 0;
476
477 UChar* result = buffer;
478 adapter1.writeTo(result);
479 result += adapter1.length();
480 adapter2.writeTo(result);
481 result += adapter2.length();
482 adapter3.writeTo(result);
483 result += adapter3.length();
484 adapter4.writeTo(result);
485 result += adapter4.length();
486 adapter5.writeTo(result);
487 result += adapter5.length();
488 adapter6.writeTo(result);
489 result += adapter6.length();
490 adapter7.writeTo(result);
491 result += adapter7.length();
492 adapter8.writeTo(result);
493 result += adapter8.length();
494 adapter9.writeTo(result);
495
496 return resultImpl.release();
497 }
498
499
500 // Convenience only.
501 template<typename StringType1>
makeString(StringType1 string1)502 String makeString(StringType1 string1)
503 {
504 return String(string1);
505 }
506
507 template<typename StringType1, typename StringType2>
makeString(StringType1 string1,StringType2 string2)508 String makeString(StringType1 string1, StringType2 string2)
509 {
510 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2);
511 if (!resultImpl)
512 CRASH();
513 return resultImpl.release();
514 }
515
516 template<typename StringType1, typename StringType2, typename StringType3>
makeString(StringType1 string1,StringType2 string2,StringType3 string3)517 String makeString(StringType1 string1, StringType2 string2, StringType3 string3)
518 {
519 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3);
520 if (!resultImpl)
521 CRASH();
522 return resultImpl.release();
523 }
524
525 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
makeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4)526 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
527 {
528 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
529 if (!resultImpl)
530 CRASH();
531 return resultImpl.release();
532 }
533
534 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
makeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5)535 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
536 {
537 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
538 if (!resultImpl)
539 CRASH();
540 return resultImpl.release();
541 }
542
543 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
makeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6)544 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
545 {
546 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
547 if (!resultImpl)
548 CRASH();
549 return resultImpl.release();
550 }
551
552 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
makeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6,StringType7 string7)553 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
554 {
555 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
556 if (!resultImpl)
557 CRASH();
558 return resultImpl.release();
559 }
560
561 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
makeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6,StringType7 string7,StringType8 string8)562 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
563 {
564 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
565 if (!resultImpl)
566 CRASH();
567 return resultImpl.release();
568 }
569
570 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
makeString(StringType1 string1,StringType2 string2,StringType3 string3,StringType4 string4,StringType5 string5,StringType6 string6,StringType7 string7,StringType8 string8,StringType9 string9)571 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
572 {
573 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9);
574 if (!resultImpl)
575 CRASH();
576 return resultImpl.release();
577 }
578
579 } // namespace WTF
580
581 using WTF::makeString;
582
583 #endif
584