]> 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 49d4a6377735ec9a0bb06beb1c2588be2fec973b..34f43c4db21aa23ffe4a403731ea2973428ac055 100644 (file)
 
 #include "ExceptionHelpers.h"
 #include "JSString.h"
 
 #include "ExceptionHelpers.h"
 #include "JSString.h"
-#include "UStringConcatenate.h"
-#include "Vector.h"
+#include <wtf/Vector.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
+// FIXME: Should move the last few callers over from this to WTF::StringBuilder.
 class JSStringBuilder {
 public:
     JSStringBuilder()
         : m_okay(true)
 class JSStringBuilder {
 public:
     JSStringBuilder()
         : m_okay(true)
+        , m_is8Bit(true)
     {
     }
 
     {
     }
 
-    void append(const UChar u)
+    void append(LChar character)
     {
     {
-        m_okay &= buffer.tryAppend(&u, 1);
-    }
-
-    void append(const char* str)
-    {
-        append(str, strlen(str));
-    }
-
-    void append(const char* str, size_t len)
-    {
-        m_okay &= buffer.tryReserveCapacity(buffer.size() + len);
-        for (size_t i = 0; i < len; i++) {
-            UChar u = static_cast<unsigned char>(str[i]);
-            m_okay &= buffer.tryAppend(&u, 1);
+        if (m_is8Bit) {
+            m_okay &= buffer8.tryAppend(&character, 1);
+            return;
         }
         }
+        UChar upconvertedCharacter = character;
+        m_okay &= buffer16.tryAppend(&upconvertedCharacter, 1);
     }
 
     }
 
-    void append(const UChar* str, size_t len)
+    void append(UChar character)
     {
     {
-        m_okay &= buffer.tryAppend(str, len);
+        if (m_is8Bit) {
+            if (character < 0x100) {
+                LChar narrowedCharacter = character;
+                m_okay &= buffer8.tryAppend(&narrowedCharacter, 1);
+                return;
+            }
+            upConvert();
+        }
+        m_okay &= buffer16.tryAppend(&character, 1);
     }
 
     }
 
-    void append(const UString& str)
+    void append(const char* str)
     {
     {
-        m_okay &= buffer.tryAppend(str.characters(), str.length());
+        append(reinterpret_cast<const LChar*>(str), strlen(str));
     }
 
     JSValue build(ExecState* exec)
     {
         if (!m_okay)
             return throwOutOfMemoryError(exec);
     }
 
     JSValue build(ExecState* exec)
     {
         if (!m_okay)
             return throwOutOfMemoryError(exec);
-        buffer.shrinkToFit();
-        if (!buffer.data())
+        if (m_is8Bit) {
+            buffer8.shrinkToFit();
+            if (!buffer8.data())
+                return throwOutOfMemoryError(exec);
+            return jsString(exec, String::adopt(buffer8));
+        }
+        buffer16.shrinkToFit();
+        if (!buffer16.data())
             return throwOutOfMemoryError(exec);
             return throwOutOfMemoryError(exec);
-        return jsString(exec, UString::adopt(buffer));
+        return jsString(exec, String::adopt(buffer16));
     }
 
     }
 
-protected:
-    Vector<UChar, 64> buffer;
-    bool m_okay;
-};
+private:
+    void append(const LChar* characters, size_t length)
+    {
+        if (m_is8Bit) {
+            m_okay &= buffer8.tryAppend(characters, length);
+            return;
+        }
+        // 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);
+        }
+    }
 
 
-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);
-}
+    void upConvert()
+    {
+        ASSERT(m_is8Bit);
+        size_t len = buffer8.size();
 
 
-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);
-}
+        for (size_t i = 0; i < len; i++)
+            buffer16.append(buffer8[i]);
 
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4);
-    if (!result)
-        return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
-}
+        buffer8.clear();
+        m_is8Bit = false;
+    }
+
+    Vector<LChar, 64, UnsafeVectorOverflow> buffer8;
+    Vector<UChar, 64, UnsafeVectorOverflow> buffer16;
+    bool m_okay;
+    bool m_is8Bit;
+};
 
 
-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)
+template<typename StringType>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType&& string)
 {
 {
-    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);
     if (!result)
         return throwOutOfMemoryError(exec);
-    return jsNontrivialString(exec, result);
+    return jsNontrivialString(exec, result.release());
 }
 
 }
 }
 
 }