[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

jianli at chromium.org jianli at chromium.org
Wed Dec 22 14:32:30 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit f54e3f0266a254c4af51a5df6ef719297056da64
Author: jianli at chromium.org <jianli at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Oct 12 22:15:54 2010 +0000

    Fix passing blob data with string data item between threads.
    https://bugs.webkit.org/show_bug.cgi?id=46543
    
    Reviewed by David Levin.
    
    The fix is to use a thread-safe ref-counted Vector<char> to store the
    string data. This also makes us be able to store any binary data in it.
    
    I've also fix BlobBuilder and BlobRegistryImpl to avoid some additional
    copies to make blob handling faster.
    
    * fileapi/BlobBuilder.cpp:
    (WebCore::BlobBuilder::append):
    * fileapi/ThreadableBlobRegistry.cpp:
    (WebCore::BlobRegistryContext::BlobRegistryContext):
    * platform/network/BlobData.cpp:
    (WebCore::BlobDataItem::RawData::RawData):
    (WebCore::BlobDataItem::RawData::detachFromCurrentThread):
    (WebCore::BlobDataItem::detachFromCurrentThread):
    (WebCore::BlobData::create):
    (WebCore::BlobData::detachFromCurrentThread):
    (WebCore::BlobData::appendData):
    * platform/network/BlobData.h:
    (WebCore::BlobDataItem::RawData::create):
    (WebCore::BlobDataItem::RawData::data):
    (WebCore::BlobDataItem::RawData::length):
    (WebCore::BlobDataItem::RawData::mutableData):
    (WebCore::BlobDataItem::BlobDataItem):
    * platform/network/BlobRegistryImpl.cpp:
    (WebCore::BlobRegistryImpl::registerBlobURL):
    * platform/network/BlobResourceHandle.cpp:
    (WebCore::BlobResourceHandle::readDataSync):
    (WebCore::BlobResourceHandle::readDataAsync):
    * platform/network/mac/FormDataStreamMac.mm:
    (WebCore::setHTTPBody):
    * platform/text/LineEnding.cpp:
    (OutputBuffer::CStringBuffer::CStringBuffer):
    (OutputBuffer::CStringBuffer::~CStringBuffer):
    (OutputBuffer::CStringBuffer::allocate):
    (OutputBuffer::CStringBuffer::copy):
    (OutputBuffer::CStringBuffer::buffer):
    (OutputBuffer::VectorCharAppendBuffer::VectorCharAppendBuffer):
    (OutputBuffer::VectorCharAppendBuffer::~VectorCharAppendBuffer):
    (OutputBuffer::VectorCharAppendBuffer::allocate):
    (OutputBuffer::VectorCharAppendBuffer::copy):
    (OutputBuffer::internalNormalizeLineEndingsToCRLF):
    (WebCore::normalizeToCROrLF):
    (WebCore::normalizeLineEndingsToCRLF):
    (WebCore::normalizeLineEndingsToCR):
    (WebCore::normalizeLineEndingsToLF):
    (WebCore::normalizeLineEndingsToNative):
    * platform/text/LineEnding.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@69610 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 0c6c5f3..6a59aaf 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,58 @@
+2010-10-12  Jian Li  <jianli at chromium.org>
+
+        Reviewed by David Levin.
+
+        Fix passing blob data with string data item between threads.
+        https://bugs.webkit.org/show_bug.cgi?id=46543
+
+        The fix is to use a thread-safe ref-counted Vector<char> to store the
+        string data. This also makes us be able to store any binary data in it.
+
+        I've also fix BlobBuilder and BlobRegistryImpl to avoid some additional
+        copies to make blob handling faster.
+
+        * fileapi/BlobBuilder.cpp:
+        (WebCore::BlobBuilder::append):
+        * fileapi/ThreadableBlobRegistry.cpp:
+        (WebCore::BlobRegistryContext::BlobRegistryContext):
+        * platform/network/BlobData.cpp:
+        (WebCore::BlobDataItem::RawData::RawData):
+        (WebCore::BlobDataItem::RawData::detachFromCurrentThread):
+        (WebCore::BlobDataItem::detachFromCurrentThread):
+        (WebCore::BlobData::create):
+        (WebCore::BlobData::detachFromCurrentThread):
+        (WebCore::BlobData::appendData):
+        * platform/network/BlobData.h:
+        (WebCore::BlobDataItem::RawData::create):
+        (WebCore::BlobDataItem::RawData::data):
+        (WebCore::BlobDataItem::RawData::length):
+        (WebCore::BlobDataItem::RawData::mutableData):
+        (WebCore::BlobDataItem::BlobDataItem):
+        * platform/network/BlobRegistryImpl.cpp:
+        (WebCore::BlobRegistryImpl::registerBlobURL):
+        * platform/network/BlobResourceHandle.cpp:
+        (WebCore::BlobResourceHandle::readDataSync):
+        (WebCore::BlobResourceHandle::readDataAsync):
+        * platform/network/mac/FormDataStreamMac.mm:
+        (WebCore::setHTTPBody):
+        * platform/text/LineEnding.cpp:
+        (OutputBuffer::CStringBuffer::CStringBuffer):
+        (OutputBuffer::CStringBuffer::~CStringBuffer):
+        (OutputBuffer::CStringBuffer::allocate):
+        (OutputBuffer::CStringBuffer::copy):
+        (OutputBuffer::CStringBuffer::buffer):
+        (OutputBuffer::VectorCharAppendBuffer::VectorCharAppendBuffer):
+        (OutputBuffer::VectorCharAppendBuffer::~VectorCharAppendBuffer):
+        (OutputBuffer::VectorCharAppendBuffer::allocate):
+        (OutputBuffer::VectorCharAppendBuffer::copy):
+        (OutputBuffer::internalNormalizeLineEndingsToCRLF):
+        (WebCore::normalizeToCROrLF):
+        (WebCore::normalizeLineEndingsToCRLF):
+        (WebCore::normalizeLineEndingsToCR):
+        (WebCore::normalizeLineEndingsToLF):
+        (WebCore::normalizeLineEndingsToNative):
+        * platform/text/LineEnding.h:
+
 2010-10-12  Sheriff Bot  <webkit.review.bot at gmail.com>
 
         Unreviewed, rolling out r69589.
diff --git a/WebCore/fileapi/BlobBuilder.cpp b/WebCore/fileapi/BlobBuilder.cpp
index 34864a5..a83726f 100644
--- a/WebCore/fileapi/BlobBuilder.cpp
+++ b/WebCore/fileapi/BlobBuilder.cpp
@@ -41,36 +41,6 @@
 
 namespace WebCore {
 
-static CString convertToCString(const String& text, const String& endingType, ExceptionCode& ec)
-{
-    DEFINE_STATIC_LOCAL(AtomicString, transparent, ("transparent"));
-    DEFINE_STATIC_LOCAL(AtomicString, native, ("native"));
-
-    ec = 0;
-
-    if (endingType.isEmpty() || endingType == transparent)
-        return UTF8Encoding().encode(text.characters(), text.length(), EntitiesForUnencodables);
-    if (endingType == native)
-        return normalizeLineEndingsToNative(UTF8Encoding().encode(text.characters(), text.length(), EntitiesForUnencodables));
-
-    ec = SYNTAX_ERR;
-    return CString();
-}
-
-static CString concatenateTwoCStrings(const CString& a, const CString& b)
-{
-    if (a.isNull() && b.isNull())
-        return CString();
-
-    char* q;
-    CString result = CString::newUninitialized(a.length() + b.length(), q);
-    if (a.length())
-        memcpy(q, a.data(), a.length());
-    if (b.length())
-        memcpy(q + a.length(), b.data(), b.length());
-    return result;
-}
-
 BlobBuilder::BlobBuilder()
     : m_size(0)
 {
@@ -78,17 +48,30 @@ BlobBuilder::BlobBuilder()
 
 bool BlobBuilder::append(const String& text, const String& endingType, ExceptionCode& ec)
 {
-    CString cstr = convertToCString(text, endingType, ec);
-    if (ec)
-        return false;
+    bool isEndingTypeTransparent = endingType == "transparent";
+    bool isEndingTypeNative = endingType == "native";
+    if (!endingType.isEmpty() && !isEndingTypeTransparent && !isEndingTypeNative) {
+        ec = SYNTAX_ERR;
+        return 0;
+    }
+
+    CString utf8Text = UTF8Encoding().encode(text.characters(), text.length(), EntitiesForUnencodables);
 
-    m_size += cstr.length();
+    // If the last item is not a data item, create one. Otherwise, we simply append the new string to the last data item.
+    if (m_items.isEmpty() || m_items[m_items.size() - 1].type != BlobDataItem::Data)
+        m_items.append(BlobDataItem(RawData::create()));
+
+    if (!utf8Text.isNull()) {
+        Vector<char>& buffer = *m_items[m_items.size() - 1].data->mutableData();
+        unsigned oldSize = buffer.size();
+
+        if (isEndingTypeNative)
+            normalizeLineEndingsToNative(utf8Text, buffer);
+        else
+            buffer.append(utf8Text.data(), utf8Text.length());
+        m_size += buffer.size() - oldSize;
+    }
 
-    // If the last item is a string, concatenate it with current string.
-    if (!m_items.isEmpty() && m_items[m_items.size() - 1].type == BlobDataItem::Data)
-        m_items[m_items.size() - 1].data = concatenateTwoCStrings(m_items[m_items.size() - 1].data, cstr);
-    else
-        m_items.append(BlobDataItem(cstr));
     return true;
 }
 
diff --git a/WebCore/fileapi/ThreadableBlobRegistry.cpp b/WebCore/fileapi/ThreadableBlobRegistry.cpp
index f74c680..2ec421b 100644
--- a/WebCore/fileapi/ThreadableBlobRegistry.cpp
+++ b/WebCore/fileapi/ThreadableBlobRegistry.cpp
@@ -41,8 +41,9 @@ namespace WebCore {
 struct BlobRegistryContext {
     BlobRegistryContext(const KURL& url, PassOwnPtr<BlobData> blobData)
         : url(url.copy())
-        , blobData(blobData->copy())
+        , blobData(blobData)
     {
+        this->blobData->detachFromCurrentThread();
     }
 
     BlobRegistryContext(const KURL& url, const KURL& srcURL)
diff --git a/WebCore/platform/network/BlobData.cpp b/WebCore/platform/network/BlobData.cpp
index 21e8917..ff39ecc 100644
--- a/WebCore/platform/network/BlobData.cpp
+++ b/WebCore/platform/network/BlobData.cpp
@@ -31,40 +31,46 @@
 #include "config.h"
 #include "BlobData.h"
 
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
 namespace WebCore {
 
 const long long BlobDataItem::toEndOfFile = -1;
 const double BlobDataItem::doNotCheckFileChange = 0;
 
-void BlobDataItem::copy(const BlobDataItem& item)
+RawData::RawData()
 {
-    type = item.type;
-    data = item.data; // This is OK because the underlying storage is Vector<char>.
-    path = item.path.crossThreadString();
-    url = item.url.copy();
-    offset = item.offset;
-    length = item.length;
-    expectedModificationTime = item.expectedModificationTime;
 }
 
-PassOwnPtr<BlobData> BlobData::copy() const
+void RawData::detachFromCurrentThread()
 {
-    OwnPtr<BlobData> blobData = adoptPtr(new BlobData());
-    blobData->m_contentType = m_contentType.crossThreadString();
-    blobData->m_contentDisposition = m_contentDisposition.crossThreadString();
-    blobData->m_items.resize(m_items.size());
-    for (size_t i = 0; i < m_items.size(); ++i)
-        blobData->m_items.at(i).copy(m_items.at(i));
+}
+
+void BlobDataItem::detachFromCurrentThread()
+{
+    data->detachFromCurrentThread();
+    path = path.crossThreadString();
+    url = url.copy();
+}
 
-    return blobData.release();
+PassOwnPtr<BlobData> BlobData::create()
+{
+    return adoptPtr(new BlobData());
 }
 
-void BlobData::appendData(const CString& data)
+void BlobData::detachFromCurrentThread()
 {
-    m_items.append(BlobDataItem(data));
+    m_contentType = m_contentType.crossThreadString();
+    m_contentDisposition = m_contentDisposition.crossThreadString();
+    for (size_t i = 0; i < m_items.size(); ++i)
+        m_items.at(i).detachFromCurrentThread();
 }
 
-void BlobData::appendData(const CString& data, long long offset, long long length)
+void BlobData::appendData(PassRefPtr<RawData> data, long long offset, long long length)
 {
     m_items.append(BlobDataItem(data, offset, length));
 }
diff --git a/WebCore/platform/network/BlobData.h b/WebCore/platform/network/BlobData.h
index 13e3b9c..1ff6344 100644
--- a/WebCore/platform/network/BlobData.h
+++ b/WebCore/platform/network/BlobData.h
@@ -33,12 +33,30 @@
 
 #include "KURL.h"
 #include "PlatformString.h"
-#include <wtf/PassOwnPtr.h>
-#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
+#include <wtf/Forward.h>
+#include <wtf/ThreadSafeShared.h>
 
 namespace WebCore {
 
+class RawData : public ThreadSafeShared<RawData> {
+public:
+    static PassRefPtr<RawData> create()
+    {
+        return adoptRef(new RawData());
+    }
+
+    void detachFromCurrentThread();
+
+    const char* data() const { return m_data.data(); }
+    size_t length() const { return m_data.size(); }
+    Vector<char>* mutableData() { return &m_data; }
+
+private:
+    RawData();
+
+    Vector<char> m_data;
+};
+
 struct BlobDataItem {
     static const long long toEndOfFile;
     static const double doNotCheckFileChange;
@@ -53,7 +71,7 @@ struct BlobDataItem {
     }
 
     // Constructor for String type (complete string).
-    explicit BlobDataItem(const CString& data)
+    explicit BlobDataItem(PassRefPtr<RawData> data)
         : type(Data)
         , data(data)
         , offset(0)
@@ -62,16 +80,6 @@ struct BlobDataItem {
     {
     }
 
-    // Constructor for String type (partial string).
-    BlobDataItem(const CString& data, long long offset, long long length)
-        : type(Data)
-        , data(data)
-        , offset(offset)
-        , length(length)
-        , expectedModificationTime(doNotCheckFileChange)
-    {
-    }
-
     // Constructor for File type (complete file).
     explicit BlobDataItem(const String& path)
         : type(File)
@@ -102,13 +110,13 @@ struct BlobDataItem {
     {
     }
 
-    // Gets a copy of the data suitable for passing to another thread.
-    void copy(const BlobDataItem&);
+    // Detaches from current thread so that it can be passed to another thread.
+    void detachFromCurrentThread();
 
     enum { Data, File, Blob } type;
     
     // For Data type.
-    CString data;
+    RefPtr<RawData> data;
 
     // For File type.
     String path;
@@ -119,19 +127,29 @@ struct BlobDataItem {
     long long offset;
     long long length;
     double expectedModificationTime;
+
+private:
+    friend class BlobData;
+
+    // Constructor for String type (partial string).
+    BlobDataItem(PassRefPtr<RawData> data, long long offset, long long length)
+        : type(Data)
+        , data(data)
+        , offset(offset)
+        , length(length)
+        , expectedModificationTime(doNotCheckFileChange)
+    {
+    }
 };
 
 typedef Vector<BlobDataItem> BlobDataItemList;
 
 class BlobData {
 public:
-    static PassOwnPtr<BlobData> create()
-    {
-        return adoptPtr(new BlobData());
-    }
+    static PassOwnPtr<BlobData> create();
 
-    // Gets a copy of the data suitable for passing to another thread.
-    PassOwnPtr<BlobData> copy() const;
+    // Detaches from current thread so that it can be passed to another thread.
+    void detachFromCurrentThread();
 
     const String& contentType() const { return m_contentType; }
     void setContentType(const String& contentType) { m_contentType = contentType; }
@@ -141,8 +159,8 @@ public:
 
     const BlobDataItemList& items() const { return m_items; }
     void swapItems(BlobDataItemList&);
-    
-    void appendData(const CString&);
+
+    void appendData(PassRefPtr<RawData>, long long offset, long long length);
     void appendFile(const String& path);
     void appendFile(const String& path, long long offset, long long length, double expectedModificationTime);
     void appendBlob(const KURL&, long long offset, long long length);
@@ -154,7 +172,7 @@ private:
     BlobData() { }
 
     // This is only exposed to BlobStorageData.
-    void appendData(const CString&, long long offset, long long length);
+    void appendData(const RawData&, long long offset, long long length);
 
     String m_contentType;
     String m_contentDisposition;
diff --git a/WebCore/platform/network/BlobRegistryImpl.cpp b/WebCore/platform/network/BlobRegistryImpl.cpp
index c5beb64..2c4e8fa 100644
--- a/WebCore/platform/network/BlobRegistryImpl.cpp
+++ b/WebCore/platform/network/BlobRegistryImpl.cpp
@@ -134,7 +134,7 @@ void BlobRegistryImpl::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blo
     for (BlobDataItemList::const_iterator iter = blobData->items().begin(); iter != blobData->items().end(); ++iter) {
         switch (iter->type) {
         case BlobDataItem::Data:
-            blobStorageData->m_data.appendData(iter->data, 0, iter->data.length());
+            blobStorageData->m_data.appendData(iter->data, 0, iter->data->length());
             break;
         case BlobDataItem::File:
             blobStorageData->m_data.appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime);
@@ -158,10 +158,7 @@ void BlobRegistryImpl::registerBlobURL(const KURL& url, const KURL& srcURL)
     if (!src)
         return;
 
-    RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create(src->contentType(), src->contentDisposition());
-    appendStorageItems(blobStorageData.get(), src->items());
-    
-    m_blobs.set(url.string(), blobStorageData);
+    m_blobs.set(url.string(), src);
 }
 
 void BlobRegistryImpl::unregisterBlobURL(const KURL& url)
diff --git a/WebCore/platform/network/BlobResourceHandle.cpp b/WebCore/platform/network/BlobResourceHandle.cpp
index 48ac2c0..753052a 100644
--- a/WebCore/platform/network/BlobResourceHandle.cpp
+++ b/WebCore/platform/network/BlobResourceHandle.cpp
@@ -359,7 +359,7 @@ int BlobResourceHandle::readDataSync(const BlobDataItem& item, char* buf, int le
     int bytesToRead = (length > remaining) ? static_cast<int>(remaining) : length;
     if (bytesToRead > m_totalRemainingSize)
         bytesToRead = static_cast<int>(m_totalRemainingSize);
-    memcpy(buf, item.data.data() + item.offset + m_currentItemReadSize, bytesToRead);
+    memcpy(buf, item.data->data() + item.offset + m_currentItemReadSize, bytesToRead);
     m_totalRemainingSize -= bytesToRead;
 
     m_currentItemReadSize += bytesToRead;
@@ -434,7 +434,7 @@ void BlobResourceHandle::readDataAsync(const BlobDataItem& item)
     long long bytesToRead = item.length - m_currentItemReadSize;
     if (bytesToRead > m_totalRemainingSize)
         bytesToRead = m_totalRemainingSize;
-    consumeData(item.data.data() + item.offset + m_currentItemReadSize, static_cast<int>(bytesToRead));
+    consumeData(item.data->data() + item.offset + m_currentItemReadSize, static_cast<int>(bytesToRead));
     m_currentItemReadSize = 0;
 }
 
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
index ed98356..9b5884f 100644
--- a/WebCore/platform/network/mac/FormDataStreamMac.mm
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -424,7 +424,7 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
                     for (size_t j = 0; j < blobData->items().size(); ++j) {
                         const BlobDataItem& blobItem = blobData->items()[j];
                         if (blobItem.type == BlobDataItem::Data) {
-                            newFormData->appendData(blobItem.data.data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
+                            newFormData->appendData(blobItem.data->data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
                         } else {
                             ASSERT(blobItem.type == BlobDataItem::File);
                             newFormData->appendFileRange(blobItem.path, blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
diff --git a/WebCore/platform/text/LineEnding.cpp b/WebCore/platform/text/LineEnding.cpp
index 17a9786..00a90eb 100644
--- a/WebCore/platform/text/LineEnding.cpp
+++ b/WebCore/platform/text/LineEnding.cpp
@@ -35,11 +35,68 @@
 #include "PlatformString.h"
 #include <wtf/text/CString.h>
 
-namespace WebCore {
+namespace {
 
-// Normalize all line-endings to CRLF.
-CString normalizeLineEndingsToCRLF(const CString& from)
+class OutputBuffer {
+public:
+    virtual char* allocate(size_t size) = 0;
+    virtual void copy(const CString&) = 0;
+    virtual ~OutputBuffer() { }
+};
+
+class CStringBuffer : public OutputBuffer {
+public:
+    CStringBuffer(CString& buffer)
+        : m_buffer(buffer)
+    {
+    }
+    virtual ~CStringBuffer() { }
+
+    virtual char* allocate(size_t size)
+    {
+        char* ptr;
+        m_buffer = CString::newUninitialized(size, ptr);
+        return ptr;
+    }
+
+    virtual void copy(const CString& source)
+    {
+        m_buffer = source;
+    }
+
+    const CString& buffer() const { return m_buffer; }
+
+private:
+    CString m_buffer;
+};
+
+class VectorCharAppendBuffer : public OutputBuffer {
+public:
+    VectorCharAppendBuffer(Vector<char>& buffer)
+        : m_buffer(buffer)
+    {
+    }
+    virtual ~VectorCharAppendBuffer() { }
+
+    virtual char* allocate(size_t size)
+    {
+        size_t oldSize = m_buffer.size();
+        m_buffer.grow(oldSize + size);
+        return m_buffer.data() + oldSize;
+    }
+
+    virtual void copy(const CString& source)
+    {
+        m_buffer.append(source.data(), source.length());
+    }
+
+private:
+    Vector<char>& m_buffer;
+};
+
+void internalNormalizeLineEndingsToCRLF(const CString& from, OutputBuffer& buffer)
 {
+    // Compute the new length.
     size_t newLen = 0;
     const char* p = from.data();
     while (char c = *p++) {
@@ -57,15 +114,18 @@ CString normalizeLineEndingsToCRLF(const CString& from)
             newLen += 1;
         }
     }
-    if (newLen == from.length())
-        return from;
     if (newLen < from.length())
-        return CString();
+        return;
+
+    if (newLen == from.length()) {
+        buffer.copy(from);
+        return;
+    }
 
-    // Make a copy of the string.
     p = from.data();
-    char* q;
-    CString result = CString::newUninitialized(newLen, q);
+    char* q = buffer.allocate(newLen);
+
+    // Make a copy of the string.
     while (char c = *p++) {
         if (c == '\r') {
             // Safe to look ahead because of trailing '\0'.
@@ -83,12 +143,18 @@ CString normalizeLineEndingsToCRLF(const CString& from)
             *q++ = c;
         }
     }
-    return result;
 }
 
+};
+
+namespace WebCore {
+
+void normalizeToCROrLF(const CString& from, Vector<char>& result, bool toCR);
+
 // Normalize all line-endings to CR or LF.
-static CString normalizeToCROrLF(const CString& from, bool toCR)
+void normalizeToCROrLF(const CString& from, Vector<char>& result, bool toCR)
 {
+    // Compute the new length.
     size_t newLen = 0;
     bool needFix = false;
     const char* p = from.data();
@@ -105,13 +171,20 @@ static CString normalizeToCROrLF(const CString& from, bool toCR)
         }
         newLen += 1;
     }
-    if (!needFix)
-        return from;
 
-    // Make a copy of the string.
+    // Grow the result buffer.
     p = from.data();
-    char* q;
-    CString result = CString::newUninitialized(newLen, q);
+    size_t oldResultSize = result.size();
+    result.grow(oldResultSize + newLen);
+    char* q = result.data() + oldResultSize;
+
+    // If no need to fix the string, just copy the string over.
+    if (!needFix) {
+        memcpy(q, p, from.length());
+        return;
+    }
+
+    // Make a copy of the string.
     while (char c = *p++) {
         if (c == '\r' && *p == '\n') {
             // Turn CRLF or CR into CR or LF.
@@ -125,27 +198,33 @@ static CString normalizeToCROrLF(const CString& from, bool toCR)
             *q++ = c;
         }
     }
-    return result;
 }
 
-// Normalize all line-endings to CR.
-CString normalizeLineEndingsToCR(const CString& from)
+CString normalizeLineEndingsToCRLF(const CString& from)
+{
+    CString result;
+    CStringBuffer buffer(result);
+    internalNormalizeLineEndingsToCRLF(from, buffer);
+    return buffer.buffer();
+}
+
+void normalizeLineEndingsToCR(const CString& from, Vector<char>& result)
 {
-    return normalizeToCROrLF(from, true);
+    normalizeToCROrLF(from, result, true);
 }
 
-// Normalize all line-endings to LF.
-CString normalizeLineEndingsToLF(const CString& from)
+void normalizeLineEndingsToLF(const CString& from, Vector<char>& result)
 {
-    return normalizeToCROrLF(from, false);
+    normalizeToCROrLF(from, result, false);
 }
 
-CString normalizeLineEndingsToNative(const CString& from)
+void normalizeLineEndingsToNative(const CString& from, Vector<char>& result)
 {
 #if OS(WINDOWS)
-    return normalizeLineEndingsToCRLF(from);
+    VectorCharAppendBuffer buffer(result);
+    internalNormalizeLineEndingsToCRLF(from, buffer);
 #else
-    return normalizeLineEndingsToLF(from);
+    normalizeLineEndingsToLF(from, result);
 #endif
 }
 
diff --git a/WebCore/platform/text/LineEnding.h b/WebCore/platform/text/LineEnding.h
index ab8d6ee..4306ce8 100644
--- a/WebCore/platform/text/LineEnding.h
+++ b/WebCore/platform/text/LineEnding.h
@@ -33,25 +33,22 @@
 #define LineEnding_h
 
 #include <wtf/Forward.h>
-
-namespace WTF {
-class CString;
-}
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
 // Normalize all line-endings in the given string to CRLF.
-WTF::CString normalizeLineEndingsToCRLF(const WTF::CString&);
+CString normalizeLineEndingsToCRLF(const CString& from);
 
-// Normalize all line-endings in the given string to CR.
-WTF::CString normalizeLineEndingsToCR(const WTF::CString&);
+// Normalize all line-endings in the given string to CR and append the result to the given buffer.
+void normalizeLineEndingsToCR(const CString& from, Vector<char>& result);
 
-// Normalize all line-endings in the given string to LF.
-WTF::CString normalizeLineEndingsToLF(const WTF::CString&);
+// Normalize all line-endings in the given string to LF and append the result to the given buffer.
+void normalizeLineEndingsToLF(const CString& from, Vector<char>& result);
 
-// Normalize all line-endings in the given string to the native line-endings.
+// Normalize all line-endings in the given string to the native line-endings and append the result to the given buffer.
 // (Normalize to CRLF on Windows and normalize to LF on all other platforms.)
-WTF::CString normalizeLineEndingsToNative(const WTF::CString&);
+void normalizeLineEndingsToNative(const CString& from, Vector<char>& result);
 
 } // namespace WebCore
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list