1 /* 2 * Copyright (C) 2009 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 JSStringBuilder_h 27 #define JSStringBuilder_h 28 29 #include "ExceptionHelpers.h" 30 #include "JSString.h" 31 #include "UStringConcatenate.h" 32 #include "Vector.h" 33 34 namespace JSC { 35 36 class JSStringBuilder { 37 public: 38 JSStringBuilder() 39 : m_okay(true) 40 { 41 } 42 43 void append(const UChar u) 44 { 45 m_okay &= buffer.tryAppend(&u, 1); 46 } 47 48 void append(const char* str) 49 { 50 append(str, strlen(str)); 51 } 52 53 void append(const char* str, size_t len) 54 { 55 m_okay &= buffer.tryReserveCapacity(buffer.size() + len); 56 for (size_t i = 0; i < len; i++) { 57 UChar u = static_cast<unsigned char>(str[i]); 58 m_okay &= buffer.tryAppend(&u, 1); 59 } 60 } 61 62 void append(const UChar* str, size_t len) 63 { 64 m_okay &= buffer.tryAppend(str, len); 65 } 66 67 void append(const UString& str) 68 { 69 m_okay &= buffer.tryAppend(str.characters(), str.length()); 70 } 71 72 JSValue build(ExecState* exec) 73 { 74 if (!m_okay) 75 return throwOutOfMemoryError(exec); 76 buffer.shrinkToFit(); 77 if (!buffer.data()) 78 return throwOutOfMemoryError(exec); 79 return jsString(exec, UString::adopt(buffer)); 80 } 81 82 protected: 83 Vector<UChar, 64> buffer; 84 bool m_okay; 85 }; 86 87 template<typename StringType1, typename StringType2> 88 inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2) 89 { 90 PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2); 91 if (!result) 92 return throwOutOfMemoryError(exec); 93 return jsNontrivialString(exec, result); 94 } 95 96 template<typename StringType1, typename StringType2, typename StringType3> 97 inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3) 98 { 99 PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3); 100 if (!result) 101 return throwOutOfMemoryError(exec); 102 return jsNontrivialString(exec, result); 103 } 104 105 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> 106 inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 107 { 108 PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4); 109 if (!result) 110 return throwOutOfMemoryError(exec); 111 return jsNontrivialString(exec, result); 112 } 113 114 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> 115 inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 116 { 117 PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5); 118 if (!result) 119 return throwOutOfMemoryError(exec); 120 return jsNontrivialString(exec, result); 121 } 122 123 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> 124 inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 125 { 126 PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6); 127 if (!result) 128 return throwOutOfMemoryError(exec); 129 return jsNontrivialString(exec, result); 130 } 131 132 } 133 134 #endif 135