]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSStringBuilder.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / JSStringBuilder.h
index 1a2b812f0f2ad208576c0c98caa72c6a27a5b2a4..34f43c4db21aa23ffe4a403731ea2973428ac055 100644 (file)
 
 #include "ExceptionHelpers.h"
 #include "JSString.h"
-#include "UStringConcatenate.h"
 #include <wtf/Vector.h>
 
 namespace JSC {
 
+// FIXME: Should move the last few callers over from this to WTF::StringBuilder.
 class JSStringBuilder {
 public:
     JSStringBuilder()
@@ -41,73 +41,64 @@ public:
     {
     }
 
-    void append(const UChar u)
+    void append(LChar character)
     {
         if (m_is8Bit) {
-            if (u < 0xff) {
-                LChar c = u;
-                m_okay &= buffer8.tryAppend(&c, 1);
+            m_okay &= buffer8.tryAppend(&character, 1);
+            return;
+        }
+        UChar upconvertedCharacter = character;
+        m_okay &= buffer16.tryAppend(&upconvertedCharacter, 1);
+    }
+
+    void append(UChar character)
+    {
+        if (m_is8Bit) {
+            if (character < 0x100) {
+                LChar narrowedCharacter = character;
+                m_okay &= buffer8.tryAppend(&narrowedCharacter, 1);
                 return;
             }
             upConvert();
         }
-        m_okay &= buffer16.tryAppend(&u, 1);
+        m_okay &= buffer16.tryAppend(&character, 1);
     }
 
     void append(const char* str)
     {
-        append(str, strlen(str));
+        append(reinterpret_cast<const LChar*>(str), strlen(str));
     }
 
-    void append(const char* str, size_t len)
+    JSValue build(ExecState* exec)
     {
+        if (!m_okay)
+            return throwOutOfMemoryError(exec);
         if (m_is8Bit) {
-            m_okay &= buffer8.tryAppend(reinterpret_cast<const LChar*>(str), len);
-            return;
-        }
-        m_okay &= buffer8.tryReserveCapacity(buffer16.size() + len);
-        for (size_t i = 0; i < len; i++) {
-            UChar u = static_cast<unsigned char>(str[i]);
-            m_okay &= buffer16.tryAppend(&u, 1);
+            buffer8.shrinkToFit();
+            if (!buffer8.data())
+                return throwOutOfMemoryError(exec);
+            return jsString(exec, String::adopt(buffer8));
         }
+        buffer16.shrinkToFit();
+        if (!buffer16.data())
+            return throwOutOfMemoryError(exec);
+        return jsString(exec, String::adopt(buffer16));
     }
 
-    void append(const LChar* str, size_t len)
+private:
+    void append(const LChar* characters, size_t length)
     {
         if (m_is8Bit) {
-            m_okay &= buffer8.tryAppend(str, len);
+            m_okay &= buffer8.tryAppend(characters, length);
             return;
         }
-        m_okay &= buffer8.tryReserveCapacity(buffer16.size() + len);
-        for (size_t i = 0; i < len; i++) {
-            UChar u = str[i];
-            m_okay &= buffer16.tryAppend(&u, 1);
+        // FIXME: There must be a more efficient way of doing this.
+        m_okay &= buffer16.tryReserveCapacity(buffer16.size() + length);
+        for (size_t i = 0; i < length; i++) {
+            UChar upconvertedCharacter = characters[i];
+            m_okay &= buffer16.tryAppend(&upconvertedCharacter, 1);
         }
     }
-    
-    void append(const UChar* str, size_t len)
-    {
-        if (m_is8Bit)
-            upConvert(); // FIXME: We could check character by character its size.
-        m_okay &= buffer16.tryAppend(str, len);
-    }
-
-    void append(const UString& str)
-    {
-        unsigned length = str.length();
-
-        if (!length)
-            return;
-
-        if (m_is8Bit) {
-            if (str.is8Bit()) {
-                m_okay &= buffer8.tryAppend(str.characters8(), length);
-                return;
-            }
-            upConvert();
-        }
-        m_okay &= buffer16.tryAppend(str.characters(), length);
-    }
 
     void upConvert()
     {
@@ -121,72 +112,25 @@ public:
         m_is8Bit = false;
     }
 
-    JSValue build(ExecState* exec)
-    {
-        if (!m_okay)
-            return throwOutOfMemoryError(exec);
-        if (m_is8Bit) {
-            buffer8.shrinkToFit();
-            if (!buffer8.data())
-                return throwOutOfMemoryError(exec);
-            return jsString(exec, UString::adopt(buffer8));
-        }
-        buffer16.shrinkToFit();
-        if (!buffer16.data())
-            return throwOutOfMemoryError(exec);
-        return jsString(exec, UString::adopt(buffer16));
-    }
-
-protected:
-    Vector<LChar, 64> buffer8;
-    Vector<UChar, 64> buffer16;
+    Vector<LChar, 64, UnsafeVectorOverflow> buffer8;
+    Vector<UChar, 64, UnsafeVectorOverflow> buffer16;
     bool m_okay;
     bool m_is8Bit;
 };
 
-template<typename StringType1, typename StringType2>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+template<typename StringType>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType&& string)
 {
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
+    return jsNontrivialString(exec, std::forward<StringType>(string));
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+template<typename StringType, typename... StringTypes>
+inline JSValue jsMakeNontrivialString(ExecState* exec, const StringType& string, const StringTypes&... strings)
 {
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6);
+    RefPtr<StringImpl> result = WTF::tryMakeString(string, strings...);
     if (!result)
         return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
+    return jsNontrivialString(exec, result.release());
 }
 
 }