18a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block/*
28a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * Copyright (C) 2009 Apple Inc. All rights reserved.
38a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *
48a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * Redistribution and use in source and binary forms, with or without
58a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * modification, are permitted provided that the following conditions
68a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * are met:
78a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * 1. Redistributions of source code must retain the above copyright
88a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *    notice, this list of conditions and the following disclaimer.
98a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * 2. Redistributions in binary form must reproduce the above copyright
108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *    notice, this list of conditions and the following disclaimer in the
118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *    documentation and/or other materials provided with the distribution.
128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *
138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block */
258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#ifndef JSStringBuilder_h
278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#define JSStringBuilder_h
288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "ExceptionHelpers.h"
308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "JSString.h"
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "UStringConcatenate.h"
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Vector.h"
338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocknamespace JSC {
358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass JSStringBuilder {
378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockpublic:
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringBuilder()
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : m_okay(true)
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(const UChar u)
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_okay &= buffer.tryAppend(&u, 1);
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(const char* str)
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        append(str, strlen(str));
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(const char* str, size_t len)
54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_okay &= buffer.tryReserveCapacity(buffer.size() + len);
56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (size_t i = 0; i < len; i++) {
57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            UChar u = static_cast<unsigned char>(str[i]);
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_okay &= buffer.tryAppend(&u, 1);
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(const UChar* str, size_t len)
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_okay &= buffer.tryAppend(str, len);
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void append(const UString& str)
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
69f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_okay &= buffer.tryAppend(str.characters(), str.length());
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    JSValue build(ExecState* exec)
738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!m_okay)
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return throwOutOfMemoryError(exec);
768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        buffer.shrinkToFit();
778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (!buffer.data())
788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return throwOutOfMemoryError(exec);
798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return jsString(exec, UString::adopt(buffer));
808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    }
818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockprotected:
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Vector<UChar, 64> buffer;
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool m_okay;
858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block};
868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocktemplate<typename StringType1, typename StringType2>
888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockinline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2);
918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!result)
928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return throwOutOfMemoryError(exec);
938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return jsNontrivialString(exec, result);
948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocktemplate<typename StringType1, typename StringType2, typename StringType3>
978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockinline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3);
1008a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!result)
1018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return throwOutOfMemoryError(exec);
1028a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return jsNontrivialString(exec, result);
1038a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocktemplate<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
1068a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockinline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
1078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4);
1098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!result)
1108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return throwOutOfMemoryError(exec);
1118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return jsNontrivialString(exec, result);
1128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocktemplate<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
1158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockinline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
1168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5);
1188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!result)
1198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return throwOutOfMemoryError(exec);
1208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return jsNontrivialString(exec, result);
1218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocktemplate<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
1248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockinline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
1258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6);
1278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!result)
1288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return throwOutOfMemoryError(exec);
1298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return jsNontrivialString(exec, result);
1308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#endif
135