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